I apologize in advance if my question is not clear, because I don’t know how to put this.
What I am trying to do is to reduce few lines of repeated code by implementing various OOP methods/concepts.
The problem
I have few set of of classes which has initialization process. So, I am implementing an init() method in all those classes. From the calling class (main), these objects will be instantiated and init() method of each object is called in the the order and call some other process after all of them are initialized.
Something like this
public function mainClass(){
_obj1 = new Class1();
_obj1.init();
_obj2 = new Class2();
_obj2.init();
_obj3 = new Class3();
_obj3.init();
doSomething();
}
Well, its not a big deal, but some of the classes’ init() methods are asynchronous and I need to add an event listener to get notified when they have finished initialization.
I tried that by extending EventDispatcher for each of those classes and dispatch event and handle it. I even implemented a logic to handle multiple asynchhnous calls by maintaining a counter.
It will be a painful job for me whenever I need to add a new class. I thought I could untilize OOP and reduce and simplify the code.
So I came up with some thing like this, which is currently not possible (abstract class).
abstract class Initializable
{
private var _callBack:Function;
//implement initializaton process in this method
function init(callback:Function=null):void;
protected function get callback():Function{
return _callBack;
}
protected function set callback(func:Function):void{
_callBack = func;
}
protected function onComplete():void{
if (_callBack){
_callBack(this);
}
}
}
This is the main problem for me, as you know abstract class is not allowed in AS3, and the “this” refers to the Initializer class but not its subclass I guess.
This is what I am asking for your help (for the hack)
I need it very much to make my system design simple and flexible, because I can extend the solution to allow mass synchronous initialization which will allow to easily queue up all objects in the order and call init() one after the other in the order in which they are added.
The mass initializer which takes care of handling the asynchronous job
public class MassInitializer
{
private var _objList:Array; //holds objects
private var _callBacks:Array;
private var _onComplete:Function;
public function MassInitializer()
{
_objList = new Array();
}
public function add(obj:Initializable,callback:Function=null):void{
_objList.push(obj);
_callBacks.push(callback);
}
public function init():void{
for (var i:int = 0;i < _objList.length;i++){
_objList.init(this);
}
}
private function onProgress(obj:Initializable):void{
//do updates here
for (var i:int;i<_objList.length;i++){
var obj:Initializable = _objList[i];
var fun:Function = _callBacks[i];
//update progress
if (fun){
fun(obj);
}
_callBacks.splice(i,1);
_objList.splice(i, 1);
}
if (_objList.length == 0){
onComplete();
}
}
private function onComplete():void{
_onComplete(this);
}
}
the main (manager/caller) class (ClassA, ClassB are subclasses of Initialzable class)
public class MainClass
{
private var _obj1:ClassA;
private var _obj2:ClassB;
public function MainClass()
{
_obj1 = new ClassA();
_obj2 = new ClassB();
}
public function init():void{
var initManager:MassInitializer = new MassInitializer();
initManager.add(obj1);
initManager.start();
}
}
probably I am trying to (or want to )implement an observer pattern, but I don’t want to confuse you by saying it in advance. Oops I said it? please ignore.
You can emulate abstract classes in ActionScript by enforcing method overrides: Just throw an error if the “abstract” method is called. I like to also implement an interface, but that’s not a must, of course: