Dec 17, 2008

《Head First 设计模式》1-4章

《Head First》在去年初着实火了一把,我是年初买的这本书,然后回学校做毕业设计的时候看了几章,假期实习的时候看完了剩下的几章。那会烦心的事特别多,也没有读书的心情,看《重构》的时候发现很多设计模式方面的东西已经忘个精光,现在重读并做些笔记。部分内容来自CSDN下载的一份EXCEL格式的笔记,图片都来自GoF的经典。设计模式出来十年了,我却是在本科毕业以后才读的这本书,也许不用考研,我会早些接触模式,对我的编程实践应该会有很多的帮助。

学习的方法:

慢一点,思考得越多,需要记的就越少
勤做练习,自己记笔记
睡觉前不要看有难度的东西
多喝水
大声说出来
听听你的大脑怎么说
要有点感觉
设计一些东西

chapter1:设计模式入门
我们已经搬到对象村,刚刚开始着手设计模式……这里每个人都在使用设计模式。很快我们就会通过设计模式跻身上流社会。
把模式装进脑子里,然后在设计和已有的运用中,寻找何处可以使用。

CHANGE
设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
把会变化的部分取出并封装起来,好让其他部分不会受到影响。
结果如何?代码变化引起的不经意后果变少,系统变得更有弹性。

设计原则:
针对接口编程,而不是针对实现编程。
从现在开始,鸭子的行为将被放在分开的类中,此类专门提供某行为接口的实现。
这样,鸭子类就不再需要知道行为的实现细节。
"针对接口编程真正的意思是""针对超类型supertype编程"""
执行时根据实际情况执行真正的行为

设计原则:多用组合,少用继承。
has a maybe better than is a.

策略模式:
定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。


良好的OO设计必须具备可复用、可扩展、可维护三个特性。
可维护的OO系统:随时想到系统以后可能需要的变化以及应付变化的原则。

模式不是被发明,而是被发现。

chapter 2:观察者模式:让你的对象知悉现状

喂,Jerry,我正在通知大家,模式小组会议改到周六晚上,这次讨论的是观察者模式,这个模式最棒了!超级棒!你一定要来呀,Jerry。

观察者模式: 定义了对象之间的一对多依赖,这样以来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

设计原则
:为了交互对象之间的松耦合设计而努力。
松耦合:依然可以交互,但不太清楚彼此的细节。


Subject:主题 Observer:观察者
要点
观察者模式定义了对象之间的一对多关系。
主题,也就是可观察者用一个共同的接口来更新观察者。
观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者接口
使用此模式时,你可从被观察者处推push或拉pull数据,然而,推的方式被认为更正确
多个观察者时,不可以依赖特定的通知次序。

Java有多种观察者模式的实现,包括了通用java.util.Observable
要注意java.util.Observable实现上所带来的一些问题。
如果有必要的话,可以实现自己的Observable,这并不难,不要害怕。
Swing大量使用了观察者模式,许多GUI框架也是如此。
此模式也被应用在许多地方。例如:JavaBeans、RMI。

chapter 3: 装饰者模式
我曾经以为男子汉应该用继承处理一切。后来我领教到运行时扩展,远比编译时期的继承威力大。看看我现在光彩的样子。

装饰模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
可以在不修改底层代码的情况下,给代码赋予新的职责。


设计原则
:类应该对扩展开发,对修改关闭。

要点1
装饰者和被装饰者对象有相同的超类型
你可以用一个或多个装饰者包装一个对象。
既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装)的场合,可以用装饰过的对象代替它。
装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。

要点2
继承属于扩展形式之一,但不见得是达到弹性设计的最佳方案。
在我们的设计中,应该允许行为可以被扩展,而无须修改现有的代码。
组合和委托可用于在运行时动态地加上新的行为。
除了继承,装饰者模式也可以让我们扩展行为。
装饰者模式意味着一群装饰者类,这些类用来包装具体组件。
装饰者类反映出被装饰的组件类型(他们具有相同的类型,都经过接口或继承实现)
装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。
你可以用无数个装饰者包装一个组件。
装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。
装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂

只有针对抽象组件类型编程时,才不会因为装饰者而受到影响。
通常有工厂或生成器之类的模式创建。

Java String
FilterInputStream: 一个抽象装饰者。
chapter 4:工厂模式--烘烤OO的精华
认识工厂方法模式
所有工厂模式都是用来封装对象的创建
工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。

组成元素
创建者Creator类
它定义了一个抽象的工厂方法,让子类实现此方法制造产品。
创建者通常会包含依赖于抽象产品的代码,而这些抽象产品由子类制造。创建者不需要真的知道在制造哪种具体产品。
产品类:工厂生产产品。对PizzaStore来说,产品就是Pizza。

另一个观点:平行的类层级
为什么产品类和创建者类是平行的?都是抽象类,且都有许多具体的子类,每个子类都有自己特定的实现。
NYPizzaStore所封装的是关于如何制作纽约风味的比萨。工厂方法就是封装这种知识的关键所在。

工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

要点:

Creator是一个类,它实现了所有操作产品的方法,但不实现工厂方法。
Creator所有的子类都必须实现这个抽象的factoryMethod方法。
所有的产品必须实现一个共同的接口,这样一来,使用这些产品的类,就可以引用这个接口,而不是具体类。
ConcreteCreator实现了factoryMethod,以实际制造出产品。
ConcreteCreator负责创建一个或多个具体产品,只有ConcreteCreator类知道如何创建这些产品。
concrete具体的adj

设计原则:要依赖抽象,不要依赖具体类。
依赖倒置原则,不能让高层组件依赖低层组件,而且不管高层或低层组件,2者都应该依赖于抽象。
所谓高层组件,是由其他低层组件定义其行为的类。
例如,PizzaStore是个高层组件,因为它的行为是由比萨定义的。
依赖倒置原则,究竟倒置在哪里?
避免OO设计中违反依赖倒置原则
1 变量不可以持有具体类的引用。
如果使用new,就会持有具体类的引用。你可以改用工厂来避开这样的做法。
2 不要让类派生自具体类。
如果派生自具体类,你就会依赖具体类,请派生自一个抽象(接口或抽象类)
3 不要覆盖基类中已实现的方法。
如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被集成的抽象。基类中已实现的方法,应该由所有的子类共享。

抽象工厂模式
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
比较工厂方法和抽象工厂。。。
要点1:
所有的工厂都是用来封装对象的创建。
简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。
工厂方法使用集成:把对象的创建委托给子类,子类实现工厂方法来创建对象。
抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。
所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。
工厂方法允许类将实例化延迟到子类进行。
抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。
依赖倒置原则,知道我们避免依赖具体类型,而要尽量依赖抽象。
工厂是很有为例的技巧,帮助我们针对抽象编程,而不要针对具体类编程。

0 comments: