Chapter1 简单工厂模式
聚合表示一种弱的“拥有”关系,体现的是A对象包含B对象,但B对象不是A对象的一部分。
合成表示一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。
Chapter2 策略模式
策略模式(Strategy):定义了算法家族,分别封装起来,让它们之间可以互相转换,此模式让算法的变化,不会影响到使用算法的客户。
- 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
- 策略模式的Strategy类层次为Context定义了一系列的可重用的算法或行为,继承有助于析取出这些算法中的公共功能。
- 策略模式就是用来封装算法的,在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。
chapter3 单一原则
单一原则(SRP):就一个类而言,应该仅有一个引起它变化的原因。
- 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。
- 软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。
- 如果能想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。
chapter4 开放封闭原则
开放-封闭原则(OCP):软件实体(类,模块,函数等等)应该可以被扩展,但是不能被修改。
- 对于扩展开发,对于修改封闭。
- 面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。
- 无论模块是多么的“封闭”,都会存在一些无法对之封闭的变化。既然不可能完全封闭,设计人员必须对于其设计的模块应该对哪种变化封装做出选择。他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化。
- 在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发生的同类变化。
- 开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象。
- 我们希望的是在开发工作展开不久就知道可能发生的变化。查明可能发生的变化所等待的时间越长,要创建正确的抽象就越困难。
chapter5 依赖倒转原则
依赖倒转原则:
- A.高层模块不应该依赖低层模块。两个都应该依赖抽象。
- B.抽象不应该依赖细节。细节应该依赖抽象。(针对接口编程,不要对实现编程)
里氏代换原则(LSP):子类型必须能够替换掉它们的父类型。
- 只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。
- 由于子类型的可替换性才使得使用父类类型的模块在无需修改的情况下就可以扩展。
- 依赖倒转其实可以说是面向对象设计的标志,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之就是过程化的设计。
chapter6 装饰模式
装饰模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
- 当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,在类中加入新的字段,新的方法和新的逻辑,从而增加了主类的的复杂程度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的的特殊行为的需要。装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊的行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
- 有效得把类的核心职责和装饰功能区分开来。而且可以去除相关类中的重复的装饰逻辑。
chapter7 代理模式
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。
- 远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。
- 虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真是对象。
- 安全代理,用来控制真是对象访问时的权限。
- 智能指引,是指当调用真实的对象时,代理处理另外一些事情。
chapter8 工厂方法模式
工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了具体产品的依赖。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单的内部逻辑判断移到了客户端代码来进行。
chapter9 原型模式
原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式其实就是一个从对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
chapter10 模板方法模式
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
当我们要为完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。
模板方法模式是通过把不变的行为搬移到超类,去除子类中的重复代码来体现它的优势。
chapter11 迪米特法则
迪米特法则(LoD),如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
在类的结构设计上,每一个类都应当尽量降低成员的访问权限,其根本思想是强调了类之间的松耦合。
类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。
chapter12 外观模式
外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式完美地体现了依赖倒转原则和迪米特法则的思想。
- 在设计初期,应该要有意识的将不同的两层分离,层与层之间建立外观Facade;
- 在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少它们之间的依赖;
- 在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,就可以为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。
chapter13 建造者模式
建造者模式(Builder),将一个复杂对象构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。
建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
chapter14 观察者模式
观察则模式又叫做发布-订阅(Publish/Subscribe)模式,定义了一种一对多的依赖关系,让多个观察对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不方便。
当一个对象的改变需要同时改变其他对象时,并且不知道它具体有多少对象有待改变时,应该考虑使用观察者模式。
观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是以来于具体,从而使得各自的变化都不会影响另一边的变化。