在上述代码中,要实例化的对象的namespace是和当前工厂类是同一个namespace,同样要实例化的类和工厂类在同一个Assembly里面。当然他们可以分布于不同的assemblies。拿上篇文章的Asbtract Factory的工厂类作为例子,如果不同的游戏机类型,其Concrete Factories和Concrete Products分别独立存在于一个namespace和assembly,例如
namespace PS3
{
public class PS3Console : AbstractGameConsole
{
}
public class PS3Joystick : AbstractJoystick
{
}
public class PS3Player : AbstractPlayer
{
public override AbstractGameDisk CreateGameDisk(GameDiskType type)
{
return new PS3RacingGameDisk();
}
public override AbstractGameConsole CreateGameConsole()
{
return new PS3Console();
}
public override AbstractJoystick CreateJoystick()
{
return new PS3Joystick();
}
}
}
名字空间(namespace)为PS3的程序编译到PS3Factory.dll中,而Wii的实现在WiiFactory.dll中,以下是原有没有使用Reflection的实现。
public enum GameDevice
{
PS3,
Wii
}
public class Player
{
private AbstractPlayer playerFactory;
public Player(GameDevice device)
{
switch (device)
{
case GameDevice.PS3:
playerFactory = new PS3Player();
break;
case GameDevice.Wii:
playerFactory = new WiiPlayer();
break;
}
}
}
使用Reflection后,可以把switch去掉,代码如下:
public class Player
{
private AbstractPlayer playerFactory;
public Player(GameDevice device)
{
//Load Assembly
Assembly asm = Assembly.LoadFrom(device.ToString() + "Factory.dll");
// Get fully qualified factory name
string name = device.ToString() + "." + device.ToString() + "Player";
// Dynamic factory creation
playerFactory = asm.CreateInstance(name) as AbstractPlayer;
}
}
GameDevice可以来自于配置文件。使用Reflection后,系统动态plug-in新的模块,例如需要增加Xbox模块,把Xbox的Concrete Factories和Concrete Products实现封装到Xbox的namespace,同时编译到XboxFactory.dll,修改GameDevice的配置文件就可以了。