package org.libspark.common.reflect { import flash.utils.Dictionary; /** * IInstanceFactory の汎用的な実装で、システム内全てで使えるファクトリを提供する. * * TODO: 後でもう少し設計考える, InstanceFactory(Genral), StackedInstanceFactory, ClassMappedInstanceFactory, FunctionInstnaceFactory に分けるか? */ public class InstanceFactory implements IInstanceFactory { private static var _general:InstanceFactory; /** * システム内で共通で使用出来るファクトリを返す. * * Ensure: result != null */ public static function get general():InstanceFactory { return _general || (_general = new InstanceFactory()); } public function InstanceFactory() { factories = new Dictionary(); } private var _factories:Dictionary; /** * 登録されているファクトリ. * キー: Class, 値: IInstanceFactory * * Ensure: result != null */ protected function get factories():Dictionary { return _factories; } /** * Require: value != null * Ensure: factories == value */ protected function set factories(value:Dictionary):void { _factories = value; } /** * 'forClass' のための特別なファクトリ 'factory' を登録する. * * Require: forClass != null * Require: factory != null */ public function registerFactory(forClass:Class, factory:IInstanceFactory):void { factories[forClass] = factory; } /** * 'forClass' のための特別なファクトリの登録を削除する. * * Require: forClass != null */ public function unregisterFactory(forClass:Class):void { if (factories[forClass] != null) { delete factories[forClass]; } } /** * 'forClass' に対するファクトリが登録されていればそれを使用してインスタンスを生成して返し、 * 登録されていなければ standardMakeInstance で定義される方法を使用してインスタンスを生成して返す. */ public function makeInstance(forClass:Class):Object { var factory:IInstanceFactory = factories[forClass] as IInstanceFactory; if (factory != null) { return factory.makeInstance(forClass); } return standardMakeInstance(forClass); } /** * 標準の方法で 'forClass' のインスタンスを生成する. */ protected function standardMakeInstance(forClass:Class):Object { return new forClass(); } } }