二、设计模式之工厂模式--工厂方法模式--创建型模式
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让类把实例化推迟到子类。工厂模式的类图如下:

抽象的IFactory提供了一个创建对象方法的接口CreateProduct(),该接口也称为"工厂方法"。在IFactory中,任何其他方法都可以调用CreateProduct()方法
创造出来的产品,但是只有子类Factory真正实现这个工厂方法并创建产品。工厂方法中让子类决定要实例化哪个一个类,这个决定并不是运行时决定,这个决定在编写创建者类时选择了那个子类,这个时候就子类决定了实际创建的产品。
示例:
using System; namespace FactoryMethod { class Program { static void Main(string[] args) { //客户调用时,只需要知道抽象的工厂,和抽象的粽子。 IZongZi zongzi = null; IZongZiFactory beiFancotry = new BeiFangZongZiFactory(); beiFancotry = new BeiFangZongZiFactory(); zongzi= beiFancotry.CreateZongZi("五香"); zongzi.Prepare(); zongzi.Ok(); IZongZiFactory NanFancotry = new NanFangZongZiFactory(); zongzi= NanFancotry.CreateZongZi("五香"); zongzi.Prepare(); zongzi.Ok(); Console.ReadKey(); } } /// <summary> /// 产品抽象 /// </summary> interface IZongZi { void Prepare(); void Ok(); } /// <summary> /// 具体产品,北方粽子 /// </summary> public class BeiFangZongZi : IZongZi { public BeiFangZongZi(string name) { Name = name; } public string Name { get; private set; } public void Prepare() { Console.WriteLine("北方:" + Name + "甜粽子,已经准备好。"); } public void Ok() { Console.WriteLine("北方:" + Name + "肉粽子,可以开吃。"); } } /// <summary> /// 具体产品,南方粽子 /// </summary> public class NanFangZongZi : IZongZi { public NanFangZongZi(string name) { Name = name; } public string Name { get; private set; } public void Prepare() { Console.WriteLine("南方:" + Name + "粽子,已经准备好。"); } public void Ok() { Console.WriteLine("南方:" + Name + "粽子,可以开吃。"); } } /// <summary> /// 粽子工厂方法,抽象的 /// </summary> interface IZongZiFactory { IZongZi CreateZongZi(string name); } /// <summary> /// 具体粽子工厂,北方粽子工厂 /// </summary> class BeiFangZongZiFactory : IZongZiFactory { public IZongZi CreateZongZi(string name) { return new BeiFangZongZi(name); } } /// <summary> /// 具体粽子工厂,南方粽子工厂 /// </summary> class NanFangZongZiFactory : IZongZiFactory { public IZongZi CreateZongZi(string name) { return new NanFangZongZi(name); } } }
示例运行结果如下:

示例解析:
示例中IZongZi对应工厂方法类图中的IProduct接口是所有所有产品的抽象类;BeiFangZongZi和NanFangZongZi实现了IZongZi接口,这两个类是产品抽象的具体实现,对应工厂方法类图中Product是产品的具体实现。IZongZiFactory对应工厂方法中IFactory接口是所有具体工厂的抽象;BeiFangZongZiFactory和NanFangZongZiFactory实现了IZongZiFactory接口,这两个是工厂接口的具体实现对应工厂方法类中的工厂实现Factory。
工厂方法优点:
首先,良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,减少模块间的耦合。
其次,工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以完成“拥抱变化”。例如在我们的例子中,需要增加一个棕色人种,则只需要增加一个BrownHuman类,工厂类不用任何修改就可完成系统扩展。
再次,屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不表,系统中的上层模块就不要发生变化,因为产品类的实例化工作是由工厂类负责,一个产品对象具体由哪一个产品生成是由工厂类决定的。在数据库开发中,大家应该能够深刻体会到工厂方法模式的好处:如果使用JDBC连接数据库,数据库从MySql切换到Oracle,需要改动地方就是切换一下驱动名称(前提条件是SQL语句是标准语句),其他的都不需要修改,这是工厂方法模式灵活性的一个直接案例。
最后,工厂方法模式是典型的解耦框架。高层模块值需要知道产品的抽象类,其他的实现类都不用关心,符合迪米特原则,我不需要的就不要去交流;也符合依赖倒转原则,只依赖产品类的抽象;当然也符合里氏替换原则,使用产品子类替换产品父类,没问题!

浙公网安备 33010602011771号