第一章1.什么是模式?模式是在物体或事件上,产生的一种规律变化与自我重复的样式与过程。在模式之中,某些固定的元素不断以可预测的方式周期性重现。2.什么是设计模式?广义讲,软件设计模式是可解决一类软件问题并能重复使用的软件设计方案;狭义讲,设计模式是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。是在类和对象的层次描述的可重复使用的软件设计问题的解决方案;设计模式是在一个上下文中,对一个问题的解决方案,及其能够达到的效果。3.设计模式四要素名称、上下文与问题、解决方案、效果模式名称(PatternName)问题(Problem):描述应该在何时使用模式。解释了设计问题和问题存在的前因后果,可能还描述模式必须满足的先决条件;解决方案(Solution):描述了设计的组成成分、相互关系及各自的职责和协作方式。模式就像一个模板,可应用于多种场合,所以解决方案并不描述一个具体的设计或实现,而是提供设计问题的抽象描述和解决问题所采用的元素组合(类和对象);效果(consequences):描述模式的应用效果及使用模式应权衡的问题4.设计模式分类23种设计模式:创建型:5种;结构型:7种;行为型:11种5.面向对象的四个基本方法:抽象(Abstraction)封装(Encapsulation)多态(Polymorphism)继承(Inheritance)6.面向对象的设计原则开闭原则(OCP):对于扩展是开放的(Openforextension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。对于修改是关闭的(Closedformodification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。单一职责原则(SRP):定义:就一个类而言,应该仅有一个引起它变化的原因;每一个引起类变化的原因就是一个职责,当类具有多职责时,应把多余职责分离出去,分别创建一些类来完成每一个职责;每一个职责都是一个变化的轴线,当需求变化时会反映为类的职责的变化;里氏替换原则(LSP):定义:所有引用基类的地方必须能透明地使用其子类的对象里氏替换原则是继承复用的基石,只有当派生类可以替换掉其基类,而软件功能不受影响时,基类才能真正被复用,派生类也才能够在基类的基础上增加新的行为LSP本质:在同一个继承体系中的对象应该有共同的行为特征依赖倒置原则(DIP):定义:高层模块不应依赖低层模块,二者都应该依赖于抽象高层模块只应该包含重要的业务模型和策略选择,低层模块则是不同业务和策略的实现;高层抽象不依赖高层和低层模块的具体实现,最多只依赖于低层的抽象;低层抽象和实现也只依赖于高层抽象;接口隔离原则(ISP):定义:类间的依赖关系应该建立在最小的接口上。多个和客户相关的接口要好于一个通用接口;如果一个类有几个使用者,与其让这个类载入所有使用者需要使用的所有方法,还不如为每个使用者创建一个特定接口,并让该类分别实现这些接口;接口隔离原则包含了四层重要含义:接口尽量要小;接口要高内聚;定制服务;接口设计是有限度的迪米特原则(LoD):定义:一个软件实体应当尽可能少的与其他实体发生相互作用。每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。迪米特法则也叫做做最少知识原则(LeastKnowledgePrinciple,简称LKP)迪米特法则的初衷在于降低类之间的耦合。第二章(请重点复习本章)1.策略模式策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。2.标准类图3.设计原则“开-闭”原则(OCP)单一职责原则(SRP)里氏替换原则(LSP)接口隔离原则(ISP)4.设计实例及代码参考书22页效果分析优点:算法和使用算法的对象相互分离,客户程序可以在运行时动态选择算法,代码复用性好,便于修改和维护;ContextInterface()ContextAlgorithmInterface()StrategyAlgorithmInterface()ConcreteStrategyAAlgorithmInterface()ConcreteStrategyBAlgorithmInterface()ConcreteStrategyCstrategy用组合替代继承,效果更好。若从Context直接生成子类,也可以实现对象的多种算法,但继承使子类和父类紧密耦合,使Context类难以理解、难以维护和难以扩展。策略模式采用组合方式,使Context和Strategy之间的依赖很小,更利于代码复用;消除了冗长的条件语句序列,将不同的算法硬编码进一个类中,选择不同的算法必然要使用冗长的条件语句序列,采用策略模式将算法封装在一个个独立的Strategy类中消除了这些条件语句;算法的动态选择,Strategy模式可以提供相同行为的不同实现,客户可以根据不同的上下文从不同的策略中选择算法;缺点:客户必须了解不同的Strategy,一个客户要选择一个合适的Strategy就必须知道这些Strategy到底有什么不同;Strategy和Context之间的通信开销加大,根据算法的需要,Context必须向每个不同的具体Strategy类实例传递不同的参数,因此Strategy接口就要传递所有这些不同参数的集合,导致Context会创建和传递一些永远用不到的参数;增加了类和对象数目,因为各种算法被抽取出来单独成类,导致了对象数目增加,这种情况在算法较多时更加严重;5.要点良好的OO设计必须具备可复用、可扩充、可维护三个特性我们常把系统中会变化的部分抽象出来封装第三章1.观察者模式观察者模式定义了对象之间一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会接到通知并自动更新。2.标准类图3.设计原则为了交互对象之间的松耦合设计而努力。4.效果分析优点:Subject和Observer之间是松偶合的,可以各自独立改变;Subject在发送广播通知时,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知;高内聚、低偶合;缺陷:松偶合导致代码关系不明显,有时可能难以理解;如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题;6.要点观察者模式定义了对象之间一对多的关系主题用一个共同的接口来更新观察者观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者的接口使用此模式时,可以从观察者处推或拉数据(推的方式被认为更正确)有多个观察者时,不可以依赖特定的通知次序。第四章(请重点复习本章)1.装饰者模式第五章(请重点复习本章)1.工厂模式2.抽象工厂模式第六章1.单件模式单件模式确保一个类只有一个实例,并提供一个全局访问点。2.标准类图3.单件模式处理多线程的方法a)同步-staticsynchronized这是保证可行的最直接方法。不考虑性能b)急切实例化一定需要一个实例的时候可以采用该种方法c)双重检查加锁publicstaticSingletongetInstance(){if(uniqueInstance==null){synchronized(Singleton.class){if(uniquelnstance==null){uniquelnstance=newSingleton();}}}}考虑性能的时候并且采用Java5以上的版本时使用该方法。4.效果分析优点对唯一实例的受控访问:因为Singleton类封装唯一实例,所以它可以严格的控制客户怎样以及何时访问它;缩小名空间:Singleton模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染命名空间;允许对操作和表示的精化:Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。可以用所需要的类的实例在运行时刻配置应用;缺陷不是所有的类实例化都需要实现单例;不便使用继承;5.要点单件模式确保程序中的一个类最多只有一个实例。单件模式提供访问这个实例的全局点。在Java中实现单件模式需要私有的构造器、一个静态方法和一个静态变量。如果使用多个类加载器,可能导致单件失效而产生多个实例。如果采用Java2第5版以下的版本,双重检查加锁实现会失效。JVM1.2及以下版本必须建立单件注册表,否则会失效。7.DumpQuestion1)难道不能创建一个类,把所有的方法和变量都定义为静态,把类直接当做一个单件?如果类是自己自足的,而且不依赖于复杂的初始化,那么可以这样做。但是静态初始化的控制权在Java手上,这么做有可能导致混乱,特别是当有许多类牵涉其中的时候。这样做常常会造成一些微妙的、不容易发现的和初始化的次序有关的Bug。除非你有绝对的必要使用类的单件,否则还是建议使用对象的单件,比较保险。2)把单件类当做超类,设计出子类,究竟可不可以继承单件类?继承单件会遇到一个问题,就是构造器是私有的。不能使用私有构造器来扩展类。因此,必须把单件的构造器改成公开的或受保护的。但是这样一来就不算是真正的单件了,因为别的类也可以实例化它。如果这的把构造器的权限改变了,想要让子类能够顺利工作,基类必须实现注册表功能。3)在那些方面全局变量比单件模式差?a)全局变量需要急切实例化,这个对象有可能非常消耗资源,而程序在一次执行中有可能没有用到它,这就造成了资源浪费。b)全局变量可以提供全局访问。但是不能保证只有一个实例。c)全局变量会变相鼓励开发人员,用许多全局变量指向许多小对象来造成命名空间的污染。第七章(请重点复习本章)1.命令模式第八章1.适配器模式适配器模式将一个类的接口转换成客户期望的另一个接口。适配器让原本不兼容的类可以合作无间。2.标准类图3.类适配器4.对象适配器5.设计原则:最少知识原则。6.要点当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观。适配器改变接口以符合客户的期望。外观将客户从一个复杂的子系统中解耦。适配器模式有两种形式:对象适配器和类适配器,类适配器在使用过程中需要用到多重继承可以为一个子系统实现一个以上的外观。适配器将一个对象封装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;而外观将一群对象“包装起来”以简化其接口。8.适配器模式效果分析优点:方便设计者自由定义接口,不用担心匹配问题;缺点:属于静态结构,由于只能单继承,所以不适用于多种不同的源适配到同一个目标;9.DumbQuestiona)如果外观封装了子系统的类,那么需要低层功能的客户如何接触这些类?外观没有封装子系统的类,外观只是提供简化的接口。所以用户觉得没有必要,可以直接使用子系统的类。外观模式一个很好的特征:提供简化接口的同时,依然将系统完整的功能暴露出来,以供需要的人使用。b)外观会新增功能吗,或者它只是将每一个请求转由子系统执行?外观可以增加新的功能,以便使用子系统更加方便。c)每一个系统只能有一个外观吗?不,可以为一个子系统创建多个外观。d)除了能够提供一个比较简单的接口之外,外观模式还有其他优点吗?外观模式允许将客户实现从任何子系统中解耦。e)我可不可以这样说,适配器模式和外观模式之间的差异在于:适配器包装一个类,而外观可以代表许多类?外观和适配器均可以包装许多类,外观的意图是简化接口,而适配器的意图是将接口转化成不同的接口。10.外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。10.外观模式的效果优点对客户端屏蔽子系统组件,减少客户端使用对象数目;实现了子系统与客户之间松耦合的关系,使得子系统组件的变化不会影响到客户;不限制客户应用子系统类;第九章1.模板方法模式