There is a shame that we have to emulate Abstractions or virtual members. In most cases we can use Interfaces to define some required structure. Of course this is useful to valid composition.

When we would like to set composition over inheritable that will goes to use some tricks.  We can image situation in normal implementation:

public interface IFactory
{
	function create(description:Object):Object;
}

Looks great. Let’s create some description. In this example this model will be quite simple, but it could be much complex.

public class CreateAnimationDescription
{
 public var name:String;
}

And there is our builder.

public class AnimationFactory implements IFactory
{
 public function create(description:Object):Object
 {
  var _description:CreateAnimationDescription = description as CreateAnimationDescription;
  // create animation according to current Application Domain.
  try
  { 
   var def:Class = getDefinitionByName(_description.name);
  } catch (e:Error) {}
  if(def)
  {
   return new def();
  }
  return null;
 }
}

Everything is working fine, and we can use this as follow:

//...
var desc:CreateAnimationDescription = new CreateAnimationDescription();
desc.name = "prealoader_loop";

// create local factory, but it could by command handler as well, or some static / class member.
var factory:AnimationFactory = new AnimationFactory(); 

// we have to type because factory.create returns Object
var product:MovieClip = factory.create(desc) as MovieClip;

//...

And problem appears. We have to make type conversion and we have to know about generic type of product in this particular factory. In this case that is simple. Even we are able to change Interface to:

public interface IFactory
{
	function create(description:CreateAnimationDescription):MovieClip;
}

But this will be generic IFactory anymore, it will be specific IMovieClipFactory. In larger project counter of interfaces will grow rapidly.
In another site will be possible to create some generic solution to handle many factories but we will be limited to most generic Interface:

function create(description:Object):Object

 

Hypothetically we can drop Interface and just implements some structure of class.

public class AnimationFactory
{
 public function create(description:CreateAnimationDescription):MovieClip
 {
  // ...
 }
}

That is some solution, but we drop for good validation that class has required members.

Finally we can imagine another implementation:

[Abstract(name = "create", type="method")]
public class AFactory extends AbstractClass
{
}

public class AnimationFactory extends AFactory
{
 public function create(description:CreateAnimationDescription):MovieClip {/**/}
}

This solution provides that every subclass of AFactory will have implemented ‘create’ method.

The last element of this puzzle. Validation.  AbstractClass should implement transparent validation, and it does.

public class AbstractClass
{
 private static var _valided:Dictionary = new Dictionary(true);
 public function AbstractClass()
 {
  if(_valided[(this as Object).constructor] !== true) validInstance(this);
 }
}

Unfortunately this validation will be launched in every creation of object. Exists other solutions like use static constructor, but this will be not transparent anymore.

Somebody could see connections between Models and Dependency Injection. It is similar, and this path goes to implement own MVC.

In next article I will continue topic about factory and I would like to show how to use this AbstractClass.

 
0 Kudos
Don't
move!