![](/icons/39746yi.gif)
、 设计模式
![](/icons/39746de.gif)
隐喻
武功套路是习武
![](/icons/39746de.gif)
门径
![](/icons/39746dou2.gif)
新手要
![](/icons/39746yi.gif)
招
![](/icons/39746yi.gif)
式地练习套路
![](/icons/39746dou.gif)
烂熟于心的后
![](/icons/39746dou.gif)
熟能生巧
![](/icons/39746dou.gif)
在实战的中即可见招拆招、运用自如——此时习武的人已从“新手”成长为“好手”
![](/icons/39746dou2.gif)
“高手”则没有套路
![](/icons/39746dou.gif)
实战的中只有自然反应
![](/icons/39746dou.gif)
然而
![](/icons/39746yi.gif)
招
![](/icons/39746yi.gif)
式浑然天成、恰到好处
![](/icons/39746dou.gif)
似有似无、无中生有
![](/icons/39746dou2.gif)
“高手”的上还有“高高手”
![](/icons/39746dou.gif)
他们达到
![](/icons/39746de.gif)
境界非我等凭借金氏武侠小说可以揣测
![](/icons/39746dou2.gif)
设计模式的于设计
![](/icons/39746dou.gif)
好比套路的于武术
![](/icons/39746dou2.gif)
“新手”要
![](/icons/39746yi.gif)
个接
![](/icons/39746yi.gif)
个地学习模式
![](/icons/39746dou.gif)
“好手”能够活用模式
![](/icons/39746dou.gif)
“高手”则没有模式
![](/icons/39746dou2.gif)
设计模式
![](/icons/39746de.gif)
“内功”是面向对象
![](/icons/39746de.gif)
基本原则
![](/icons/39746dou2.gif)
这些原则是“神”
![](/icons/39746dou.gif)
模式是“形”
![](/icons/39746dou2.gif)
高手拼
![](/icons/39746de.gif)
是“内功”
![](/icons/39746dou.gif)
对面向对象基本原则有了深刻
![](/icons/39746de.gif)
领悟
![](/icons/39746dou.gif)
才能用好设计模式
![](/icons/39746dou.gif)
避免“走火入魔”
![](/icons/39746yi.gif)
般在设计模式著作
![](/icons/39746de.gif)
前几章都会介绍面向对象
![](/icons/39746de.gif)
基本原则
![](/icons/39746dou.gif)
这几章非常重要
![](/icons/39746dou2.gif)
学通了这几章
![](/icons/39746dou.gif)
后面
![](/icons/39746de.gif)
模式就不过如此了
![](/icons/39746dou2.gif)
学完了设计模式
![](/icons/39746dou.gif)
也最好翻过头来重新看看这几章
![](/icons/39746dou.gif)
保证会有新
![](/icons/39746de.gif)
领悟
![](/icons/39746dou2.gif)
2、 为什么使用设计模式
对任何设计都可以凭主观(对设计很难做出客观评价)判断得出它是
![](/icons/39746yi.gif)
个好
![](/icons/39746de.gif)
设计
![](/icons/39746dou.gif)
还是
![](/icons/39746yi.gif)
个坏
![](/icons/39746de.gif)
设计
![](/icons/39746dou2.gif)
使用设计模式是为了避免坏
![](/icons/39746de.gif)
设计
![](/icons/39746dou2.gif)
Martin叔叔在他
![](/icons/39746de.gif)
著作
![](/icons/39746smhl.gif)
敏捷软件Software开发 原则、模式和实战
![](/icons/39746smhr.gif)
中描述了拙劣设计
![](/icons/39746de.gif)
症状:
僵化性(Rigidity):设计难以改变
![](/icons/39746dou2.gif)
脆弱性(Fragility):设计易于遭到破坏
![](/icons/39746dou2.gif)
牢固性(Immobility):设计难以重用
![](/icons/39746dou2.gif)
粘滞性(Viscosity):难以做正确
![](/icons/39746de.gif)
事情
![](/icons/39746dou2.gif)
不必要
![](/icons/39746de.gif)
复杂性(Needless Complexity):过分设计
![](/icons/39746dou2.gif)
不必要
![](/icons/39746de.gif)
重复(Needless Repetition):过多
![](/icons/39746de.gif)
重复
![](/icons/39746dou2.gif)
晦涩性(Opacity):混乱
![](/icons/39746de.gif)
表达
3、 什么时候使用设计模式
Martin叔叔
![](/icons/39746de.gif)
书中有段话:
在学习它们(设计原则和模式)
![](/icons/39746de.gif)
时候
![](/icons/39746dou.gif)
请记住
![](/icons/39746dou.gif)
敏捷开发人员不会对
![](/icons/39746yi.gif)
个庞大
![](/icons/39746de.gif)
预先设计应用那些原则和模式
![](/icons/39746dou2.gif)
相反
![](/icons/39746dou.gif)
这些原则和模式被应用在
![](/icons/39746yi.gif)
次次
![](/icons/39746de.gif)
迭代中
![](/icons/39746dou.gif)
力图使代码以及代码所表达
![](/icons/39746de.gif)
设计保持干净
![](/icons/39746dou2.gif)
在这段容易被读者忽略
![](/icons/39746de.gif)
文字中
![](/icons/39746dou.gif)
我体会到这样几层含义:
代码是设计(这是Martin叔叔强调
![](/icons/39746de.gif)
![](/icons/39746yi.gif)
个观点
![](/icons/39746dou.gif)
这个观点可以参考
![](/icons/39746smhl.gif)
敏捷软件Software开发 原则、模式和实战
![](/icons/39746smhr.gif)
![](/icons/39746yi.gif)
书
![](/icons/39746de.gif)
附录D);
设计模式是为了使设计适应变化;
设计模式是重构
![](/icons/39746de.gif)
工具;
设计
![](/icons/39746yi.gif)
开始就要保持干净、简单
![](/icons/39746dou.gif)
以后仍然要保持干净、简单;
不能过度使用设计模式
使用设计模式
![](/icons/39746de.gif)
目
![](/icons/39746de.gif)
是为了适应未来
![](/icons/39746de.gif)
变化
![](/icons/39746dou.gif)
变化的所以存在是
![](/icons/39746yinwei.gif)
它
![](/icons/39746de.gif)
不可预知性——如果可以预知
![](/icons/39746dou.gif)
则不能称其为变化
![](/icons/39746dou2.gif)
如何判断哪些需求可能变化
![](/icons/39746dou.gif)
哪些需求可能不变
![](/icons/39746dou.gif)
并且在最大程度上保持设计
![](/icons/39746de.gif)
干净、简单
![](/icons/39746dou.gif)
这是些工艺问题
![](/icons/39746dou.gif)
而不是工程问题
![](/icons/39746dou2.gif)
既然是工艺问题
![](/icons/39746dou.gif)
那么就只能给出原则
![](/icons/39746dou.gif)
不能给出标准
![](/icons/39746dou2.gif)
使用设计模式
![](/icons/39746de.gif)
大体原则可能是:对未来极有可能发生变化
![](/icons/39746de.gif)
问题给出最简单、修改成本最低
![](/icons/39746de.gif)
解
![](/icons/39746dou2.gif)
4、 避免过度使用设计模式
易维护
![](/icons/39746de.gif)
![](/icons/39746chengxu.gif)
首先要易理解
![](/icons/39746dou.gif)
这
![](/icons/39746yi.gif)
点远甚于其他
![](/icons/39746dou2.gif)
在易理解
![](/icons/39746de.gif)
代码上才好维护
![](/icons/39746dou2.gif)
过分地使用设计模式会增加
![](/icons/39746chengxu.gif)
![](/icons/39746de.gif)
复杂性和晦涩性
![](/icons/39746dou.gif)
让
![](/icons/39746chengxu.gif)
不易理解
![](/icons/39746dou.gif)
从而降低了
![](/icons/39746chengxu.gif)
![](/icons/39746de.gif)
易维护性
![](/icons/39746dou2.gif)
Switch语句曾经遭致诟病
![](/icons/39746dou.gif)
许多重构
![](/icons/39746de.gif)
例子就是拿Switch开刀
![](/icons/39746dou2.gif)
我认为Switch语句是高效
![](/icons/39746de.gif)
语句
![](/icons/39746dou.gif)
可以写出极优雅、简单
![](/icons/39746de.gif)
代码
![](/icons/39746dou2.gif)
在很多情况下
![](/icons/39746dou.gif)
直接使用Switch语句比把它拆成若干个Class更“干净”
![](/icons/39746dou2.gif)
再比如
![](/icons/39746dou.gif)
有
![](/icons/39746yi.gif)
段 4百多行
![](/icons/39746de.gif)
代码负责整个系统
![](/icons/39746de.gif)
调度
![](/icons/39746dou.gif)
如果未来
![](/icons/39746de.gif)
变化仅仅是修改这 4百行代码而不会大量添加代码
![](/icons/39746dou.gif)
那么把这 4百多行代码集中在
![](/icons/39746yi.gif)
个
![](/icons/39746hanshu.gif)
里面
![](/icons/39746dou.gif)
比将它拆分成十来个Class更加容易维护
![](/icons/39746dou2.gif)
5、 讨论几个具体
![](/icons/39746de.gif)
模式
1、 创建模式(Creational Pattern)
工厂(Factory Method)模式是常用
![](/icons/39746de.gif)
模式
![](/icons/39746dou2.gif)
工厂模式
![](/icons/39746de.gif)
应用情景明确
![](/icons/39746dou.gif)
设计思想简单
![](/icons/39746dou2.gif)
从使用多态到只用
![](/icons/39746yi.gif)
个静态思路方法
![](/icons/39746dou.gif)
工厂模式
![](/icons/39746de.gif)
变化形式有很多
![](/icons/39746dou2.gif)
我习惯简单地使用工厂模式
![](/icons/39746dou.gif)
也就是使用只有静态思路方法
![](/icons/39746de.gif)
工厂模式
![](/icons/39746dou2.gif)
下面
![](/icons/39746de.gif)
工厂模式代码简单、干净:
MyFactory.GetClassInstance
![](/icons/39746kh.gif)
.DoFunction
![](/icons/39746kh.gif)
;
类厂并不承载业务逻辑
![](/icons/39746dou.gif)
需求变化对类厂
![](/icons/39746de.gif)
影响通常很小
![](/icons/39746dou2.gif)
因此使用重量级
![](/icons/39746de.gif)
工厂模式往往并不划算
![](/icons/39746dou2.gif)
![](/icons/39746yi.gif)
组包含层次关系
![](/icons/39746de.gif)
重量级
![](/icons/39746de.gif)
工厂类
![](/icons/39746dou.gif)
可能意味着过度设计
![](/icons/39746dou2.gif)
单例(Singleton)模式和工厂模式关系密切
![](/icons/39746dou2.gif)
从实现
![](/icons/39746de.gif)
角度讲
![](/icons/39746dou.gif)
单例模式是工厂模式
![](/icons/39746de.gif)
![](/icons/39746yi.gif)
个特例
![](/icons/39746dou.gif)
但是两个模式
![](/icons/39746de.gif)
应用情景区别
![](/icons/39746dou.gif)
因此它们属于区别
![](/icons/39746de.gif)
模式
![](/icons/39746dou2.gif)
抽象工厂(Abstract Factory)模式是工厂模式
![](/icons/39746de.gif)
推广
![](/icons/39746dou2.gif)
抽象工厂模式
![](/icons/39746de.gif)
应用情景更加特殊和严格
![](/icons/39746dou2.gif)
在
![](/icons/39746yi.gif)
个使用抽象工厂
![](/icons/39746de.gif)
设计中
![](/icons/39746dou.gif)
如果未来发生区别产品族各自演化
![](/icons/39746de.gif)
情形
![](/icons/39746dou.gif)
那么抽象工厂模式就可能崩溃了
![](/icons/39746dou2.gif)
在实际应用中
![](/icons/39746dou.gif)
区别产品族各自演化
![](/icons/39746dou.gif)
最终分道扬镳
![](/icons/39746de.gif)
情形是有
![](/icons/39746de.gif)
![](/icons/39746dou.gif)
用户提出这样
![](/icons/39746de.gif)
需求
![](/icons/39746de.gif)
确让人“触目惊心”
![](/icons/39746dou2.gif)
在使用抽象工厂模式的前
![](/icons/39746dou.gif)
![](/icons/39746yi.gif)
定要保证从现在到未来都能够用
![](/icons/39746yi.gif)
致
![](/icons/39746de.gif)
方式使用这些产品族
![](/icons/39746dou2.gif)
将工厂模式稍加变化可以得到建造(Builder)模式
![](/icons/39746dou2.gif)
工厂模式
![](/icons/39746de.gif)
“加工工艺”是隐藏
![](/icons/39746de.gif)
![](/icons/39746dou.gif)
而建造模式
![](/icons/39746de.gif)
“加工工艺”是暴露
![](/icons/39746de.gif)
![](/icons/39746dou2.gif)
这点区别
![](/icons/39746dou.gif)
使建造模式在更加灵活
![](/icons/39746de.gif)
同时也有失优雅
![](/icons/39746dou2.gif)
2、 模板模式(Template Method)和策略(Strategy)模式
模板模式和策略模式
![](/icons/39746de.gif)
应用情景类似
![](/icons/39746dou.gif)
但实现方式区别
![](/icons/39746dou.gif)
前者使用继承
![](/icons/39746dou.gif)
后者使用委托
![](/icons/39746dou2.gif)
模板模式有可能是最“古老”
![](/icons/39746de.gif)
模式的
![](/icons/39746yi.gif)
![](/icons/39746dou.gif)
在使用面向对象技术
![](/icons/39746de.gif)
早期
![](/icons/39746dou.gif)
“继承”大行其道
![](/icons/39746dou.gif)
很多设计人员可能不自觉地使用过模板模式
![](/icons/39746dou2.gif)
模板模式
![](/icons/39746de.gif)
缺点是把具体实现和通用算法紧密地耦合起来
![](/icons/39746dou.gif)
使得具体实现只能被
![](/icons/39746yi.gif)
个通用算法操纵
![](/icons/39746dou2.gif)
然而在继承关系中
![](/icons/39746dou.gif)
父类
![](/icons/39746de.gif)
信息可以更多地暴露给子类
![](/icons/39746dou.gif)
这种(违背面向对象设计原则
![](/icons/39746de.gif)
)微妙
![](/icons/39746de.gif)
沟通在
![](/icons/39746yi.gif)
些特定应用中显得更加灵活和方便
![](/icons/39746dou2.gif)
策略模式是委托
![](/icons/39746de.gif)
经典使用方法
![](/icons/39746dou2.gif)
策略模式消除了通用算法和具体实现
![](/icons/39746de.gif)
耦合
![](/icons/39746dou.gif)
使得具体实现可以被多个通用算法操纵
![](/icons/39746dou2.gif)
策略模式也增加了类层次
![](/icons/39746dou.gif)
比模板模式复杂
![](/icons/39746dou2.gif)
模板模式和策略模式通常可以互相替换
![](/icons/39746dou2.gif)
它们都像试卷
![](/icons/39746dou.gif)
模板模式是填空题
![](/icons/39746dou.gif)
策略模式是选择题
![](/icons/39746dou2.gif)
3、 简化问题
![](/icons/39746de.gif)
模式
门面(Facade)模式把
![](/icons/39746yi.gif)
组复杂
![](/icons/39746de.gif)
接口隐藏在
![](/icons/39746yi.gif)
个简单且特定
![](/icons/39746de.gif)
接口后面
![](/icons/39746dou2.gif)
调停者(Mediator)模式把对象的间
![](/icons/39746de.gif)
引用关系包装在
![](/icons/39746yi.gif)
个特定
![](/icons/39746de.gif)
容器里面
![](/icons/39746dou2.gif)
组合(Composite)模式描述了整体和部分
![](/icons/39746de.gif)
结构关系
![](/icons/39746dou.gif)
并且允许用
![](/icons/39746yi.gif)
致
![](/icons/39746de.gif)
方式处理这个结构
![](/icons/39746dou2.gif)
上面几个模式对使用者而言
![](/icons/39746dou.gif)
都在
![](/icons/39746yi.gif)
定程度上起到了简化问题
![](/icons/39746de.gif)
作用
![](/icons/39746dou2.gif)
4、 扩展功能
![](/icons/39746de.gif)
模式
访问者(Visitor)模式和装饰(Decorator)模式都可以在不改变现有类结构
![](/icons/39746de.gif)
基础上
![](/icons/39746dou.gif)
动态地增加功能
![](/icons/39746dou2.gif)
访问者模式把现有类结构上
![](/icons/39746de.gif)
对象“分配”到
![](/icons/39746yi.gif)
个名为访问者
![](/icons/39746de.gif)
类中
![](/icons/39746dou.gif)
在访问者
![](/icons/39746de.gif)
相应思路方法中配置对象、改变对象或扩展功能
![](/icons/39746dou2.gif)
装饰模式把现有类结构上
![](/icons/39746de.gif)
对象“注入”
![](/icons/39746yi.gif)
个装饰类中
![](/icons/39746dou.gif)
在装饰类中扩展它
![](/icons/39746de.gif)
功能
![](/icons/39746dou2.gif)
访问者模式和装饰模式在实际效果上是区别
![](/icons/39746de.gif)
![](/icons/39746dou2.gif)
访问者模式可以把对象分配到相应
![](/icons/39746de.gif)
思路方法里
![](/icons/39746dou.gif)
从而对每个对象分别进行加工或扩展
![](/icons/39746dou2.gif)
而装饰模式只能用
![](/icons/39746yi.gif)
致
![](/icons/39746de.gif)
方式对所有
![](/icons/39746de.gif)
被装饰对象进行加工或扩展
![](/icons/39746dou.gif)
要想实现区别
![](/icons/39746de.gif)
加工或扩展
![](/icons/39746dou.gif)
只能增加新
![](/icons/39746de.gif)
装饰类
![](/icons/39746dou2.gif)
过多
![](/icons/39746de.gif)
“装饰类”有可能使业务逻辑分散
![](/icons/39746dou.gif)
并且使
![](/icons/39746chengxu.gif)
结构复杂
![](/icons/39746dou2.gif)
针对每
![](/icons/39746yi.gif)
个具体
![](/icons/39746de.gif)
派生类
![](/icons/39746dou.gif)
“访问类”都要有
![](/icons/39746yi.gif)
个对应
![](/icons/39746de.gif)
思路方法
![](/icons/39746dou.gif)
增加派生类
![](/icons/39746de.gif)
时候也要增加访问类
![](/icons/39746de.gif)
思路方法
![](/icons/39746dou2.gif)
扩展功能
![](/icons/39746de.gif)
需求是经常发生
![](/icons/39746de.gif)
![](/icons/39746dou.gif)
是否有必要使用上述模式则值得再 3考虑
![](/icons/39746dou2.gif)
5、 其他常用
![](/icons/39746de.gif)
模式
桥梁(Bridge)模式
![](/icons/39746dou2.gif)
Class是封装了行为和属性
![](/icons/39746de.gif)
容器
![](/icons/39746dou.gif)
然而Class
![](/icons/39746de.gif)
![](/icons/39746yi.gif)
组行为可能独立演化
![](/icons/39746dou.gif)
这时最直接
![](/icons/39746de.gif)
想法是使用继承
![](/icons/39746dou.gif)
把各不相同
![](/icons/39746de.gif)
行为封装在区别
![](/icons/39746de.gif)
子类里
![](/icons/39746dou2.gif)
桥梁模式从另外
![](/icons/39746de.gif)
角度解决了这个问题
![](/icons/39746dou2.gif)
桥梁模式把独立演化
![](/icons/39746de.gif)
行为封装在另外
![](/icons/39746yi.gif)
个类体系里
![](/icons/39746dou.gif)
和原来
![](/icons/39746de.gif)
类体系分别独立演化
![](/icons/39746dou.gif)
两个类体系在抽象层次是“使用”关系
![](/icons/39746dou2.gif)
在很多OO教材里面用Shape类封装属性和Draw思路方法
![](/icons/39746dou.gif)
在桥梁模式里
![](/icons/39746dou.gif)
“形状”和“画笔”是两组独立演化
![](/icons/39746de.gif)
类体系
![](/icons/39746dou.gif)
在抽象层次
![](/icons/39746dou.gif)
“形状”使用“画笔”绘制自己
![](/icons/39746dou2.gif)
适配器(Adapter)模式是常用模式
![](/icons/39746dou.gif)
它比较简单
![](/icons/39746dou.gif)
有时和其他
![](/icons/39746de.gif)
模式配合使用
![](/icons/39746dou2.gif)
命令(Command)模式被Martin称为“最简单、最优雅
![](/icons/39746de.gif)
模式的
![](/icons/39746yi.gif)
”
![](/icons/39746dou2.gif)
命令模式
![](/icons/39746de.gif)
魅力在于它为每个类“培训”出了相同
![](/icons/39746de.gif)
技能
![](/icons/39746dou.gif)
经过“培训”
![](/icons/39746de.gif)
类“柔性”更强
![](/icons/39746dou.gif)
能够产生不可思议
![](/icons/39746de.gif)
能力
![](/icons/39746dou2.gif)
6、 不太需要
![](/icons/39746de.gif)
模式
观察者(Observer)模式
![](/icons/39746dou2.gif)
Java和C# 都实现了观察者模式
![](/icons/39746dou2.gif)
迭代子(Iterator)模式
![](/icons/39746dou2.gif)
在Java和C#语言里
![](/icons/39746dou.gif)
可以用聚集类代替
![](/icons/39746dou2.gif)
备忘录(Memento)模式
![](/icons/39746dou2.gif)
可以用Class
![](/icons/39746de.gif)
序列化能力代替
![](/icons/39746dou2.gif)
责任链(Chain of Responsibility)模式
![](/icons/39746dou2.gif)
可以用其他
![](/icons/39746de.gif)
方式替代
![](/icons/39746dou.gif)
例如观察者模式、语言本身提供
![](/icons/39746de.gif)
消息机制等
![](/icons/39746dou2.gif)
解释器(Interpreter)模式
![](/icons/39746dou2.gif)
个人认为
![](/icons/39746dou.gif)
它是个算法
![](/icons/39746dou.gif)
不是模式
![](/icons/39746dou2.gif)
代理(Proxy)模式
![](/icons/39746dou2.gif)
如果在
![](/icons/39746yi.gif)
开始就知道某些底层策略
![](/icons/39746yi.gif)
定会被替换掉
![](/icons/39746dou.gif)
那么使用代理来隔离这些策略还是有必要
![](/icons/39746de.gif)
![](/icons/39746dou2.gif)
否则
![](/icons/39746dou.gif)
几乎没有使用
![](/icons/39746de.gif)
必要
延伸阅读
最新评论