進入新章節
1
Make it Stick
有些人已经解决你的问题了。在本章,你将学习到为何(以及如
何)利用其他开发人员的经验与智慧。他们遭遇过相同的问题,也顺利地解
决过这些问题。本章结束前,我们会看到设计模式的使用与优点,看看某些
关键的OO设计原则,并透过一个例子来了解模式如何运作。使用模式最好的
方式是:「把模式装进脑子中,然后在你的设计和已有的应用中,寻找何处
可以使用这些模式。」以往是代码复用,现在是经验复用。
欢迎来到
设计模式
1 介绍设计模式
我们已经搬到对象
村,刚刚开始着手设计模式...
这里每个人都在使用设计模式。
很快我们就会透过设计模式挤
身上流社会。
2
第一章
先从简单的模拟鸭子应用做起
Joe上 班 的公司做 了 一套相当 成 功的模拟 鸭 子游戏: S imUD u ck。
游 戏 中 出 现 各 种 鸭 子 , 一 边 游 泳 戏 水 , 一 边 呱 呱 叫 。 此 系 统
的 内 部 设 计 使 用 了 标 准 的 O O 技 术 , 设 计 了 一 个 鸭 子 超 类 (
Superclass),并让各种 鸭 子 继 承 此 超类。
Duck
quack()
swim()
display()
//
鸭子 的其他方法
display() {
//
外观 是绿头
}
MallardDuck
display() {
//
外 观是红头
}
RedheadDuck
许 多 其 他 类 型的 鸭 子 继承
Duck类。
每 个 鸭 子 子 类
型 ( s u b t y p e )
负 责 实 现 自 己 的
d i s p la y( ) 行 为
在 屏 幕 上 显 示 其
外观。
所 有 的 鸭 子 都 会 呱
呱叫( Quack )也会
游 泳 ( S w i m ) , 所
以 由 超 类 负 责 处 理
这部分的实现 代码。
去 年 , 公 司 的 竞 争 压 力 加 剧 。 在 一 个 星 期 长 的 高 尔 夫 假
期 兼 头 脑 风 暴 会 议 之 后 , 公 司 主 管 认 为 该 是 创 新 的 时 候
了 , 他 们 需 要 在 「 下 周 」 股 东 会 议 上 展 示 一 些 「 真 正 」
让人印象深刻的东西来振奋人心。
因 为 每 一 种 鸭 子 的
外 观 都 不 同 , 所 以
di sp la y( )方 法是 抽
象的。
模拟鸭子
介紹設計模式
目前位置
�
3
Joe
我 只 需 要 在 D u c k 类 中 加 上
fly()方法,然后 所 有 鸭 子 都 会
继承fly()。这是我大显身手,展
示OO才华的时候了。
所 有 的 子 类
都 会 继 承
fly()
Joe加上的
主 管 认 为 , 此 模 拟 程 序 需 要 会 飞 的 鸭 子 , 将 竞 争 者 抛 在
后头。当然,在这个时候,Joe的经理拍胸脯告诉主管们,
J o e 只 需 要 一 个 星 期 就 可 以 搞 定 , 「 毕 竟 , J o e 是 一 个 O O
程序员...这有什么困难?」
现在我们得让鸭子能飞
其他的鸭子类 型...
Duck
quack()
swim()
display()
y()
//
鸭子 的其他方法 ... .
display() {
//
外观 是绿头
}
MallardDuck
display() {
//
外观 是红头
}
RedheadDuck
我们想要的
4
第一章
他 体 会 到 了
一 件 事 : 当
涉 及 「 维 护 」
时,为了「复
用」(reuse)
目的而使用继
承,结局并不
完美。
好吧!我承认设计中有一点小
疏失。但是,他们怎么不干脆把
这当成一种「特色」,其实还挺
有趣的呀..
J o e , 我 正 在 股 东 会 议 上 ,
刚 刚 看 了 一 下 展 示 , 有 一
只「橡皮鸭子」在屏幕上飞来飞去,这
是你开的玩 笑吗?你可能要开始 去逛逛
Monster.com(编注:美国最大的求职网
站)了...
Joe忽略了一件事:并非Duck 所有
的 子 类 都 会 飞 。 当 J o e 在 D u c k 超 类
中 加 上 新 的 行 为 , 这 会 使 得 某 些 子
类 也 具 有 这 个 不恰 当 的行 为 。现 在
可好 了 !S i mU D uc k 程序 中 有一 个 会
飞的非动物。
对 代 码 所 做的 局部 修 改 , 影响 层 面
可能不只局部(会飞的橡皮鸭)!
怎么回事?
quack()
swim()
display()
y()
//
鸭子 的其他方法
display() {
//
外观 是绿头
}
MallardDuck
display() {
//
外观 是红头
}
RedheadDuck
quack() {
//
覆盖 成吱吱叫
}
display() {
//
外观 是橡皮鸭
}
RubberDuck
Duck
橡 皮 鸭 子 不 会
呱 呱 叫 , 所 以
把 q u a c k ( ) 的
定 义 覆 盖 成 「 吱 吱
叫」(squ eak)。
在 超 类 中 加 上
f l y ( ) , 就 会 导 致
所 有 的 子 类 都 具 备
f l y ( ) , 连 那 些 不
该 具 备 f l y ( ) 的 子
类也无法免除 。
但是,可怕的问题发生了 ...
事情出错了
介紹設計模式
目前位置
�
5
Joe想到继承
我 可 以 把 橡 皮 鸭 类
中 的 f l y ( ) 方 法 覆 盖 掉 , 就
好 像 覆 盖 q u a c k ( ) 的 作 法 一
样...
quack() { //
吱吱 叫
}
display() { //
橡皮 鸭
}
y() {
//
覆盖 ,变成什么 事都不做
}
RubberDuck
削尖你的鉛筆
q A.
代码在多 个子类中重复。
q B.
运行时的 行为不容易改变 。
q C.
我们不能 让鸭子跳舞。
q D.
难以得知 所有鸭子的全部 行 为。
q E.
鸭子不能 同时又飞又叫。
q F.
改变会牵 一发动全身,造 成 其他鸭子不想
要的改变 。
利用继承来提供Duck的行为,这 会 导 致 下 列 哪些缺点?(多选)
quack() {
//
覆盖 ,变成什么 事都不做
}
display() { //
诱饵 鸭
}
y() {
//
覆盖 ,变成什么 事都不做
}
DecoyDuck
这是继 承层次中 的另一 个
类 。 注 意 , 诱 饵 鸭 既 不
会飞也 不会叫, 可是橡 皮
鸭不会飞但会 叫。
可 是 , 如 果 以 后 我 加 入 诱
饵 鸭 ( D e c o y D u c k ) , 又
会 如 何 ? 诱 饵 鸭 是假 鸭 ,不 会
飞也不会叫...
评论0