创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。
创建型模式抛弃了new实例化对象的硬编码——并不是说程序中就看不到new了,而是把这些对象的实例化代码脱离开来,成立一个专门管理对象创建的部门,进一步细化社会分工,各司其职,这就是创建型模式的意义,它使得复杂的组合对象的构建工作灵活起来。
创建型:迷宫!
我们把迷宫这个游戏的其它逻辑要素统统忽略掉,这里只关注迷宫的结构和它的构建过程。
一个迷宫由多个房间组成,而房间又由四个面构成,每个面可以是墙或者门,门是通路,墙是死路,如下图:
创建型表述的就是:怎样合理地创建迷宫各零部件、并且怎样把这些零部件构建成一个完整的迷宫。这中间有很多技巧,灵活的设计使系统能从容的面对变化。
MapSite:迷宫各构件的抽象类。有的构件(如Door)的Enter()可能会改变游戏者的位置,这取决于具体构件的设计。
Room:迷宫构件元素。有四个Side,每一面可以是Wall或者Door。如果是Wall,游戏者Enter时就会碰壁。如果是Door,并且门是开着的话,游戏者Enter时就会进入另一个房间(改变位置/坐标)。
Maze:迷宫。整个迷宫的构成部件都将在这里有序的组织起来。至于用什么数据结构来存放迷宫的零部件,我们暂时不关心,这是设计细节,正是我们希望对外隐藏的。
我们不打算在Maze类中组建迷宫,因为我们希望Maze类只表述“构造好的迷宫的最终状态”,但迷宫的构建方法、流程、步骤,我们应该把这些逻辑分离出来。这里我们定义另一个类MazeGame:
MazeGame::CreateMaze() 就是我们通常所说的简单工厂了。
然而,这远远不够。在CreateMaze() 中,仅仅是创建一个有两个房间的迷宫,代码就这么复杂了。显然得想办法使它变得更简单。例如,在Room的构造函数中可以提前用墙壁来初始化房间的每一面。但这仅仅是将代码移到了其他地方。CreateMaze() 真正的问题不在于它的大小而在于它不灵活。它对迷宫的布局进行了硬编码,改变布局意味着改变这个成员函数,或是重定义它——这意味着重新实现整个过程——或是对它的部分进行改变——这容易产生错误并且不利于重用。
创建型模式显示如何使得这个设计更灵活,但代码量未必会更小。特别是,应用创建型模式后,将便于修改迷宫构件定义的类,更好地应对需求变更。
抽象工厂:多风格UI包
关键字:系列构件的创建
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
适应性:对新系列开放,对新构件关闭。即添加新的产品/构件后,要修改工厂的接口(增加CreateXxx函数)。
应用场景:多风格UI工具包
现在考虑打造一个支持多视感风格的UI工具包,如Windows风格、Motif风格、Mac风格的窗口标准部件(如按钮、标题栏、文本框、滚动条等)。