1.抽象工厂模式介绍
上一篇我们了解了工厂模式,知道工厂模式可以解决简单工厂的缺陷(简单工厂添加新产品时要修改工厂类,不符合开闭原则),但是简单工厂和工厂模式都是只生产一种产品(前边的简单工厂和工厂都只生产鼠标),实际上戴尔和惠普公司不仅生产鼠标还生产键盘,为了解决系列产品的问题,就有了抽象工厂模式。我们就以生产鼠标和键盘为例来理解抽象工厂。
产品类,包括鼠标类和键盘类:
//鼠标抽象类 public abstract class Mouse { public abstract void Print(); } //戴尔鼠标 public class DellMouse : Mouse { public override void Print() { Console.WriteLine("生产了一个Dell鼠标!"); } } //惠普鼠标 public class HpMouse : Mouse { public override void Print() { Console.WriteLine("生产了一个惠普鼠标!"); } } //键盘抽象类 public abstract class Keybo { public abstract void Print(); } //戴尔键盘类 public class DellKeybo : Keybo { public override void Print() { Console.WriteLine("生产了一个戴尔键盘!"); } } //惠普键盘 public class HpKeybo : Keybo { public override void Print() { Console.WriteLine("生产了一个惠普键盘!"); } }
工厂类, 抽象工厂类提供了生产鼠标和生产键盘的抽象方法,戴尔工厂继承了抽象工厂,实现抽象方法时只创建自己品牌的鼠标和键盘;惠普工厂同理,代码如下:
/// <summary> /// Pc产品工厂抽象类 /// </summary> public abstract class PcFactory { public abstract Mouse CreateMouse(); public abstract Keybo CreateKeybo(); } //戴尔pc工厂 public class DellPcFactroy : PcFactory { public override Keybo CreateKeybo() { return new DellKeybo(); } public override Mouse CreateMouse() { return new DellMouse(); } } //惠普pc工厂 public class HpPcFactory : PcFactory { public override Mouse CreateMouse() { return new HpMouse(); } public override Keybo CreateKeybo() { return new HpKeybo(); } }
客户端代码:
class Program { static void Main(string[] args) { //生产一个戴尔鼠标/键盘 PcFactory dellFactory = new DellPcFactroy(); Mouse dellMouse= dellFactory.CreateMouse(); Keybo dellKeybo = dellFactory.CreateKeybo(); dellMouse.Print(); dellKeybo.Print(); //生产一个惠普鼠标/键盘 PcFactory hpFactory = new HpPcFactory(); Mouse hpMouse = hpFactory.CreateMouse(); Keybo hpKeybo = hpFactory.CreateKeybo(); hpMouse.Print(); hpKeybo.Print(); Console.ReadKey(); } }
程序运行结果如下:
我们可以看出抽象工厂和工厂模式的区别在于:抽象工厂可以生产多种产品(两种:鼠标和键盘),而工厂模式只生产一种产品(键盘),抽象工厂主要时解决生产系列产品的问题。思考一下:如果抽象工厂中只有一种产品是什么情况呢?只有一种产品的抽象工厂其实就是工厂模式,我们可以把工厂模式看作是抽象工厂的一个特例。
2.小结
上边例子的类图:
抽象工厂的优点:抽象工厂具有工厂模式的优点,对添加系列产品符合闭合原则(工厂模式的系列产品只有一种)。如要生产华硕的鼠标和键盘,只需要添加一个AsusPcFactory(继承与PcFactory),AsusMouse(继承Mouse),AsusKeybo(继承Keybo),就可以在客户端通过以下代码生产华硕鼠标和键盘:
PcFactory asusPcFactory=new AsusPcFactory(); asusPcFactory.CreateMouse();//生产华硕鼠标 asusPcFactory.CreaetKeybo();//生产华硕键盘
抽象模式的缺点:抽象模式对添加新产品不符合开闭原则。如要生产显示器,不仅要添加显示器抽象类和显示器具体类,还需要修改PcFactory,在抽象工厂中添加一个CreateDisplay抽象方法(或接口),戴尔工厂和惠普工厂也要实现新增的抽象方法(或者接口)。