Dec 21, 2008

《Head First 设计模式》9-13章

Chapter 9:迭代器和组合模式--管理良好的集合
我们能学习如何让客户遍历你的对象而又无法窥视你存储对象的方式;也将学习如何创建一些对象超集合,能够一口气就跳过某些让人望而生畏的数据结构;还将学写到一些关于对象职责的知识。

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的表示。
迭代器模式让我们能游走于聚合内的每一个元素,而不是暴露其内部的表示。
把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。

设计原则:一个类应该只有一个引起变化的原因。
类的每个责任都有改变的潜在区域。超过一个责任,意味着超过一个改变的区域。
这个原则告诉我们,尽量让每个类保持单一责任。

组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一直的方式处理个别对象以及对象组合。
组合模式让我们能用树形方式创建对象的结构,树里面包含了组合以及个别的对象。
使用组合结构,我们能把相同的操作应用在组合和个别对象上。换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的差别。
统一处理个别对象和组合对象。



空迭代器
NullIterator,返回一个迭代器,而这个迭代器得hasNext永远返回false。

要点
迭代器允许访问聚合的元素,而不需要暴露它的内部结构。
迭代器将遍历聚合的工作封装进一个对象中。
当使用迭代器的时候,我们依赖聚合提供遍历。
迭代器提供了一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多态机制。
我们应该努力让一个类只分配一个责任。
组合模式提供一个结构,可同时包容个别对象组合对象
组合模式允许客户对个别对象以及组合对象一视同仁。
组合结构内的任意对象称为组件,组件可以是组合,也可以是叶节点。

在实现组合模式时,有许多设计上的折中。你要根据需要平衡透明性和安全性


Chapter 10:状态模式--事务的状态

策略模式和状态模式是双胞胎,在出生时才分开。


策略模式是围绕可以互换的算法来创建成功业务的。
状态模式通过改变对象内部的状态来帮助对象控制自己的行为。
1 定义一个State接口。在这个接口内,糖果机的每个动作都有一个对应的方法。
2 然后为机器中的每个状态实现状态类。这些类将负责在对应的状态下进行机器的行为。
3 我们要摆脱旧的条件代码,取而代之的方式是,将动作委托到状态类。


状态模式:允许对象在内部状态改变是改变它的行为,对象看起来好像修改了它的类。
要点
状态模式允许一个对象基于内部状态而拥有不同的行为。
和程序状态机PSM不同,状态模式用类代表状态。
Context会将行为委托给当前状态对象。
通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了。


状态模式和策略模式有相同的类图,但是它们的意图不同
策略模式通常会用行为或算法来配置Context类。
状态模式允许Context随着状态的改变而改变行为。
状态装换可以由State类或Context类控制。
使用状态模式通常会导致设计中类的数目大量增加。
状态类可以被多个Context实例共享。


Chapter 11:代理模式--控制对象访问


你是一个白脸,提供很好且很友善的服务,但是你不希望每个人都叫你做事,所以找了黑脸控制对你的访问。


控制和管理访问,这就是代理要做的事。
你的客户对象所做的就像是在做远程方法调用,但其实只是调用本地堆中的“代理”对象上的方法,再由代理处理所有网络通信的低层细节。
1 先浏览并了解一下RMI。
2 我们会把GumballMachine变成远程服务,提供一些可以被远程调用的方法。
3 我们将创建一个能和远程的GumballMachine沟通的代理,这需要用到RMI。
4 最后再结合监视系统,CEO就可以监视任何数量的远程糖果机了。


方法调用是如何发生的
1 客户对象调用客户辅助对象的doBigThing方法。
2 "客户辅助对象打包调用信息(变量,方法名称等),然后通过网络将它运给服务辅助对象。"
3 服务辅助对象把来自客户辅助对象的信息解包,找出被调用的方法(以及在哪个对象内),然后调用真正的服务对象上的真正方法。
4 服务对象上的方法被调用,将结果返回给服务辅助对象。
5 服务辅助对象把调用的返回信息打包,然后通过网络运回给客户辅助对象。
6 客户辅助对象把返回值解包,返回给客户对象。对于客户来说,这是完全透明的。


RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建和服务对象相同的方法。


制作远程服务
1 制作远程接口
2 制作远程的实现
3 利用rmic产生的sub和skeleton
4 启动RMI registry(rmiregistry)
5 开始远程服务

远程代理;虚拟代理:暂时代理初建开销大的对象


