一、模式简介(Brief Introduction)
定义一个用于创建对象的接口,让子类去决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。这样客户端就只需要了解这个接口即可。
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
二、模式分析(Analysis)
抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
注:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
三、案例分析(Example)
namespace 雷锋工厂 { class Program //客户端 { static void Main(string[] args) { IFactory factory =newUndergraduateFactory (); LeiFeng student =factory.CreateLeiFeng(); student.BuyRice(); student.Sweep(); student.Wash(); } } class LeiFeng { public void Sweep() { Console.WriteLine("扫地"); } public void Wash() { Console.WriteLine("洗衣"); } public void BuyRice() { Console.WriteLine("买米"); } } //学雷锋的大学生 class Undergraduate : LeiFeng { } //社区志愿者 class Volunteer : LeiFeng { } //雷锋工厂 interface IFactory { LeiFeng CreateLeiFeng(); } //雷锋的大学生工厂 class UndergraduateFactory : IFactory { public LeiFeng CreateLeiFeng() { return new Undergraduate(); } } //社区志愿者工厂 class VolunteerFactory : IFactory { public LeiFeng CreateLeiFeng() { return new Volunteer(); } } }
四、解决的问题(What To Solve)
在程序设计中,有时候客户端并不需要知道所使用的对象的创建过程,或者对使用哪一个具体的对象并不确定,这时候就可以使用工厂方法来解决这个问题。
下面情况下你可以考虑使用工厂方法模式:
第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。
第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。
五、扩展(Extend)
涉及到开放—封闭原则和依赖倒装原则。
开放—封闭: 软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能(如果往简单工厂中添加“M的N次方”就会在运算工厂类添加case语句,违反了此原则)。
依赖倒装:要针对抽象层编程,而不要针对具体类编程(从工厂类和各个分支的耦合,抽象出一个接口,让各个工厂去实现这个接口)。
六、优点(Advantage)
- 可以使代码结构清晰,有效地封装变化。在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。
- 对调用者屏蔽具体的产品类。如果使用工厂模式,调用者只关心产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
- 降低耦合度。产品类的实例化通常来说是很复杂的,它需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好产品类,然后交给调用者使用。对调用者来说,产品所依赖的类都是透明的。
七、联系(Link)
1、简单工厂:简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
优点:在于工厂类中包含了必要的逻辑判断,根据客户段的选择条件动态实例化相关类,对于客户端来说,去除与具体产品的依赖。
2、工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现一个运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要加功能,本来是改工厂类,而现在是修改客户端。