设计模式(1) 创建型模式和抽象工厂(Abstract Factory)(一)

2014-11-24 07:20:04 · 作者: · 浏览: 9
问题聚焦:分别用一句话概括这节的几个知识点
什么是创建型模式:抽象了实例化过程
创建型模式有哪些:抽象工厂,工厂方法,原型模式,生成器模式
什么是抽象工厂(AbstractFactory)模式:与接口交互,获得一系列相关或互相依赖的对象实例。


创建型模式
两个主旋律:
它们都将关于该系统使用哪些具体的类的信息封装起来 它们隐藏了这些类的实例是如何被创建和放在一起的
Demo: 迷宫的创建 关注的问题: 迷宫的构件:Room,Wall,Door创建迷宫:使用一系列操作将构件增加到迷宫中,然后连接它们,切忌不可以通过硬编码的方式增加构件增加新的构件:如只有咒语才能打开的Door, 以及如何比较容易的将这些新构件添加到迷宫中 要想很好的实现上面的要求,硬编码是绝对不可以的。 在使用创建型模式解决这些问题之前,先说明一下这个迷宫游戏的一些类和接口的设定
1 构件的类图 Enter()方法决定你下一个转向将要进入什么,是一个新的房间,或是一个墙壁(就是无法通过)。 \ vcq9oaM8L2Jsb2NrcXVvdGU+CjQg1K3QzcSjyr2jqFByb3RvdHlwZaOpCgo8YmxvY2txdW90ZT7I57n7Q3JlYXRlTWF6ZdPJtuDW1tSt0M21xLe/vOSjrMe9sdq6zcPFttTP87LOyv27r6Osy/y/vbG0sqK9q9Xi0Km21M/z1Pa807W9w9S5rNbQo6zEx8O0xOO/ydLU08Oyu82stcS21M/zzOa7u9Xi0KnUrdDNttTP89LUuMSx5MPUuay1xLm5s8mhozwvYmxvY2txdW90ZT4KCgo8aHI+Cjxicj4KCrPpz/O5pLOnIKOoQWJzdHJhY3QgRmFjdG9yeaOpCjxicj4KCtLizbyjuszhuanSu7j2tLS9qNK7z7XB0M/gudi78s/gu6XSwMC1ttTP87XEvdO/2qOstvjO3tDo1ri2qMv8w8e+38zltcTA4KGjCkRlbW+jugq/vMLH0ru49tans9a24NbWvefD5rfnJiMyNjY4NDu1xNPDu6e958PmuaS+37D8oaMKvefD5rfnJiMyNjY4NDuw/MCoufa2r8z1oaK0sL/aus2wtMWltci0sL/a1+m8/rXEzeK527rN0NDOqqGjCtKqx/OjurGj1qS958Pmt+cmIzI2Njg0O7XEv8nSxtay0NS6zcHpu+7Q1KGjCsnovMajugo8YmxvY2txdW90ZT4Ks+nP88DgV2lkZ2V0RmFjdG9yecDgo6zV4rj2wODJ+cP3wcvSu7j208PAtLS0vajDv9K7wOC7+bG+tLC/2tfpvP61xL3Tv9o8L2Jsb2NrcXVvdGU+Cgo8YmxvY2txdW90ZT7Dv9K7wOC0sL/a1+m8/ra809DSu7j2s+nP88Dgo6y2+L7fzOXX08Dg1PLKtc/Wwcuz6b/a1+m8/rXEzNi2qLXEt+cmIzI2Njg0OzwvYmxvY2txdW90ZT4KPGJsb2NrcXVvdGU+PGJyPgo8L2Jsb2NrcXVvdGU+Cgo8aW1nIHNyYz0="https://www.cppentry.com/upload_files/article/76/1_6zdrg__.jpg" alt="\">
\
使用:
每一种风格标准都对应于一个具体的WidgetFactory子类. 每一子类实现那些用于创建合适风格标准的创口组件的操作.
客户仅与抽象类定义的接口交互,而不使用特定的具体类的接口.
场景: 一个系统要独立于它的产品的创建、组合和表示时一个系统要由多个产品系列中的一个来配置时当要强调一系列相关的产品对象的设计以便进行联合使用时当提供一个产品类库,而只想显示它们的接口而不是实现时 结构: 和上面的窗口组件的创建的设计很相似
\
\
参与者 AbstractFactory:声明一个创建抽象产品对象的操作接口ConcreteFactory:实现创建具体产品对象的操作AbstractProduct:为一类产品对象声明一个接口ConcreteProduct:定义一个将被相应的具体工厂创建的产品对象,实现AbstractProduct接口Client:仅使用由AbstractFactory和AbstractProduct类声明的接口 协作
通常在运行时刻创建一个ConcreteFactory类的实例,这一具体的工厂创建具有特定实现的产品对象。为创建不同的产品对象,客户应使用不同的具体工厂 AbstractFactory将产品对象的创建延迟到它的ConcreteFactory子类
优点 分离了具体的类:用户只通过抽象接口获得实例,被隔离的信息有:创建产品对象的责任和过程,类的实现,类名易于交换产品的系列:一个具体工厂类在一个应用中只出现一次,即是一个单例,所以如果想更换产品系列,只需要使用不同的具体工厂即可,所有生产的接口都是一样的。有利于产品的一致性:当产品对象被设计在一起工作时,一个应用一次只能使用同一个系列中的对象。 缺点 难以支持新种类的产品:抽象工厂接口确定了可以被创建的产品集合,如果要支持新种类的产品,就需要扩展该工厂类和其所有子类的相关接口。 实现 将工厂作为单件:一个应用中一般每个产品系列只需要一个具体工厂实例 创建产品:
通常为每一个产品定义一个工厂方法,一个具体的工厂将为每个产品重定义该工厂方法(Factory Method)以指定产品 如果有多个可能的产品系列,具体工厂也可以使用原型(Prototype)模式来实现。具体工厂使用产品系列中每个产品的原型实例来初始化,且它通过复制它的原型来创建新的产品。
定义可扩展的工厂
增加一种新的产品要求改变AbstractFactory的接口以及所有与它相关的类。 一个更灵活但不太安全的设计是给创建对象的操作增加一个参数,该参数指定了将被创建的对象的种类。使用这种方法,AbstractFactrory只需要一个Make操作和一个指示要创建对象的种类的参数。


代码示例 使用抽象工厂模式创建之前我们所讨论的迷宫
类MazeFactory可以创建迷宫的组件。
class MazeFactory {
public:
    MazeFactory();

    virtual Maze* MakeMaze() const
        { return new Maze; }
    virtual Wall* MakeWall() const
        { return new Wall; }
    virtual Room* MakeRoom(int n) const
        { reutrn new Room(n); }
    virtual Door* MakeDoor(Room* r1, Room* r2) const
        { return new Door(r1, r2); }
};

以MazeFactory为参数的新版本的CreateMaze成员函数
Maze* MazeGame::CreateMaze (MazeFactory& factory)