代理模式:为另一个对象提供一个替身或占位符以控制这个对象的访问。
使用代理模式创建代表representative对象,让代表对象控制某对象的访问,被代理的对象可以是远程的对象,创建开销大的对象或需要安全控制的对象。
 


要点

代理模式为一个对象提供代表,以便控制客户对对象的访问,管理访问的方式有许多种。
远程代理管理客户和远程对象之间的交互。
虚拟代理控制访问实例化开销大的对象
保护代理基于调用者控制对象方法的访问。
代理模式有许多变体,例如:缓存代理,同步代理,防火墙代理和写入时复制代理
代理在结构上类似装饰者,但是目的不同。
装饰者模式为对象加上行为,而代理则是控制访问。
Java内置的代理支持,可以根据需要建立动态代理,并将所有调用分配到所选的处理器。
就和其他的包装者wrapper一样,代理会造成你的设计中类的数目增加。

Chapter 12: 复合模式--模式中的模式
谁料得到模式居然可以携手合作?

模式常被一起使用,并被组合在同一个设计解决方案中。
复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题。

设计模式是MVC的钥匙。
MVC是由数个设计模式结合起来的模式。如果你能够看着MVC内部的各个模式,MVC的一切就会跟着开始明朗起来。

要点
MVC是复合模式,结合观察者模式策略模式组合模式
模型使用观察者模式,以便观察者更新,同事保持两者之间的解耦。
控制器是视图的策略,视图可以使用不同的控制器实现,得到不同的行为。
视图使用组合模式实现用户界面,用户界面通常使用嵌套的组件,像面板、框架和按钮。
这些模式携手合作,把MVC的三层解耦,这样额可以保持设计干净,又有弹性。
适配器模式用来将新的模型是配成已有的视图和控制器。
Model2是MVC在Web上的应用。
在Model2中,控制器实现成Servlet,而JSP/HTML实现视图。
迎接一个充满设计模式的崭新世界。

Chapter 13:与设计模式相处--真实世界中的模式

模式是在某种情境(context)下,针对某问题的某种解决方案。
情境就是应用某个模式的情况。这应该是会不断出现的情况。
问题就是你想在某个情境下达到的目的,但也可以是某情境下的约束。
解决方案就是你追求的,一个通用的设计,用来解决约束,达到目的。
如果你发现自己处于某个情境下,面对着所欲达到的目标被一群约束影响着的问题,然而,你能够应用某个设计,克服这些约束并达到该目标,将你领向某个解决方案。

反模式告诉你如何采用一个不好的解决方案解决一个问题。

要点
让设计模式自然而然地出现在你的设计中,而不是为了使用而使用。
让设计模式并非僵化的教条;你可以依据自己的需要采用或调整。
总是使用满足需要的最简单解决方案,不管它用不用模式。
学习设计模式的类目,可以帮你自己熟悉这些模式以及它们之间的关系。
模式的分类或类目是将模式分成不同的族群,如果这么做对你有帮助,就采用吧!
你必须相当专注才能够成为一个模式的作家;这需要时间也需要耐心,同事还必须乐意做大量的精化工作。
请牢记:你所遇到大多数的模式都是现有模式的变体,而非新的模式。
模式能够为你带来的最大好处之一是,让你的团队拥有共享词汇。
任何社群都有自己的行话,模式社群也是如此。别让这些行话绊着,在读完这本书之后,你已经能够应用大部分的行话了。

剩下的模式

桥接模式 Bridge Pattern
不只改变你的实现,也改变你的抽象。
生成器 Builder Pattern
使用生成器模式封装一个产品的构造过程,并允许按步骤构造。
责任链 Chain of Responsibility Pattern
当你想要让一个以上的对象有机会能够处理某个请求的时候,就使用责任链模式。
蝇量 Flyweight Pattern
如想让某个类的一个实例用来提供许多虚拟实例,就使用蝇量模式。
解释器 Interpreter Pattern
使用解释器模式为语言创建解释器。
中介者 Mediator Pattern
使用中介者模式来几种相关对象之间复杂的沟通和控制方式。
备忘录 Memento Pattern
当你需要让对象返回之前的状态时,就使用备忘录模式。
原型 Prototype Pattern
当创建给定类的实例的过程很昂贵或很复杂时,就使用原型模式。
访问者 Visitor Pattern
当你想要为一个对象的组合增加新的能力,切封装并不重要时,就使用访问者模式。

0 comments: