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

(转)GoF--Creational Design Patterns 创建型设计模式(一)

2008-08-07 10:29 253 查看
创建型设计模式: 对类的实例化过程进行抽象,能够使软件模块做到与对象的创建和组织无关。外界对于这些对象只知道他们的公共接口,而不清楚具体的实现细节。

创建型模式重点是解决好 ( 创建什么 谁来创建 何时创建 )等问题1.Simple Factory Pattern 简单工厂模式 静态工厂模式

由一个工厂类根据传入的参量,动态决定创建出哪一类产品类的实例(参考GRASP 中的Creator Pattern:工厂类具有初始化具体产品类的数据)

特点:

(1) 被创建的对象特征: 具有共同的父类

(2) 根据不同的条件返回不同的类的实例

(3) 参与者

工厂角色:由客户调用,返回一个产品实例

抽象产品角色(共同的父类)或接口:定义 声明 产品的接口

具体产品角色:实现产品的接口

(4) 顺序图:

新建一个工厂->创建产品A->返回产品A->传递参数->创建产品B->返回产品B...

例子:

国旗生产厂

工厂角色 国旗生产厂家 类

抽象产品角色(共同的父类) 四方布

具体产品角色 中国国旗类 美国国旗类 ....

优势:

(1)外界可以从直接创建具体产品对象的尴尬局面摆脱出来

(2)明确了区分各自的职责和权力,有利于整个软件体系结构的优化

缺点:

(1)由于工厂类集中了所有实例的创建逻辑,很容易违反GRASP的高内聚的责任分配原则

(2)当具体产品类不断增多时,可能会出现要求工厂类根据不同条件使用不同工厂去创建具体实例的需求,这种对条件的判断和对具体产品类型的判断交错在一起,布利于模块功能的蔓延,对系统的扩展和维护很不利

应用:

(1)工厂类负责创建的产品类比较少

(2) "简单"模式只能用于简单的工作,呵呵~

(3) 客户只知道传入工厂类的参数,对于如何创建对象不关心

2.Factory Method Pattern 工厂方法模式 虚拟构造器 多态工厂(参考:GRASP 中的Polymorphism)

特点:

(1) 被创建的对象特征: 产品具有共同的父类 ,工厂也具备共同的父类 当然都是抽象出来的

(2) 根据不同的条件使用不同的具体工厂类 去创建不同的具体产品类的实例

(3) 涉及到的角色

工厂角色:creator 声明工厂方法FactoryMethod,返回一个产品

具体工厂类:Concrete Creator 实现工厂方法FactoryMethod,由客户调用,返回一个产品实例

抽象产品角色(共同的父类)或接口:定义 声明 产品的接口

具体产品角色:实现产品的接口

(4)顺序图

客户 创建工厂对象A->创建产品A->返回产品A

创建工厂对象B->创建产品B->返回产品B

...

例子:

兵工厂生产战斗机器 多文档系统

难点: 工厂类和具体工厂类

eg:

//工厂抽象类

abstract class Document

{

protected ArrayList pages=new ArrayList();

public Document()

{

t his.CreatePages();

}

abstract public void CreatePages();

}

//具体工厂1

class Report:Document

{

override public void CreatePages()

{

pages.add(new skillPage());

pages.add(new educationPage());

...

}

}

优势:

(1)核心是 抽象工厂类 各种具体工厂类 通过继承 将 工厂方法继承下来 ,如此 客户只关心 抽象产品和抽象工厂,不用理会返回的是哪一种具体产品,被哪一个具体工厂创建的

(2) 关键是 : 基于工厂角色和产品角色的多态性设计

(3) 扩展性好: 添加新产品时,不需要更改 抽象产品和抽象工厂的接口,只需要添加相对应的具体工厂类和具体产品类就看可以了

缺点:加入新的产品,要添加新的具体产品类,和与之对应的具体工厂类,当二者比较简单时,系统会有相对的额外开销

应用:

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

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

客户需要清楚创建了哪一个对象;

3.Abstract Factory Pattern 抽象工厂模式 kit模式

与工厂方法模式 最大的区别: Factory Method Pattern针对的是一个产品等级结构,而 abstract Factory中针对的是多个产品等级结构

重点:产品族的概念

抽象工厂就是要生成产品族.在这个产品族中,各产品之间有关联耦合,抽象工厂将这些关联耦合设计成一个抽象类.其符合 grasp中的 Pure Fabrication模式,同时取得 高内聚和低耦合的效果

参与者:

抽象工厂 Abstract Factory :声明生成抽象产品的方法

具体工厂 Concrete Factory :执行 生成抽象产品的方法 ,生成一个 具体的产品.

抽象产品 Abstract Product :为一种产品声明接口

具体产品 Product:定义 具体工厂生成的具体产品的对象,实现产品接口

关系类:表达各产品族之间的联系类

顺序图:

client -> 创建抽象工厂a->生成产品a->生成产品b->....

client -> 创建抽象工厂b->生成产品a->生成产品b->....

实例:

扩展了的兵工厂

大陆生态系统:

//抽象大陆工厂

abstract class ContinentFactory

{

abstract public Herbivore createHerbivore();

abstract public Carnivore createCarnivore();

}

//非洲大陆,有角马 狮子

class AfricaFactory:ContinentFactory

{

override public Herbivore createHerbivore()

{

return new Wildebeest();

}

override public Carnivore createCarnivore()

{

return new Lion();

}

}

//美洲大陆,有狼/野牛

class AmericaFactory:ContinentFactory

{

override public Herbivore createHerbivore()

{

return new Bison();

}

override public Carnivore createCarnivore()

{

return new Wolf();

}

}

//食草动物

abstract class Herbivore

{

}

//食肉动物

abstract class Carnivore

{

abstract public void Eat(Herbinore h);

}

//角马/野牛 略

//狮子/狼 略

//动物世界类 (描述 在不同大陆 ,动物之间的食物链 关系责任)

class AnimalWorld

{

private Herbivore herbivore;

private Carnivore carnivore;

//创建两种动物分类

public AnimalWorld(ContinentFactory factory)

{

carnivore=factory.createCarnivore();

herbivore=factory.createHerbivore();

}

//运行食物链

public void RunFoodChain()

{

carnivore.Eat();

}

}

//测试程序

static void main()

{

//创造并运行非洲动物世界

ContinentFactory africa=new AfricaFactory();

AnimalWorld africaWorld=new AnimalWorld(africa);

africaWorld.RunFoodChain();

}

优点 :

隔离了具体类的生成,使得客户不需要知道什么被创建了.这样就使更换一个具体工厂变得相对容易.

最大好处:当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象.这对于那些需要根据当前环境来决定其行为的软件系统来说,是非常实用的一种设计模式.

缺点:

在添加新的产品对象时,难以扩展抽象工厂以便生产新种类的产品.如果要对该接口进行扩展,就需要涉及到对AbstractFactory及其所有之类的修改,显然有小小的不变,但不是很重要;

应用:

系统需要屏蔽有关对象如何创建/如何组织和如何表示

系统需要由关联的多个对象来构成

有关联的多个对象需要一起应用并且他们的约束是强迫的(不可分离)

你想提供一组对象而不显示他们的实现过程,只显示他们的接口
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: