设计模式可复用面向对象软件的基础 第3章 创建(14)
发布时间:2021-06-05
发布时间:2021-06-05
本书设计实例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。本书分类描述了一组设计良好,表达清楚的软件设计模式,这些模式在实用环境下有特别有用
1 )它使你可以改变一个产品的内部表示 B u i l d e r对象提供给导向器一个构造产品的抽象接口。该接口使得生成器可以隐藏这个产品的表示和内部结构。它同时也隐藏了该产品是如何装配的。因为产品是通过抽象接口构造的,你在改变该产品的内部表示时所要做的只是定义一个新的生成器。
2) 它将构造代码和表示代码分开 B u i l d e r模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。客户不需要知道定义产品内部结构的类的所有信息;这些类是不出现在B u i l d e r接口中的。每个 C o n c r e t e B u i l d e r包含了创建和装配一个特定产品的所有代码。这些代码只需要写一次;然后不同的 D i r e c t o r可以复用它以在相同部件集合的基础上构作不同的 P r o d u c t。在前面的RT F例子中,我们可以为 RT F格式以外的格式定义一个阅读器,比如一个 S G M L R e a d e r,并使用相同的 Te x t C o n v e r t e r生成 S G M L文档的 A S C I I Te x t、Te X Te x t和 Te x t Wi d g e t译本。
3 )它使你可对构造过程进行更精细的控制 B u i l d e r模式与一下子就生成产品的创建型模式不同,它是在导向者的控制下一步一步构造产品的。仅当该产品完成时导向者才从生成器中取回它。因此 B u i l d e r接口相比其他创建型模式能更好的反映产品的构造过程。这使你可以更精细的控制构建过程,从而能更精细的控制所得产品的内部结构。
8. 实现通常有一个抽象的 B u i l d e r类为导向者可能要求创建的每一个构件定义一个操作。这些操
作缺省情况下什么都不做。一个 C o n c r e t e B u i l d e r类对它有兴趣创建的构件重定义这些操作。
这里是其他一些要考虑的实现问题:
1) 装配和构造接口生成器逐步的构造它们的产品。因此 B u i l d e r类接口必须足够普遍,以便为各种类型的具体生成器构造产品。
一个关键的设计问题在于构造和装配过程的模型。构造请求的结果只是被添加到产品中,通常这样的模型就已足够了。在 RT F的例子中,生成器转换下一个标记并将它添加到它已经转换了的正文中。
但有时你可能需要访问前面已经构造了的产品部件。我们在代码示例一节所给出的 M a z e例子中,M a z e B u i l d e r接口允许你在已经存在的房间之间增加一扇门。像语法分析树这样自底向上构建的树型结构就是另一个例子。在这种情况下,生成器会将子结点返回给导向者,然后导向者将它们回传给生成者去创建父结点。
2) 为什么产品没有抽象类通常情况下,由具体生成器生成的产品,它们的表示相差是如此之大以至于给不同的产品以公共父类没有太大意思。在 RT F例子中, A S C I I Te x t和 Te x t Wi d g e t对象不太可能有公共接口,它们也不需要这样的接口。因为客户通常用合适的具体生成器来配置导向者,客户处于的位置使它知道 B u i l d e r的哪一个具体子类被使用和能相应的处理它的产品。
3 )在B u i l d e r中却省的方法为空 C + +中,生成方法故意不声明为纯虚成员函数,而是把它们定义为空方法,这使客户只重定义他们所感兴趣的操作。
9. 代码示例我们将定义一个 C r e a t e M a z e成员函数的变体,它以类 M a z e B u i l d e r的一个生成器对象作为
参数。 M a z e B u i l d e r类定义下面的接口来创建迷宫:
本书设计实例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。本书分类描述了一组设计良好,表达清楚的软件设计模式,这些模式在实用环境下有特别有用
该接口可以创建:1)迷宫。2)有一个特定房间号的房间。3)在有号码的房间之间的门。 G e t M a z e操作返回这个迷宫给客户。 M a z e B u i l d e r的子类将重定义这些操作,返回它们所创建的迷宫。
M a z e B u i l d e r的所有建造迷宫的操作缺省时什么也不做。不将它们定义为纯虚函数是为了便于派生类只重定义它们所感兴趣的那些方法。
用M a z e B u i l d e r接
口,我们可以改变C r e a t e
M a z e成员函数,以生成器
作为它的参数。
将这个C r e a t e M a z
e版本与原来的相比,注意
生成器是如何隐藏迷宫的内部表示的—即定义房间、门和墙壁的那些类—以及这些部件是如何组装成最终的迷宫的。有人可能猜测到有一些类是用来表示房间和门的,但没有迹象显示哪个类是用来表示墙壁的。这就使得改变一个迷宫的表示方式要容易一些,因为所有 M a z e B u i l d e r的客户都不需要被改变。
像其他创建型模式一样, B u i l d e r模式封装了对象是如何被创建的,在这个例子中是通过 M a z e B u i l d e r所定义的接口来封装的。这就意味着我们可以重用 M a z e B u i l d e r来创建不同种类的迷
宫。C r e a t e C o m p
l e x M a z e操作给出
了一个例子:
注意M a z e B u
i l d e r自己并不创建迷宫;它的主要目的仅仅是为创建迷宫定义一个接口。它主要为方便起见定义一些空的实现。 M a z e B u i l d e r的子类做实际工作。
子类S t a n d a r d M a z e B u i l d e r是一个创建简单迷宫的实现。它将它正在创建的迷宫放在变量
_ c u r r e n t M a z e中。
上一篇:WSUS服务器的迁移
下一篇:特种加工论文