我也设计模式——6.注册工厂
这一节不讲模式,讲注册工厂,是为了下一节研究Flyweight做准备。
注册工厂,就是建立一个小型“DB”,采用注册方式,对实例进行管理。
从实现上有两种方式,但本质是相同的,都是在管理一组对象。
为了讲述方便,先建立一组父子类,Subject是ConcreteSubject1和ConcreteSubject2的父类。
第1种,可以认为是Singleton模式的一个扩展,所谓的“多件”,用简单工厂+单件实现:在单件的私有构造函数中,一次性把DB建立好,有多少元素,就new多少实例出来;在单件的一个方法中,用简单工厂根据不同参数返回不同的实例对象。这个方法的好处是避免了用反射根据参数动态生成新对象;由于在开始一次性就要建立好所有对象,所以需要创建的小对象很多时,不宜采用。代码如下:
第2种,则是在注册工厂类中放一个私有HashTable,来模拟一个小型数据库。比如说要创建对象A,先在注册工厂的HashTable中根据键,看A是否存在,如果有就返回这个对象,否则就用发射原理new一个A对象,在Hashtable中注册并返回。UML静态类图及顺序图如下:
代码如下:
补注:说到这里,一定要花些篇幅讲讲反射工厂,这是.NET专有的发射技术。
注册工厂,就是建立一个小型“DB”,采用注册方式,对实例进行管理。
从实现上有两种方式,但本质是相同的,都是在管理一组对象。
为了讲述方便,先建立一组父子类,Subject是ConcreteSubject1和ConcreteSubject2的父类。
public class Subject
{
}
public class ConcreteSubject1 : Subject
{
}
public class ConcreteSubject2 : Subject
{
}
{
}
public class ConcreteSubject1 : Subject
{
}
public class ConcreteSubject2 : Subject
{
}
第1种,可以认为是Singleton模式的一个扩展,所谓的“多件”,用简单工厂+单件实现:在单件的私有构造函数中,一次性把DB建立好,有多少元素,就new多少实例出来;在单件的一个方法中,用简单工厂根据不同参数返回不同的实例对象。这个方法的好处是避免了用反射根据参数动态生成新对象;由于在开始一次性就要建立好所有对象,所以需要创建的小对象很多时,不宜采用。代码如下:
public class CSingleton
{
private static CSingleton mySingleton = null;
private Subject cs1, cs2;
private CSingleton()
{
cs1 = new ConcreteSubject1();
cs2 = new ConcreteSubject2();
}
public static CSingleton Instance()
{
if (mySingleton == null)
mySingleton = new CSingleton();
return mySingleton;
}
public Subject Do(int n)
{
if (n == 1)
return cs1;
else
return cs2;
}
}
{
private static CSingleton mySingleton = null;
private Subject cs1, cs2;
private CSingleton()
{
cs1 = new ConcreteSubject1();
cs2 = new ConcreteSubject2();
}
public static CSingleton Instance()
{
if (mySingleton == null)
mySingleton = new CSingleton();
return mySingleton;
}
public Subject Do(int n)
{
if (n == 1)
return cs1;
else
return cs2;
}
}
第2种,则是在注册工厂类中放一个私有HashTable,来模拟一个小型数据库。比如说要创建对象A,先在注册工厂的HashTable中根据键,看A是否存在,如果有就返回这个对象,否则就用发射原理new一个A对象,在Hashtable中注册并返回。UML静态类图及顺序图如下:
代码如下:
public class RegFactory
{
private Hashtable objReg;
public RegFactory()
{
objReg = new Hashtable();
}
public Subject GetSubject(string name)
{
Subject r = null;
try
{
r = (Subject)objReg[name];
}
catch
{
}
if(r == null)
{
try
{
Type t = Type.GetType(name);
ConstructorInfo ci = t.GetConstructor(System.Type.EmptyTypes);
r = (Subject)ci.Invoke(null);
objReg.Add(name, r);
}
catch
{
throw new SystemException("No this Class Type");
}
}
return r;
}
}
{
private Hashtable objReg;
public RegFactory()
{
objReg = new Hashtable();
}
public Subject GetSubject(string name)
{
Subject r = null;
try
{
r = (Subject)objReg[name];
}
catch
{
}
if(r == null)
{
try
{
Type t = Type.GetType(name);
ConstructorInfo ci = t.GetConstructor(System.Type.EmptyTypes);
r = (Subject)ci.Invoke(null);
objReg.Add(name, r);
}
catch
{
throw new SystemException("No this Class Type");
}
}
return r;
}
}
补注:说到这里,一定要花些篇幅讲讲反射工厂,这是.NET专有的发射技术。