- 首先介绍方法论,参考了《大道至简 — 软件工程实践者的思想》
- DP与Spring、SOA类比,皆出于实践
- DP的必要性和要点,辅助代码简要说明
- 抛砖引玉,介绍几个DP:
- Factory Pattern
- Decorator Pattern
- Proxy Pattern
- SingLeton Pattern
- Command Pattern
- 其它
- 介绍点:
- a) 使用一些可与现实结合的生动例子(引用网上资源)
- 介绍其本质(个人理解)
- 简要介绍其如何使用
<一>开幕
大家好,我是crazycy,今天我们讨论的主题是Design Pattern
首先感谢千年一叹的安排和付出,虽然他极其的忙。
今天的话题可能不很适合初学者,对于初学者的建议可以看我的文章:http://www.blogjava.net/crazycy/archive/2006/07/07/57106.html
<二> 设计模式的起因
在谈设计模式之前,我们想一下:为什么会有设计模式?
Christopher Alexander说:每一个模式描述了一个在我们周围不断重复发生的问题以及该问题的解决方案的核心。
咱们大多是做研发的,往往有自己的体会,遇到问题--解决问题,这个过程中会发现有一些问题及其解决方案不断变换面孔重复出现,其后面的有着共同的本质。实际上这些本质就是模式。
从哲学角度说,设计模式的出现是实践经验的结晶,是产生于实践并指导实践。
<三>联想
说到这里,我们现在用的、谈的比较火爆的就是Spring Hibernate之类的框架。是吧?
Struts直接革新了Web Model 2的应用。
Hibernate直接解决了持久层的非面向对象的尴尬。
Spring直接挑战了原先的Java EE框架。
这些都是源于实践。选择一种架构、一种技术的依据是什么? Rod Johnson 认为,应该是基于实践的依据、来自历史项目或亲自试验的经验,而不是任何形式的偶像崇拜或者门户之见。 这个是循序方法:实践的反复总结。(十足的哲学)
为什么说Spring是实践的总结:大家可以看一下我的blog的一片文章http://www.blogjava.net/crazycy/archive/2006/06/05/50519.aspx 比较简略。
<四> 哲学
周爱民先生的《大道至简 — 软件工程实践者的思想》对方法、方法论有如下描述:
============================================================================================================
3. 方法
推动这种逻辑向前发展的,是 “ 方法 ” 和 “ 方法论 ” 的出现。长期的编程实践,自然的归演与总结,必须沉淀为某种 ( 软件开发 ) 方法,于是 “ 过程 ” 出现了,于是 “ 对象 ” 出现了,于是相关的方法论也就出现了。
这是实践的成果。方法不是某个人或者某个组织创造的。瓜熟而蒂落,实践积累达到一定的程度,微软不提出某个方法, IBM 也会提出这个方法。即便他们都不提出,可能你自己已经在使用这个方法了。
方法并不神秘,因为它就是你今天正在做的、从事的和实现的。正如 “ 模式 ” 是一种方法,而模式就是你昨天书写代码的那个行为。只不过, GoF 归纳、抽取、提升了这些行为的内在规律。
你看不到你做事的行为,也就不能理解 “ 模式 ” 作为一种方法的价值。所以大师们众口一词:模式需要一定的编程经验才能理解。
同理,理解过程也需要编程经验,理解对象也需要编程经验,理解 MDA 与 SOA 还是需要编程经验。
—— 这可能就发生在你去回顾你上一行代码编写的经过,或者上一个项目失败的经历的那一瞬息。经验来源于回顾、理解与分析,而不是你将要写的下一行代码。
有人在寺院扫了一辈子的落叶而得道,也有人因为一句话而得道。
感觉不过瘾可以看一下我的blog文章:
http://www.blogjava.net/crazycy/archive/2006/05/24/47799.html
而对于方法论,查了一下大概阐述如下:方法论是一套完整的实践引导体系,是指导实践的理论基础,是人们在长期社会实践中总结和摸索出来的,符合客观发展规律的,符合人们对研究对象进行科学分析与判断的社会实践进程或步骤。方法是实践的成果,如同瓜熟蒂落,实践积累达到一定程度,必然会提出方法。
<五>DP产生的必要性和目标
咱们大家对OO编程都熟悉,OO的三个基本特征:封装、继承、多态。
OO解决不了的问题--Java为例子:
java语言要求将一个类实例化时,必须调用这个类的具体类的构造子,所以java语言给出的类的实例化方法无法做到只依赖抽象类型。
这造成了调用者合被调用者的一种紧耦合
设计模式追求的目标是调用者和被调用者之间的解耦。
示例:
消费一个对象的客户端只依赖于对象的抽象类型,而不是具体类型
A类:
State state = new StartState();
工厂类:
public class StateFactory {
public State static createState() {
State state = new. StartState();
return state;
}
}
A类:
State state = StateFactory.createState();
这样就很容易理解工厂类就是生产对象,也就是创建对象,把对象的创建过程从类A中摘取出来.
这样也就达到了DP的目标,也正是因为这个目标的提出,才诞生了IoC。
可以参考的我blog文章:http://www.blogjava.net/crazycy/archive/2006/03/19/36068.aspx
这里有朋友问抽象工厂和工厂方法两个模式的区别,
可以参考我的blog文章:http://www.blogjava.net/crazycy/archive/2006/10/08/73858.html
<六>介绍几个模式
Decorator模式是
1. 对真实对象进行包装
2. 使其功能扩展
3. 表现形式:new 包装类1(new 包装类2(真实对象));这样真实对象就具备了本身、包装类1、包装类2的功能;
4. 实现时只需要把真实对象做为包装类的聚合对象;
实在不行就想想ML时,如果带上TT后,原来的不影响,而且还安全了。主要就是包装原先的对象。
可参考我的blog文章:http://www.blogjava.net/crazycy/archive/2006/04/30/44169.html
Dynamic Proxy模式是
代理模式(Proxy,这里侧重于Dynamic Proxy)可以理解成给一个对象提供一个代理对象,这个代理对象就是把原对象进行包装,使其与调用处理器相关联。
因为代理对象和真实对象具有相同的接口,客户访问时,通过接口调用代理实例的方法,这个调用会被分发到该实例对应的处理器。处理器在把客户端调用传递给真实的对象之前或者之后,可执行某个操作,也可以选择不把这个调用传递给真实的对象。
1. 将真实对象包装
2. 使其与调用处理类绑定
3. 表现形式:Proxy.newProxyInstance(realObject.getClass(). getClassLoader(), realObject.getClass().getInterfaces(), new InvocationHandler(realObj));这样真实对象就与InvocationHandler类邦定了,对外是一个代理类的形式;
4. 实现时只需要把真实对象做为调用处理器的聚合对象
实在不行就想想:垂帘听政:犹如清朝康熙年间的四大府臣,很多权利不在皇帝手里,必须通过辅佐大臣去办;
具体示例参加blog:
http://www.blogjava.net/crazycy/archive/2006/04/29/44006.html
Command模式
本质:将调用操作的对象 和 知道如何实现改操作的对象 解耦。
1 调用者
发出请求的对象,请求被包装成请求对象的形式(侧重于对象)
2 接收者
知道如何处理某个请求的对象。
3 关联者
具备调用者传入的请求对象;
并且绑定接收者。
大家都用过Struts吧?
或许Struts的Action就是一个很好的说明示例:
Public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res)
方法的action就是关联者
方法的req可以理解成请求者
方法的form 就是请求对象
方法的mapping就是接收者