简单工厂模式实现:以计算器程序为例,结构图如下
工厂类是这样写的:
class OperationFactory{
public static Operation createOperate(String operate){
Operation oper = null;
switch(operate) {
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*";
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}
return oper;
}
}
客户端的应用:
Operation oper
oper = OpearationFactory.createOperate("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
工厂方式模式实现: 计算器的工厂方法模式实现的结构图如下
先构建一个工厂接口:
interface IFactory{
Operaation CreateOperation();
然后加减乘除各建一个具体工厂去实现这个接口:
class AddFactory : IFactory{ //加法类工厂
public Operation CreateOperation()
{
return new OperationAdd();
}
}
class SubFactory : IFactory{
public Operation CreateOperation()
{
return new OperationSub();
}
}
class MulFactory : IFactory{
public Operation CreateOperation()
{
return new OperationMul();
}
}
class DivFactory : IFactory{
public Operation CreateOperation()
{
return new OperationDiv();
}
}
客户端的应用:
IFactory operFactory = new AddFactory();
Operation oper = operFactory.Createoperation();
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetReSult();
简单工厂 VS 工厂方法
简单工厂模式的最大优点就在于工厂类中包含了必要的逻辑判断, 根据客户端的选择条件动态实例化相关的类, 对于客户端来说,去除了与具体产品的依赖。但是当后期需要更改需求时 此时就需要给运算工厂类的方法里加 "case" 的分支条件, 需要修改原来的类, 这违背了 “开闭原则”。于是工厂方法孕育而生。
工厂方法模式(Factory Method): 定义一个用于创建对象的接口, 让子类去决定实例化哪一个类。 工厂方法使一个类的实例化延迟到其子类。
既然这个工厂类与分支耦合, 那么我们就对它下手, 根据依赖转置原则, 我们把工厂类抽象出一个接口,这个接口只有一个方法, 就是创建抽象产品的工厂方法。 然后, 所有的要生产具体类的工厂, 就去实现这个接口, 这样, 一个简单工厂模式的工厂类, 变成了一个工厂抽象接口和多个具体生成对象的工厂, 于是当我们要增加需求时 比如计算器求“M 的 N 次方”, 就不需要更改原有的工厂类了, 需要增加此功能的运算类和相应的工厂类就可以了。也完全符合了 “开闭原则”, 又保持了封装对象创建过程的优点。但工厂方法模式也有缺点, 就是当增加产品工厂类时 增加了额外的开发量。
工厂方法模式实现时, 客户端需要决定实例化哪一个工厂来实现运算类, 选择判断的问题还是存在的, 也就是说, 工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。 你想要增加功能, 本来是更改工厂类, 而现在时更改客户端。