工厂方法模式
工厂方法模式是对简单工厂模式的改进,它为每个对象增加了一个工厂类,专门用于生成该对象。
工厂方法实现加减乘除例子如下:
1 操作类
public class Operation { public double NumberA { get; set; } public double NumberB { get; set; } public virtual double GetResult() { double result = 0; return result; } } public class OperationAdd : Operation { public override double GetResult() { return NumberA + NumberB; } } public class OperationSub : Operation { public override double GetResult() { return NumberA - NumberB; } } public class OperationMul : Operation { public override double GetResult() { return NumberA * NumberB; } } public class OperationDiv : Operation { public override double GetResult() { if (NumberB == 0) { throw new Exception("除数不能为0"); } return NumberA / NumberB; } }
2 为每一个操作类添加一个工厂对象
/// <summary> /// 工厂方法模式把简单工厂的内部逻辑判断移导了客户端代码来进行,增加方法时,不需要增加条件分支,只需增加对象和工厂 /// </summary> interface IFactory { Operation CreateOperation(); } public class AddFactory:IFactory { public Operation CreateOperation() { return new OperationAdd(); } } public class SubFactory : IFactory { public Operation CreateOperation() { return new OperationSub(); } } public class MulFactory : IFactory { public Operation CreateOperation() { return new OperationMul(); } } public class DivFactory : IFactory { public Operation CreateOperation() { return new OperationDiv(); } }
3 在客户端使用工厂生产需要使用的对象
IFactory addFactory = new AddFactory(); Operation operation = addFactory.CreateOperation(); operation.NumberA = 1; operation.NumberB = 2; Console.WriteLine(operation.GetResult());
运行结果为:3
工厂方法模式把判断移到了客户端,并没有解决判断实例化哪个对象的问题,但这种模式在某些场景中是有很大的好处的,例如使用SQLServer数据库,代码开发完成后,如果数据改为Oracle,只需修改实例化工厂,不需要修改其它地方,更不需要修改被操作对象的实例化过程,下面比较使用工厂方法模式和不使用时代码的区别:
private void UseFactory() { //如果所有加法变减法,只修改一句 IFactory addFactory = new AddFactory(); Operation operation1 = addFactory.CreateOperation(); operation1.NumberA = 1; operation1.NumberB = 2; Console.WriteLine(operation1.GetResult()); Operation operation2 = addFactory.CreateOperation(); operation2.NumberA = 5; operation2.NumberB = 3; Console.WriteLine(operation1.GetResult()); Operation operation3 = addFactory.CreateOperation(); operation3.NumberA = 6; operation3.NumberB = 1; Console.WriteLine(operation1.GetResult()); } private void unUseFactory() { //如果所有加法变减法,需要修改所有实例化的地方,简单工厂也存在该问题 Operation operation1 = new OperationAdd(); operation1.NumberA = 1; operation1.NumberB = 2; Console.WriteLine(operation1.GetResult()); Operation operation2 = new OperationAdd(); operation2.NumberA = 5; operation2.NumberB = 3; Console.WriteLine(operation1.GetResult()); Operation operation3 = new OperationAdd(); operation3.NumberA = 6; operation3.NumberB = 1; Console.WriteLine(operation1.GetResult()); }
总体而言,工厂发放克服了简单工厂违反开放-封闭原则的缺点,又保持了封装对象创建过程的优点,封装对象创建的过程使得更换对象时,程序不需要做大的改动,降低了客户端与具体对象的耦合度。