您的位置:首页 > 编程语言 > C#

艾伟_转载:C# Design Patterns (1) - Factory Method

2011-08-29 00:22 423 查看
Simple Factory Pattern (简单工厂模式)

特性:

把类的实例化工作,集中到一个「工厂类」去处理,亦即将 new instance 的工作,都交给一个「工厂」去处理,而不要分散写在各个类中。

客户端程序,与创建实例 (对象) 的工作必须隔离,亦即「解耦」,客户端程序只要专注于自己的业务逻辑。适用于客户端程序在开发过程中,尚无法预知要创建的具体类型。

产品具体的实现能和客户端隔离,便于事后抽换。

Simple Factory Pattern (简单工厂模式)、Factory Method Pattern (工厂方法模式),在实作的代码中,有时很难明确去界定此二者。Simple Factory 的特性,如前所述,在于将创建实例 (new instance) 的工作,集中由特定的一个「工厂类」来处理,避免写在各个类中,以方便日后添加新功能,和修改既有的功能。

如下「进口水果」的代码,为 O'Reilly 的「C# 3.0 Design Patterns」这本书籍 [1] 第五章的 Factory Method 示例。乍看之下,我觉得它比较像 Simple Factory Pattern,因其仍将创建实例,和部分逻辑判断的工作,都集中在一个 工厂类 (Creator1 类) 去处理,导致日后要添加新功能 (多引进一个国家的水果),或要修改判断「进口月份」的逻辑时,仍要修改 server-side 的这个「工厂类」,而无法只修改 client-side 的 Page_Load 方法,违背了「开放-封闭」原则。

但这个示例,要实例化哪个类型,是由「工厂类」以及客户端 (水果店主人) 的 Page_Load 方法,共同决定的。透过 IProduct 接口,看似隔离了客户端程序、具体 Product 的依赖关系,但客户端程序仍有创建对象的决定权,因此其与创建实例 (对象) 的工作并未真正隔离。

FactoryMethod.aspx.cs
using System;

public partial class FactoryMethod : System.Web.UI.Page
{
//客户端调用(Client-Side)。
protected void Page_Load(object sender, EventArgs e)
{
//客户端程序调用的时候,只要改右侧创建实体的类型即可
IFactory factory1 = new 博派Factory();
变形金刚 擎天柱 = factory1.createTransformer();
擎天柱.transformCar();

//把职责委托给平行层次中的子类
IFactory factory2 = new 狂派Factory();
变形金刚 威震天 = factory2.createTransformer();
威震天.transformAirplane();
}
}

//IProduct
class 变形金刚
{
public virtual void transformCar()
{
Console.WriteLine("变汽车");
}

public virtual void transformAirplane()
{
Console.WriteLine("变飞机");
}

public virtual void transformAnimal()
{
Console.WriteLine("变动物");
}
}

//IProduct 的子类
class 博派 : 变形金刚
{ }

//IProduct 的子类
class 狂派 : 变形金刚
{ }

//变形金刚工厂 (亦可用抽象类)
interface IFactory
{
//隐藏实现细节。
//事前不知道要创建哪种变形金刚,延至「客户端」中实现。
变形金刚 createTransformer();
}

//博派的工厂 (由此种子类来决定具体实例化哪种类型)
class 博派Factory : IFactory
{
public 变形金刚 createTransformer()
{
return new 博派();
}
}

//狂派的工厂 (由此种子类来决定具体实例化哪种类型)
class 狂派Factory : IFactory
{
public 变形金刚 createTransformer()
{
return new 狂派();
}
}

//以后引进新产品 (堕落金刚) 时,我们不需要冒险修改既有的「工厂类」,而只要添加新的产品类、新的工厂类,
//最后由 IFactory 的子类,以及客户端程序 (Page_Load 方法),来决定要创建哪些具体类型;
//整个架构变成只有「扩展」的变化,而不再有「修改」的变化。

//若要修改旧功能,如狂派类,要加入组合成「大力神」的功能时,也只需要修改既有的「狂派」类。



图 2 Sybase PowerDesigner 绘制的「变形金刚 - 工厂方法模式」Class Diagram

以后引进新产品 (堕落金刚) 时,我们不需要冒险修改既有的「工厂类」,而只要添加新的「产品类」、新的「工厂类」,最后由 IFactory 的子类,以及客户端程序 (Page_Load 方法),来决定要创建哪些具体类型;整个架构变成只有「扩展」的变化,而不再有「修改」的变化。此外,若要修改旧功能,如:「狂派」类,要加入组合成「大力神」的功能时,也只需要修改既有的「狂派」类即可。

Factory Method Pattern 并无固定的实现方式,上述两个示例,仅为其中一种实现方式,若参考一些 Java 的论坛、书籍、文件,还能找到更多的变化应用 [7], [8]。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: