厂方法:定义一个用于创建对象的接口,让子类来决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
缺点:需要客户端决定实现哪一个类,选择判断的问题还是一样存在,跟简单工厂一样,只是更改的地方不一样,简单工厂更改的是工厂类,工厂方法修改的是调用客户端。
案例分析:还是以上一篇的计算机为案例吧
按照惯例给出,工厂方法的类图
1.操作符类和操作符的实现类可以是一样的。
public abstract class 操作符基类 { public double A; public double B; public abstract double 运算(); }
public class 加法 : 操作符基类 { public override double 运算() { return A + B; } } public class 减法 : 操作符基类 { public override double 运算() { return A - B; } } public class 乘法 : 操作符基类 { public override double 运算() { return A * B; } } public class 除法 : 操作符基类 { public override double 运算() { if (B.Equals(0)) { throw new Exception("被除数不能为0"); } return A / B; } }
2.改造简单工厂类,让其他抽象出来一个接口来创建对象。
public interface I工厂类 { 操作符基类 创造操作符(); }
3.,创建对象的任务就由 I工厂类 的子类来实现。
public class 加法工厂 : I工厂类 { public 操作符基类 创造操作符() { return new 加法(); } } public class 减法工厂 : I工厂类 { public 操作符基类 创造操作符() { return new 减法(); } } public class 乘法工厂 : I工厂类 { public 操作符基类 创造操作符() { return new 乘法(); } } public class 除法工厂 : I工厂类 { public 操作符基类 创造操作符() { return new 除法(); } }
4.客户端调用,需要先创建对应的工厂类(高耦合),由工厂实现类去创建对象。
static void Main(string[] args) { I工厂类 factory = new 乘法工厂(); var op = factory.创造操作符(); op.B = 10; op.A = 20; op.运算(); Console.WriteLine(op.运算()); Console.ReadLine(); }
总结:工厂方法克服了简单工厂的修改封闭原则的缺点,又保持了封装对象创建的过程。但是,他额外增加了开发量,每一个产品都必须有一个新建工厂类去创建,而且,客户端调用的时候耦合度也很高,但是可以结合简单工厂一起使用即:工厂方法+简单工厂+反射。