c#设计模式(4)——抽象工厂模式
一、引言
在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,这是本专题所要介绍的内容。
部分内容选自https://www.cnblogs.com/zhili/p/SingletonPatterm.html,感觉写得很好,我只是自己总结成自己的东西。
二、介绍
一个工厂负责一些产品的创建,即产品簇。单一职责就是创建完整的产品簇,抽象工厂类抽象出实现的产品方法,具体产品工厂类当继承抽象类后,必须显式的override父类的抽象方法。即这样子理解,玩游戏时有红方和蓝方,红方会产生英雄和小兵,蓝方也会产生英雄和小兵,两者有共同之处又有不同之处,可以有红色工厂创建红方英雄和小兵,蓝方工厂产生蓝方英雄和小兵。抽象人物对象肯定是英雄和小兵了,具体实现就是红方和蓝方了。工厂抽象类就是创建英雄和小兵,继承工厂抽象类的红方工厂就是创建红方英雄和红方小兵了,蓝方工厂就是创建蓝方英雄和蓝方小兵啦。
1.先来指定英雄和小兵(英语含义和内容不搭,别介意,懒得改程序了)
public interface IArmy { /// <summary> /// show出Army /// </summary> void ShowArmy(); } public interface IRace { /// <summary> /// show出王者 /// </summary> void ShowKing(); }
2.接下来就是红方和蓝方的小兵和英雄具体功能实现啦,红方小兵和英雄继承了基类,实现了红方英雄和小兵独特技能,同理,蓝方小兵和英雄也继承了基类,实现了独特技能。 现在想想也知道,有两方的英雄和小兵都具体实现了,接下来就有个管理工厂,来创建两方的小兵和英雄。
/// <summary> /// 实现具体实现方法 /// </summary> public class NE : IRace { public void ShowKing() { Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "Moon"); } } public class NEArmy : IArmy { public void ShowArmy() { Console.WriteLine("The Army of {0} is {1}", this.GetType().Name, "大G、风骑士、蝙蝠"); } }
public class Human: IRace { public void ShowKing() { Console.WriteLine("The King of {0} is {1}", this.GetType().Name, "Moon"); } } public class HumanArmy : IArmy { public void ShowArmy() { Console.WriteLine("The Army of {0} is {1}", this.GetType().Name, "footman,火枪,骑士,狮鹫"); } }
3.既然两方都有共同的需求,就是创建英雄和小兵,那就抽象出两个方法,创建英雄和创建小兵,工厂抽象类就是创建英雄和小兵的抽象方法。
public abstract class AbstractFactory { public abstract IRace CreateRace(); public abstract IArmy CreateArmy(); }
4.继承工厂抽象类的红方工厂就是创建红方英雄和红方小兵了,蓝方工厂就是创建蓝方英雄和蓝方小兵啦。
public class HumanFactory : AbstractFactory { public override IArmy CreateArmy() { return new HumanArmy(); } public override IRace CreateRace() { return new Human(); } }
public class NEFactory : AbstractFactory { public override IArmy CreateArmy() { return new NEArmy(); } public override IRace CreateRace() { return new NE(); } }
5.主函数调用工厂类实现
class Program { static void Main(string[] args) { //创建红方工厂 AbstractFactory redFactory = new HumanFactory(); //红方创建并实现英雄的方法 IArmy humanArmy = redFactory.CreateArmy(); humanArmy.ShowArmy(); //红方创建并实现小兵方法 IRace humanRace = redFactory.CreateRace(); humanRace.ShowKing(); //创建蓝方工厂 AbstractFactory blueFactory = new NEFactory(); //蓝方创建并实现英雄方法 blueFactory.CreateArmy().ShowArmy(); //蓝方创建并实现小兵方法 blueFactory.CreateRace().ShowKing(); } }
三、总结
抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展,这真是抽象工厂模式的优点所在,然后抽象模式同时也存在不足的地方。下面就具体看下抽象工厂的缺点(缺点其实在前面的介绍中以已经涉及了):
抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。