views:

711

answers:

3

I'm new to object oriented programming and flash. As far as I know, global variables and functions are evil things. We have to use objects, right?

So far everything is going pretty well, apart from when I want to eg. create a log function which will write a debug message to a textfield object.

The problem is that I need to be able to use this log function everywhere, in childs, in childs of these childs and in the parents of these childs, etc. - anywhere in the code.

How should I do this in a good object oriented way? Because, that object will no longer be accessable when I call it in object A and want to use it in object A's child, which is object B.

+3  A: 

Many different ways, of course, depending on the details of your app. (And globals aren't by definition "evil" -- in fact in Flash, they can be quite useful.) One approach would be to define a publicly accessible static method, which you could call from anywhere in your code, and might be defined as a separate class like so:

package
{
    public class MyCustomLogger
    {
     public function MyCustomLogger()
     {
      //
     }

     public static function log(text:String):void
     {
      trace(text);
     }
    }
}

Defined this way, you might call your log function using ClassName.staticFunctionName notation from anywhere in your app:

[some code...]

MyCustomLogger.log("My log text.")

[some more code...]

This kind of approach is pretty common. From there, it can get more complicated, depending on your needs; your post indicates you want to write the string to a TextField object, in which case the static log function would require either a reference to that TextField object when it's called, or its own static access path to the TextField instance as defined elsewhere in your application. In that case, I might suggest defining a global instance variable into whose constructor you might pass a reference to the TextField target (and writing to it with your log function), or various other approaches -- again, depending on your specific needs. But for purposes of illustration, using a publicly accessible static method is one fairly standard approach you might consider.

Christian Nunciato
This will make a new instance of the object everytime you call it right? So It's not possible to create a TextField in the MyCustomLogger class?
Tom
"Would require its own static access path to the TextField instance as defined elsewhere in your application. In that case, I might suggest defining a global instance variable into whose constructor you might pass a reference to the TextField target (and writing to it with your log function)."I would like to know how exactly to do that. I'm afraid I got kind of lost in your explanation. Where and how do I define that "global instance variable"? Thanks!
Tom
Well, it sort of depends on your environment. In Flash, you could define a variable in an included ActionScript file, or explicitly on a keyframe somewhere on your timeline, or in Flex you could define a public variable in your Main MXML file, and access it using parentApplication.yourFunctionName ... as I said, there are so many ways to handle this situation. But the simplest approach would probably be using a static method or a Singleton, as Cay describes.
Christian Nunciato
+2  A: 

Another approach is to use a Singleton class. In short, it's very much like the class Christian showed you, but the way you access it is SingletonClass.getInstance().doSomething(). The principle behind it, is that the class keeps only one instance of itself, so each time you call getInstance(), the class checks if that instance has been created, and returns it. You can learn more about it and check different implementations of it here: http://life.neophi.com/danielr/2006/10/singleton_pattern_in_as3.html

For your case though, I would probably go the simpler way of a static global class as Christian said. In order to access a textfield from within the static method log(), you could make another static method registerTextfield(tf:TextField) and call it at the beginning of your application with the Textfield, register it in a static variable, and go from there. Adding to Christian's example, it would go something like this:

package
{
    import flash.text.TextField;
    public class MyCustomLogger
    {
        private static var _textfield:TextField;

        public function MyCustomLogger()
        {
                //
        }

        public static function log(text:String):void
        {
                _textfield.text=text;
        }

        public static function registerTextField(textfield:TextField):void
        {
                _textfield=textfield;
        }
    }
}

Good luck!

Cay
A: 

The Object-Oriented way to do this would be to create a partial(abstract, deferred) class containing your logging functionality and inherit from that class if you need to use those facilities.

Most languages don't allow multiple inheritance so hacks have to be used (singletons, static functions)

So given the language in question is ActionScript, and neither abstract nor partial classes are supported...?
Christian Nunciato
Is this possible in Actionscript 3?
Tom
No, AS3 supports neither abstract classes nor multiple inheritance. You could inherit from a base class containing the logging functionality, but the reasons not to do so would probably far outweigh the benefits.
Christian Nunciato