设计模式之工厂方法模式VS简单工厂方法模式
名词解释:
简单工厂:这个实在是没什么解释的,就是一个工厂类,然后有一个方法,根据传递的参数可以通过switch(你也可以是if,或者是使用高端的反射 )来进行对象的创建。
工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
区别:简单工厂的优点是工厂类中包含了逻辑(即通过判断,实例化对应的类型),对于客户端来说去除了与具体产品的依赖。但是如果有了新功能则就需要修改这个判断的逻辑(也就是违背了开放-封闭原则),所以这个也是工厂方法出现的必要性。工厂方法呢每一个类都有自己的工厂,当然也有抽象的工厂基类,这样客户端想实例哪种类型,只需实例化其对应的工厂即可。
必要元素:
实体类的抽象类(也可以是接口)、抽象工厂类(可以是接口)、各种实体类(继承自抽象类或者实现自接口)、各种实体工厂(继承自抽象工厂类或者实现自接口)。
上例子:
实体抽象类以及各个实体类:
abstract class Operation { public double NumberA { get; set; } public double NumberB { get; set; } public abstract double GetResult(); } class OperationAdd:Operation { public override double GetResult() { return NumberA + NumberB; } } class OperationDiv:Operation { public override double GetResult() { if (NumberB == 0) throw new Exception("除数不能为0"); return NumberA / NumberB; } } class OperationMul:Operation { public override double GetResult() { return NumberA * NumberB; } } class OperationSub:Operation { public override double GetResult() { return NumberA - NumberB; } }
抽象工厂类和各个实体工厂类:
abstract class OperationFactory { public abstract Operation CreationOperation(); } class OperationAddFactory : OperationFactory { public override Operation CreationOperation() { return new OperationAdd(); } } class OperationSubFactory : OperationFactory { public override Operation CreationOperation() { return new OperationSub(); } } class OperationMulFactory : OperationFactory { public override Operation CreationOperation() { return new OperationMul(); } } class OperationDivFactory:OperationFactory { public override Operation CreationOperation() { return new OperationDiv(); } }
客户端使用:
Operation operation = factory.CreationOperation(); operation.NumberA = 2; operation.NumberB = 4; double result = operation.GetResult(); Console.WriteLine(result); factory = new OperationSubFactory(); operation = factory.CreationOperation(); operation.NumberA = 4; operation.NumberB = 2; result = operation.GetResult(); Console.WriteLine(result);
这样,如果我们有新的类型出现,则增加实体类,并且增加实体类的工厂即可,在客户端就可以直接使用新的工厂创建新的类型了。
总结:
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现实体的创建,选择判断的问题还是存在,也就是说工厂方法把简单工厂内部逻辑判断移到了客户端代码来实现,之前如果要增加类型,修改的是工厂类,现在直接修改客户端即可(当然如果增加了某一个类型,也是需要增加其相对应的工厂类)。