您的位置:首页 > 其它

设计模式——工厂方法模式的实现[备忘录]

2012-06-01 10:23 232 查看
在研究完简单工厂模式,从它的优缺点中,我们不难看出:如果我们要新增加一个新的运算方法,我们需要做两步:

1、编写新的运算方法;

2、去修改OperationFactory类,增加case分支判断;

这样一个弊端:同时开放了扩展,而且也开放了修改,违背了开放-封闭原则。

从简单工厂模式UML图中我们发现“简单工厂类”是依赖于“运算类”。

为了解决这个问题,我们分别为每个运算方法类建立工厂,每个工厂继承于同一接口,这样“简单工厂类”对于“运算类”的依赖,就降低了。

这就是工厂方法模式。

简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。

工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

在客户端调用方面:工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在。也就是说工厂方法把简单工厂的内部逻辑判断转移到了客户端代码来进行。如果你需要新添功能,本来需要改工厂类,现在需要修改客户端。

计算器的工厂方法模式UML图:

+、-、*、/类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SimpleFactoryPattern
{
class OperationBLL
{
}
/// <summary>
/// 加法
/// </summary>
internal class OperationAdd:Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA + NumberB;
return result;
}

}
/// <summary>
/// 减法
/// </summary>
internal class OperationSub:Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA - NumberB;
return result;
}
}
/// <summary>
/// 乘法
/// </summary>
internal class OperationMul:Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA * NumberB;
return result;
}
}
/// <summary>
/// 除法
/// </summary>
internal class OperationDiv:Operation
{
public override double GetResult()
{
double result = 0;
if (NumberB==0)
{
throw new Exception("除数不能为0.");

}
result = NumberA / NumberB;
return result;
}
}


工厂方法类是对简单工厂类加强。

这样整个工厂和产品体系其实都没有修改的变化,而只是扩展的变化,这就完全符合了“开放-封闭”原则。

但是随之而来有一个问题:由于每增加一个产品。就需要一个产品工厂的类,增加了额外的开发量。

但是这样的问题可以利用“反射”解决分支判断的问题。

补充:

优点:

基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象。而且如何创建一个具体产品的细节完全封装在具体工厂内部,符合高内聚,低耦合。

在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,很好的利用了封装和委托。

[b]缺点:[/b]

在添加新产品时,需要编写新的具体产品类(其实这不算一个缺点,因为这是不可避免的),要增加与之对应的具体工厂类。

[b]应用情景:[/b]

类不知道自己要创建哪一个对象时

类用它的子类来指定创建哪个对象

当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: