装饰模式解释:
工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
模式类型: 创造类模式。
使用时机:
1.对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。
2.只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。
在代理模式中的各个角色有:
UML图:
代码实现:
创建一个Operation类.
///
/// 运算类
///
class Operation
{
private double _numberA = 0;
private double _numberB = 0;
public double NumberA
{
get { return _numberA; }
set { _numberA = value; }
}
public double NumberB
{
get { return _numberB; }
set { _numberB = value; }
}
///
/// 得到运算结果
///
///
public virtual double GetResult()
{
double result = 0;
return result;
}
}
依次创建OperationAdd,OperationSub,OperationMul,OperationDiv类.
///
/// 加法类
///
class OperationAdd : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA + NumberB;
return result;
}
}
///
/// 减法类
///
class OperationSub : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA - NumberB;
return result;
}
}
///
/// 乘法类
///
class OperationMul : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA * NumberB;
return result;
}
}
///
/// 除法类
///
class OperationDiv : Operation
{
public override double GetResult()
{
double result = 0;
if (NumberB == 0)
throw new Exception("除数不能为0。");
result = NumberA / NumberB;
return result;
}
}
创建工厂接口:IFactory.
///
/// 工厂方法
///
interface IFactory
{
Operation 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();
}
}
客户端调用
.
Static void Main()
{
IFactory operFactory = new AddFactory();
Operation oper = operFactory.CreateOperation();
oper.NumberA = 10;
oper.NumberB = 20;
double result = oper.GetResult();
operFactory = new DivFactory();
oper = operFactory.CreateOperation();
oper.NumberA = 21;
oper.NumberB = 7;
result = oper.GetResult();
}
简单工厂的优点是工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对客户端来说,去除了与具体产品的依赖. (如计算器案例:客户端只要给"+"给工厂, 工厂就会生成相关的实例对象,客户端只要消费即可). 但是如果要增加新计算逻辑 "求平方".那就必须在工厂类里增加 Case 分支. 这就等于说我们不但对扩展开放了,也对修改(原的有类)开放了.违背了开放-封闭原则.
工厂方法则是在简单工厂的基础上把工厂类抽象出一个接口,并且这个接口只有一个方法,就是创建抽象产品的工厂方法. 然后所有要生产具体类的工厂,就去实现这个接口.于是如果要增加 "求平方"功能时,就不需要改原有的工厂类, 只需要增加此功能的 运算类 和相应的 工厂类 就可以了. 这样就实现了对扩展开放,对修改封闭. 符合开放-封闭原则.
工厂方法的缺点:
工厂方法把简单工厂内部的逻辑判断移到了客户端来进行, 新增功能时变成要修改客户端. 要解决这个问题,可以使用 "反射" .