工厂方法模式——定义了一个创建对像的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。(摘自《Head First Design Patterns》)
以下是自已用VS画了一个简图:
我用抽像类代替了接口来实现产品基类,只是为了在子类少些一些重复代码。产品基类代码如下:
public abstract class Weapon
{
#region = Aggressivity =
private int _aggressivity;
public int Aggressivity
{
get { return _aggressivity; }
set { _aggressivity = value; }
}
#endregion
#region = Appearance =
private string _appearance;
public string Appearance
{
get { return _appearance; }
set { _appearance = value; }
}
#endregion
public void Show()
{
Console.WriteLine(this.Appearance + " 攻击力:" + this.Aggressivity.ToString());
}
}
实现三个产品:
class Knife : Weapon
{
public Knife()
{
this.Aggressivity = 30;
this.Appearance = "这是一把匕首";
}
}
class Sword : Weapon
{
public Sword()
{
this.Aggressivity = 50;
this.Appearance = "这是一把剑";
}
}
class Axe : Weapon
{
public Axe()
{
this.Aggressivity = 100;
this.Appearance = "这是一把斧子";
}
}
创建工厂基类:
public abstract class WeaponFactory
{
protected string Property = string.Empty;
protected int Aggressivity = 0;
public abstract Weapon CreateWeapon(string typeName);
protected void Process(Weapon w)
{
w.Appearance += string.Format(" {0}", Property);
w.Aggressivity += this.Aggressivity;
}
}
其中重要的就是那个CreateWeapon抽象方法,它是工厂的灵魂,其它的只是为了充实一下内容,可以任意扩展。
实现二个工厂:
class NoPropertyFactory : WeaponFactory
{
public override Weapon CreateWeapon(string typeName)
{
switch (typeName)
{
case "sword":
return new Sword();
case "knife":
return new Knife();
break;
case "axe":
return new Axe();
break;
}
return null;
}
}
class IcePropertyFactory : WeaponFactory
{
public IcePropertyFactory()
{
this.Aggressivity = 50;
this.Property = " 附冰属性";
}
public override Weapon CreateWeapon(string typeName)
{
switch (typeName)
{
case "sword":
Weapon sword = new Sword();
Process(sword);
return sword;
case "knife":
Weapon knife = new Knife();
Process(knife);
return knife;
break;
case "axe":
Weapon axe = new Axe();
Process(axe);
return axe;
break;
}
return null;
}
}
普通工厂创造普通的武器,冰属性工厂创造的当然是带冰属性的武器,攻击力也有提高,这里可以任意创建自己的工厂,比如:火属性工厂,风属性工厂。
下面,我们开始生产武器:
WeaponFactory iceFactory = new IcePropertyFactory();
WeaponFactory factory = new NoPropertyFactory();
Weapon sword1 = factory.CreateWeapon("sword");
sword1.Show();
Weapon sword2 = iceFactory.CreateWeapon("sword");
sword2.Show();
Weapon axe1 = factory.CreateWeapon("axe");
axe1.Show();
Weapon axe2 = iceFactory.CreateWeapon("axe");
axe2.Show();
Weapon knife1 = factory.CreateWeapon("knife");
knife1.Show();
Weapon knife2 = iceFactory.CreateWeapon("knife");
knife2.Show();
上面创建了这二个不同的工厂,并分别生产了剑,匕首和斧子,产生的效果自然也是不一样,下面是输出结果:
这是一把剑 攻击力:50
这是一把剑 附冰属性 攻击力:100
这是一把斧子 攻击力:100
这是一把斧子 附冰属性 攻击力:150
这是一把匕首 攻击力:30
这是一把匕首 附冰属性 攻击力:80
当然,还可以更简单——简单工厂:
static class SimpleFactory
{
public static Weapon CreateWeapon(string typeName)
{
switch (typeName)
{
case "sword":
return new Sword();
case "knife":
return new Knife();
break;
case "axe":
return new Axe();
break;
}
return null;
}
}
这简单工厂其实就是包含一个工厂方法的类,测试就不写了,因为里面的方法跟上面的普通工厂效果是一样的。