- 浏览: 30854 次
- 性别:
- 来自: 西安
文章分类
最新评论
《易学 设计模式》 - 书摘精要
(前言)
设计模式和具体的语言没有关系,学习设计模式最重要的目的就是要建立面向对象的思想,尽可能地面向接口编程、低耦合、高内聚,使设计的程序可复用;
在掌握面向对象的思想方式后,再回过头来看设计模式,就会有更深刻的理解;
学习设计模式,一定要勤学多练;
(P4)
对象的创建会消耗掉系统的很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题;
在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了开发人员关注的焦点,因为如何设计对象的结构、继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性等。
对象结构的设计很容易体现出设计人员水平的高低;
在对象的结构和对象的创建问题都解决了之后,就剩下对象的行为问题了,如果对象的行为设计的好,那么对象的行为就会更清晰,它们之间的协作效率就会提高;
(P5)
设计模式并不只是一种方法和技术,它更是一种思想、一个方法论。
它和具体的语言没有关系,学习设计模式最主要的目的就是要建立面向对象的思想,尽可能地面向接口编程、低耦合、高内聚,使你设计的程序尽可能地复用;
(P23)
简单工厂模式又叫静态工厂方法模式,是所有工厂模式中最简单的一个;
在程序设计中,离不开对象的创建,对象创建效率的高低对系统资源的占用影响较大,因此需要对此进行详细研究,最好的办法就是将对象的创建和使用分开;
简单工厂模式只适用于要创建的具体对象比较少或简单的情况,而创建比较复杂的对象时,简单工厂模式不是一个很好的选择;
(P31)
工厂方法模式相对于简单工厂模式来说,就是把一个单一的工厂类,分成了多个具体的小工厂,并抽象出了一个工厂类,这个工厂类只负责定义创建的方式,创建的具体内容由继承它的小工厂类实现;
(P35)
【工厂方法模式】
[定义] 工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由实现抽象工厂的具体工厂类来完成;
[原理] 工厂方法模式主要由4部分组成:抽象工厂类、实现抽象工厂类的具体工厂类、抽象类和实现抽象类的具体类;
[使用时机] 当在代码中使用new来创建对象时,就可以考虑使用工厂方法模式。一般来说,工厂方法模式会应用在比较复杂的对象创建上;
[优点]
在工厂方法模式中,客户端不再负责对象的创建,而是把这个责任交给了具体的工厂类,客户端只负责对象的调用,从而明确了各个类的职责;
如果有新的产品加进来,只需要新增加一个具体的创建产品工厂类和具体的产品类就可以了,不会影响到原来已有的其他代码,代码量也不会变大,后期维护更加容易,增强了系统的可扩展性;
[缺点] 使用该模式需要额外地编写代码,增加了工作量;
(P39)
每一种设计模式都是为了解决一类问题而产生的,如果说工厂方法模式是针对一个产品结构而言的话,那么抽象工厂模式就是针对于多个产品结构而言的,它主要用于帮助客户一次创建多个不同产品对象;
(P40)
工厂方法模式是针对于一个产品系列的,而抽象工厂模式是针对于多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类;
(P45)
【抽象工厂模式】
[定义] 如果客户端需要创建一些产品结构,而这些产品结构又分别属于不同的产品类别,则可以使用抽象工厂模式,抽象工厂模式中抽象工厂类负责定义创建对象的接口,这一系列对象的创建工作由实现抽象工厂的具体工厂类来具体完成;
[原理] 抽象工厂模式主要由4部分组成:抽象工厂类、实现抽象工厂类的具体工厂类、抽象类和实现抽象类的具体类;
[使用时机] 当系统需要创建一系列相互关联的对象时,就需要使用抽象工厂模式;
[优点]
在抽象工厂模式中,客户端不再负责对象的创建,而是把这个责任交给了具体的工厂类,客户端只负责对对象的调用,从而明确了各个类的职责;
当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单,而且,如果要更换这一系列的产品,只需要更换一个工厂类即可;
[缺点] 如果有新的产品加进来,则需要修改抽象工厂类的设计,并同时修改实现这个抽象工厂类的具体工厂类,需要额外编写代码,增加了工作量;
(P52)
在简单工厂模式中,一个工厂类负责所有产品对象的创建,这个工厂类的职责大大增加。由于简单工厂模式使用静态方法来创建对象,这就导致静态方法无法被继承;
在工厂方法模式中,一个具体的工厂类负责创建一个单独的产品,如果有两个不同的产品要创建,就需要两个不同的工厂类,即使这两个产品有某些必要的联系,也还是需要两个不同的工厂类;
在抽象工厂模式中,一个具体的工厂类负责创建一系列相互关联的产品,当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单;如果要更换这一系列的产品,则只需要更换一个工厂类即可;
(P57)
【创建者模式】
[定义] 创建者模式就是将一个复杂对象的构建与它的表示相分离,使得同样的构建过程可以创建不同的表示,而且客户端不知道对象的构建细节;
[原理] 创建者模式主要由5个部分组成:组装类、抽象创建者类、实现抽象创建者类的具体创建者类、抽象产品类和实现抽象产品类的具体产品类;
[使用时机] 当系统需要创建一个复杂的对象,而且这个复杂的对象组装起来比较麻烦时,就可以使用创建者模式;
[优点] 在创建者模式中,客户端不再负责对象的创建和组装,而是把这个创建的责任交给具体的创建者类,把组装的责任交给组装类,客户端只负责对象的调用,从而明确了各个类的职责;
[缺点] 虽然利用创建者模式可以创建出不同类型的产品,但如果产品之间的差异非常大,则需要编写多个创建者类才能实现,这时如果结合工厂模式更好;
(P64)
【原型模式】
[定义] 原型模式就是通过一个原型对象来表明要创建的对象类型,然后用复制这个原型对象的方法来创建更多同类型对象;
[原理] 原型模式主要由2部分组成:抽象原型和具体原型类;
[使用时机] 当系统需要创建的对象是动态加载的,而且产品具有一定层次时,需要使用原型模式;
[优点] 在原型模式中,可以动态地添加产品类,而且对整体结构没有影响;
[缺点] 由于原型模式需要给每个类都配备一个克隆的方法,这就需要在设计类时通盘考虑,因为在已有类的基础上来添加clone操作是比较困难的;而且原型模式在实现深层次的复制时,需要编写一定量的代码;
(P73)
【单例模式】
[定义] 单例模式就是确保一个类只有一个实例,并且该实例必须自动创建,并向整个系统提供该实例;
[原理] 单例模式可以分为饿汉式单例模式和懒汉式单例模式两种:饿汉式单例模式在类初始化时就已经创建了自身的对象,而懒汉式单例模式则是在需要使用的时候才创建自身的对象;
[使用时机] 当系统要求一个类只有一个实例时,就需要使用单例模式;
[优点] 在单例模式中,客户调用类的实例时,只能调用一个公共的接口,这就为整个开发团队提供了一个共享的概念;
[缺点] 实现单例模式的类在实例化后,不能被别的类继承;在分布式系统中,当系统中的单例类被复制运行在多个虚拟机下时,在每一个虚拟机下都会创建一个实例对象,此时如果想知道具体哪个虚拟机下运行着哪个单例对象时很困难的,而且单例类很难实现序列化;
(P79)
在所有的设计模式中,最简单的就数外观模式了。外观模式又叫门面模式,顾名思义,就是对一个系统进行包装,该系统对外的接口统一由外观类进行提供;
【外观模式】
[定义] 外观模式就是为子系统对外提供的一组接口提供一个统一的界面,使得其他系统对该系统的访问都通过这个统一的界面来完成;
[原理] 外观模式主要由3部分组成:抽象外观类、实现抽象外观类的具体外观类和其他子系统;
[使用时机] 当一个复杂的系统需要对外提供接口时,就需要将对外提供的接口统一封装在一个外观类里,供外系统使用;
[优点] 外观模式通过提供一个统一的对外接口,避免了外部系统和子系统之间的直接联系,从而降低了系统间的依赖和复杂度;
[缺点] 限制了外部系统对子系统调用的灵活性,只能按照外观类中提供的方式对子系统进行调用;
(P107)
【适配器模式】
[定义] 适配器模式就是将一个系统的接口转换成另外一种形式,从而使原来不能直接调用的接口变得可以调用;
[原理] 适配器模式主要由3部分组成:目标类、源类和适配器类;
适配器类分为对象适配器和类适配器:对象适配器即实现目标类的接口,依赖适配者类;类适配器即直接继承适配者类,并实现目标类的接口;
[使用时机] 当系统需要使用一个外部接口,而这个外部接口不符合系统需要的时候,就需要使用适配器模式;
[优点] 使用适配器模式,可以将一个系统的接口和本来不相容的另一个系统的类联系起来,从而使得这两个类能够在一起工作,强调了对接口的转换;
[缺点] 对于类适配器来说,不能适配一个类以及它的子类;对于对象适配器来说,重新定义被适配的类的行为比较困难;
(P122)
【代理模式】
[定义] 代理模式就是给一个对象提供一个代理对象,由这个代理对象控制对原对象的引用,使代理类在客户端和原对象之间起到一个中介的作用;
[原理] 代理模式主要由3部分组成:抽象目标类、具体目标类和代理类;
[使用时机] 当系统需要对某个对象进行额外的控制时,就需要使用代理模式;
[优点] 使用代理模式,能够在不改变原来代码功能的基础上对某一对象进行额外的控制,从而更好地体现了面向对象中单一职责的思想;
[缺点] 对于静态代理来说,一个接口只服务于一种类型,如果要代理的方法很多,则要为每个方法定义一个接口;
(P153)
【装饰模式】
[定义] 装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例委托给装饰类。装饰模式是继承关系的一个替代方案;
[原理] 装饰模式主要由4部分组成:抽象的被装饰类、具体的被装饰类、抽象的装饰类和具体的装饰类;
[使用时机] 当系统需要扩展一个类的功能,或者客户端需要动态的给一个对象添加功能,并且此时如果使用继承会很复杂时,就需要使用装饰模式;
[优点] 使用装饰模式,能够提供比使用继承关系更灵活的扩展对象的功能,它可以动态地增加对象的功能,并且可以随意地组合这些功能;
[缺点] 正因为可以随意地组合这些功能,有时候就可能会出现一些不合理的逻辑。使用装饰模式进行系统设计往往会产生许多看上去类似的小对象,这些对象的类或是它们的属性值是一样的,仅仅在它们相互连接的方式上有所不同;
(P171)
桥模式可能是所有设计模式中最难理解的一个模式了;
桥模式中的抽象指的是抽象类及派生类,实现指的是这些抽象类及派生类实现自己的方式;
【桥模式】
[定义] 桥模式就是将抽象与其实现解耦,使它们可以分别独立地变化。桥模式也是继承关系的一个替代方案;
[原理] 桥模式主要由4部分组成:抽象类、抽象类的继承类、实现类和实现类的继承类;
[使用时机] 当系统需要在它的抽象和实现之间增加更多的灵活性,或者一个对象有多于一个的抽象和实现时,就需要使用桥模式;
[优点] 使用桥模式,能够提供比使用继承关系更灵活的功能。它可以使抽象和实现分离开,降低了耦合关系。当有新的抽象或实现方式时,只需要继承一个抽象和继承一个实现即可;
[缺点] 如果要重新抽象出另外一个类型,则需要修改抽象;
(P196)
适配器、代理、装饰和桥模式都是为了解决对象之间的依赖关系,降低对象间的耦合度,给设计增加更多的灵活性;
(P201)
【组合模式】
[定义] 组合模式就是把部分和整体的关系用树形结构来表示,从而使客户端能够把一个一个的部分对象和由它们组合起来的整体对象采用同样的方式来看待。它也是继承的一个替代方案;
[原理] 组合模式主要由3部分组成:抽象类、叶子类和父类;
[使用时机] 当系统要描述的对象是树形结构,并且要在客户端忽略掉子对象和父对象的区别时,就需要使用组合模式;
[优点] 使用组合模式,能够提供比使用继承关系更灵活的功能,并且可以灵活地组合子对象和父对象之间的关系,从而使客户端的调用简单,客户端可以一致地使用组合结构或其中单个对象,用户就不必关心自己处理的是单个对象还是整个组合结构,这简化了客户端代码;
[缺点] 虽然组合模式使得向集合添加新类型的组件变得容易,只要这些组件提供一个相似的编程接口即可,但这也是它的缺点,因为这种做法很难限制某个类;
(P220)
【享元模式】
[定义] 享元模式就是把部分和整体的关系用树形结构来表示,从而使客户端能够把一个一个的部分对象和由它们组合起来的整体对象采用同样的方式来看待。它也是继承的一个替代方案;
[原理] 享元模式主要由3部分组成:享元类、具体的享元类和享元工厂类;
[使用时机] 当系统需要使用大量重复的对象,而且这些对象要消耗很大的内存时,就需要使用享元模式;
[优点] 使用享元模式,可以为系统节省大量的空间;
[缺点] 但是在享元工厂里可以看到,需要维护所有的享元对象,如果要维护的享元很多,在查找的时候要消耗大量的时间。因此,享元模式是典型的以时间换空间;
(P227)
结构型模式主要解决了对象的组成以及对象之间的依赖关系;
(P234)
【模板方法模式】
[定义] 模板方法模式就是定义一个算法执行的骨架,而将具体的算法延迟到子类中来实现;
[原理] 模板方法模式主要由2部分组成:抽象的骨架类和具体实现类;
[使用时机] 当系统中算法的骨架是固定的,而算法的实现可能有很多种的时候,就需要使用模板方法模式;
[优点] 使用模板方法模式,在定义算法的骨架的同时,可以很灵活地实现具体的算法,满足用户灵活多变的需求;
[缺点] 虽然使用模板方法模式可以很自由地实现具体的算法,但如果算法的骨架有改变的话,则需要修改抽象类;
(P270)
【观察者模式】
[定义] 观察者模式就是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新;
[原理] 观察者模式主要由4部分组成:抽象目标类、具体目标类、抽象观察者类和具体观察者类;
[使用时机] 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有所改变,或者说当一个对象必须通知其他对象,而它又不能假定其他对象是谁的时候,就需要使用观察者模式;
[优点] 观察者模式在被观察者和观察者之间建立一个抽象的耦合,每一个具体观察者都符合一个抽象观察者的接口,被观察者并不知道任何一个具体观察者,它只知道它们都有一个共同的接口,从而使得被观察者和观察者耦合度降低,而且观察者模式支持广播通信。被观察者会向所有的注册过的观察者发出通知;
[缺点] 如果一个被观察者对象有很多观察者,通知所有的观察者会耗费很多时间;
(P286)
【状态模式】
[定义] 状态模式就是根据对象的状态不同,将有不同的行为;
[原理] 状态模式主要由3部分组成:抽象状态类、具体状态类和上下文类;
[使用时机] 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为,或者一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态时,就需要使用状态模式;
[优点] 状态模式使代码中复杂而冗长的逻辑判断语句问题得到了解决,而且具体状态角色将具体状态和它对应的行为封装了起来,这使得增加一种新的状态变得十分简单;
[缺点] 使用状态模式时,每个状态对应一个具体的状态类。使结构分散,逻辑不太清晰,阅读代码时比较困难;
(P299)
【策略模式】
[定义] 策略模式就是定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化;
[原理] 策略模式主要由3部分组成:抽象策略类、具体策略类和上下文场景类;
[使用时机] 当系统需要能够在几种算法中快速地切换,或系统中有一些类,它们仅行为不同时,或系统中存在多重条件选择语句时,就可以考虑采用策略模式;
[优点] 使用策略模式,可以替换继承关系的办法,也可以避免使用多重条件转移语句;
[缺点] 使用策略模式时客户端必须知道所有的策略类,并自行决定使用哪一个策略类,如果算法比较多,则会造成很多的策略类;
(P305)
【职责链模式】
[定义] 职责链模式就是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止;
[原理] 职责链模式主要由2部分组成:抽象处理类、具体处理类和上下文场景类;
[使用时机] 当有多个对象处理请求,而且需要动态指定处理者的时候,就可以考虑使用职责链模式;
[优点] 使用职责链模式可以降低类之间的耦合度。使得处理类仅需要保持一个指向其后继者的引用,也使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需知道该请求会被正确地处理,接收者和发送者都没有对方的明确的信息,这种处理方法增强了给对象指派职责的灵活性;
[缺点] 因为对象不知道是其他哪一个对象处理其请求的,所以职责链模式不保证对象被接收,从而使得该请求可能一直到链接的末端都得不到处理;
(P316)
【命令模式】
[定义] 命令模式就是把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能;
[原理] 命令模式主要由4部分组成:抽象命令类、具体命令类、调用者和接收者;
[使用时机] 当需要先将一个函数登记上,然后在以后调用此函数时,就需要使用命令模式,其实这就是回调函数;
[优点] 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开,从而使新的命令可以很容易地被加入到系统里,可以很方便地设计命令队列,也可以很容易地实现对请求的撤销和重做,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令很容易;
[缺点] 使用命令模式会导致某些系统有过多的具体命令类,这使得太多的命令类难于管理;
(P342)
【访问者模式】
[定义] 访问者模式表示一个作用于某对象结构中的各元素的操作。它使开发者可以在不改变各元素的类的前提下定义作用于这些元素的新操作;
[原理] 访问者模式主要由5部分组成:抽象访问者类、具体访问者类、抽象元素类、具体元素类和对象结果类;
[使用时机] 当一个对象结构包含很多类对象,它们有不同的接口,而系统要求这些对象实施一些依赖于其具体类的操作时,就可以考虑使用访问者模式;
[优点] 使用了访问者模式以后,对于原来的类层次增加新的操作,仅仅需要实现一个具体访问者角色就可以了,而不必修改整个类层次,而且每个具体的访问者角色都对应于一个相关操作,因此如果一个操作的需求有变,就不用改动整个类层次,只需修改一个具体访问者角色即可;
[缺点] 如果系统中的类层次发生了变化,就必须修改访问者角色和每一个具体访问者角色,因此访问者模式不适合具体元素角色经常发生变化的情况;
(P348)
【调停者模式】
[定义] 调停者模式就是用一个中介者对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互;
[原理] 调停者模式主要由4部分组成:抽象调停者类、具体调停者类、抽象同事类和具体同事类;
[使用时机] 当一组对象以定义良好但是复杂的方式进行通信,而且这些对象产生的相互依赖关系结构混乱且难以理解,或一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象时,就可以考虑使用调停者模式;
[优点] 当使用调停者模式时,它将各个通信的对象进行解耦,使得原本分布于多个对象间的行为集中在一起,改变这些行为只需生成的协调类即可,这样的关系使得程序更易于理解、维护和扩展;
[缺点] 调停者模式使控制集中化,因为所有的交互行为都集中在调停者类中,使得这个类变得庞大而复杂,从而难以维护;
(P355)
【备忘录模式】
[定义] 备忘录模式就是一个保存另外一个对象内部状态复制的对象,这样以后就可以将该对象恢复到原先保存的状态;
[原理] 备忘录模式主要由2部分组成:源发器类和备忘录类;
[使用时机] 当系统必须要保存一个对象在某一个时刻的状态,以方便需要时能恢复到先前的状态时,就需要考虑使用备忘录模式;
[优点] 使用备忘录模式,可以避免暴露一些只应由源发器管理却又必须存储在源发器之外的信息,而且能够在对象需要时恢复到先前的状态;
[缺点] 使用备忘录可能代价很高。如果源发器在生成备忘录时必须复制并存储大量的信息,或者客户非常频繁地创建备忘录和恢复源发器状态,可能会导致非常大的开销;
(P358)
【迭代器模式】
[定义] 迭代器模式提供一种顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示的方法;
[原理] 迭代器模式主要由4部分组成:迭代器角色、具体迭代器角色、容器角色和具体容器角色;
[使用时机] 当访问一个聚合对象的内容而无需暴露它的内部表示,或者需要支持对聚合对象的多种遍历,或者需要为遍历不同的聚合结构提供一个统一的接口时,就可以考虑使用迭代器模式;
[优点] 迭代器模式分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据;
[缺点] 迭代器模式是为容器而存在的,因此它仅适用于对容器的访问;
(P385)
【解释器模式】
[定义] 解释器模式给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子;
[原理] 解释器模式主要由4部分组成:抽象表达式角色、终结符表达式角色、非终结符表达式和上下文;
[使用时机] 当有一个语言需要解释执行,并且可将该语言中的句子表示为一个抽象语法树时,就可以考虑使用解释器模式;
[优点] 解释器模式提供了一个简单的方式来执行语法,而且容易修改或者扩展语法,但解释器模式比较适用于文法简单并且对处理的效率要求较低的情况;
[缺点] 对于复杂的文法,解释器模式将不是一个很好的选择,因为复杂文法的类层次变得庞大而无法管理,此时语法分析程序生成器这样的工具是更好的选择,它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间;
(P387)
【单一职责原则 (SRP)】
单一职责原则的核心思想就是:系统中的每一个对象都应该只有一个单独的职责,而所有对象所关注的就是自身职责的完成。它的英文缩写是 SRP,英文全称是 Single Responsibility Principle。
其实单一职责原则的意思就是:开发人员经常说的“高内聚、低耦合”。也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。在设计模式中,所有的设计模式都遵循这一原则;
【开闭原则 (OCP)】
开闭原则的核心思想就是:一个对象对扩展开放,对修改关闭。它的英文缩写是 OCP,英文全称是 Open for Extension, Closed for Modification。
其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是改动现有的代码。也就是说,软件开发人员一旦写出了可以运行的代码,就不应该去改变它,而是要保证它能一直运行下去,如何才能做到这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现层则是可以改变和扩展的;
【里氏替换原则 (LSP)】
里氏替换原则的核心思想就是:在任何父类出现的地方都可以用它的子类来替代。它的英文缩写是 LSP,英文全称是 Liskov Substitution Principle。
其实里氏替换原则的意思就是:同一个继承体系中的对象应该有共同的行为特征。里氏替换原则关注的是怎样良好地使用继承,也就是说不要滥用继承,它是继承复用的基石;
【依赖注入原则 (DIP)】
依赖注入原则的核心思想就是:要依赖于抽象,不要依赖于具体的实现。它的英文缩写是 DIP,英文全称是 Dependence Inversion Principle。
其实依赖注入原则的意思就是:在应用程序中,所有的类如果使用或依赖于其他的类,则都应该依赖于这些其他类的抽象类,而不是这些其他类的具体实现类。抽象层次应该不依赖于具体的实现细节,这样才能保证系统的可复用性和可维护性。为了实现这一原则,就要求开发人员在编程时要针对接口编程,而不针对实现编程;
【接口分离原则 (ISP)】
接口分离原则的核心思想就是:不应该强迫客户程序依赖它们不需要使用的方法。它的英文缩写是 ISP,英文全称是 Interface Segregation Principle。
其实接口分离原则的意思就是:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口当中;
【迪米特原则 (LOD)】
迪米特原则的核心思想就是:一个对象应当对其他对象尽可能少的了解。它的英文缩写是 LOD,英文全称是 Law of Demeter。
其实迪米特原则的意思就是:降低各个对象之间的耦合,提高系统的可维护性。在模块之间,应该只通过接口来通信,而不理会模块的内部工作原理,它可以使各个模块耦合程度降到最低,促进软件的复用;
【优先使用组合而不是继承原则 (CARP)】
优先使用组合而不是继承原则的核心思想就是:优先使用组合,而不是继承。它的英文缩写是 CARP,英文全称是 Composite / Aggregate Reuse Principle。
其实优先使用组合而不是继承原则的意思就是:在复用对象的时候,要优先考虑使用组合,而不是继承,这是因为在使用继承时,父类的任何改变都可能影响子类的行为,而在使用组合时,是通过获得对其他对象的引用而在运行时刻动态定义的,有助于保持每个类的单一职责原则;
设计模式和具体的语言没有关系,学习设计模式最重要的目的就是要建立面向对象的思想,尽可能地面向接口编程、低耦合、高内聚,使设计的程序可复用;
在掌握面向对象的思想方式后,再回过头来看设计模式,就会有更深刻的理解;
学习设计模式,一定要勤学多练;
(P4)
对象的创建会消耗掉系统的很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题;
在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了开发人员关注的焦点,因为如何设计对象的结构、继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性等。
对象结构的设计很容易体现出设计人员水平的高低;
在对象的结构和对象的创建问题都解决了之后,就剩下对象的行为问题了,如果对象的行为设计的好,那么对象的行为就会更清晰,它们之间的协作效率就会提高;
(P5)
设计模式并不只是一种方法和技术,它更是一种思想、一个方法论。
它和具体的语言没有关系,学习设计模式最主要的目的就是要建立面向对象的思想,尽可能地面向接口编程、低耦合、高内聚,使你设计的程序尽可能地复用;
(P23)
简单工厂模式又叫静态工厂方法模式,是所有工厂模式中最简单的一个;
在程序设计中,离不开对象的创建,对象创建效率的高低对系统资源的占用影响较大,因此需要对此进行详细研究,最好的办法就是将对象的创建和使用分开;
简单工厂模式只适用于要创建的具体对象比较少或简单的情况,而创建比较复杂的对象时,简单工厂模式不是一个很好的选择;
(P31)
工厂方法模式相对于简单工厂模式来说,就是把一个单一的工厂类,分成了多个具体的小工厂,并抽象出了一个工厂类,这个工厂类只负责定义创建的方式,创建的具体内容由继承它的小工厂类实现;
(P35)
【工厂方法模式】
[定义] 工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由实现抽象工厂的具体工厂类来完成;
[原理] 工厂方法模式主要由4部分组成:抽象工厂类、实现抽象工厂类的具体工厂类、抽象类和实现抽象类的具体类;
[使用时机] 当在代码中使用new来创建对象时,就可以考虑使用工厂方法模式。一般来说,工厂方法模式会应用在比较复杂的对象创建上;
[优点]
在工厂方法模式中,客户端不再负责对象的创建,而是把这个责任交给了具体的工厂类,客户端只负责对象的调用,从而明确了各个类的职责;
如果有新的产品加进来,只需要新增加一个具体的创建产品工厂类和具体的产品类就可以了,不会影响到原来已有的其他代码,代码量也不会变大,后期维护更加容易,增强了系统的可扩展性;
[缺点] 使用该模式需要额外地编写代码,增加了工作量;
(P39)
每一种设计模式都是为了解决一类问题而产生的,如果说工厂方法模式是针对一个产品结构而言的话,那么抽象工厂模式就是针对于多个产品结构而言的,它主要用于帮助客户一次创建多个不同产品对象;
(P40)
工厂方法模式是针对于一个产品系列的,而抽象工厂模式是针对于多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类;
(P45)
【抽象工厂模式】
[定义] 如果客户端需要创建一些产品结构,而这些产品结构又分别属于不同的产品类别,则可以使用抽象工厂模式,抽象工厂模式中抽象工厂类负责定义创建对象的接口,这一系列对象的创建工作由实现抽象工厂的具体工厂类来具体完成;
[原理] 抽象工厂模式主要由4部分组成:抽象工厂类、实现抽象工厂类的具体工厂类、抽象类和实现抽象类的具体类;
[使用时机] 当系统需要创建一系列相互关联的对象时,就需要使用抽象工厂模式;
[优点]
在抽象工厂模式中,客户端不再负责对象的创建,而是把这个责任交给了具体的工厂类,客户端只负责对对象的调用,从而明确了各个类的职责;
当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单,而且,如果要更换这一系列的产品,只需要更换一个工厂类即可;
[缺点] 如果有新的产品加进来,则需要修改抽象工厂类的设计,并同时修改实现这个抽象工厂类的具体工厂类,需要额外编写代码,增加了工作量;
(P52)
在简单工厂模式中,一个工厂类负责所有产品对象的创建,这个工厂类的职责大大增加。由于简单工厂模式使用静态方法来创建对象,这就导致静态方法无法被继承;
在工厂方法模式中,一个具体的工厂类负责创建一个单独的产品,如果有两个不同的产品要创建,就需要两个不同的工厂类,即使这两个产品有某些必要的联系,也还是需要两个不同的工厂类;
在抽象工厂模式中,一个具体的工厂类负责创建一系列相互关联的产品,当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单;如果要更换这一系列的产品,则只需要更换一个工厂类即可;
(P57)
【创建者模式】
[定义] 创建者模式就是将一个复杂对象的构建与它的表示相分离,使得同样的构建过程可以创建不同的表示,而且客户端不知道对象的构建细节;
[原理] 创建者模式主要由5个部分组成:组装类、抽象创建者类、实现抽象创建者类的具体创建者类、抽象产品类和实现抽象产品类的具体产品类;
[使用时机] 当系统需要创建一个复杂的对象,而且这个复杂的对象组装起来比较麻烦时,就可以使用创建者模式;
[优点] 在创建者模式中,客户端不再负责对象的创建和组装,而是把这个创建的责任交给具体的创建者类,把组装的责任交给组装类,客户端只负责对象的调用,从而明确了各个类的职责;
[缺点] 虽然利用创建者模式可以创建出不同类型的产品,但如果产品之间的差异非常大,则需要编写多个创建者类才能实现,这时如果结合工厂模式更好;
(P64)
【原型模式】
[定义] 原型模式就是通过一个原型对象来表明要创建的对象类型,然后用复制这个原型对象的方法来创建更多同类型对象;
[原理] 原型模式主要由2部分组成:抽象原型和具体原型类;
[使用时机] 当系统需要创建的对象是动态加载的,而且产品具有一定层次时,需要使用原型模式;
[优点] 在原型模式中,可以动态地添加产品类,而且对整体结构没有影响;
[缺点] 由于原型模式需要给每个类都配备一个克隆的方法,这就需要在设计类时通盘考虑,因为在已有类的基础上来添加clone操作是比较困难的;而且原型模式在实现深层次的复制时,需要编写一定量的代码;
(P73)
【单例模式】
[定义] 单例模式就是确保一个类只有一个实例,并且该实例必须自动创建,并向整个系统提供该实例;
[原理] 单例模式可以分为饿汉式单例模式和懒汉式单例模式两种:饿汉式单例模式在类初始化时就已经创建了自身的对象,而懒汉式单例模式则是在需要使用的时候才创建自身的对象;
[使用时机] 当系统要求一个类只有一个实例时,就需要使用单例模式;
[优点] 在单例模式中,客户调用类的实例时,只能调用一个公共的接口,这就为整个开发团队提供了一个共享的概念;
[缺点] 实现单例模式的类在实例化后,不能被别的类继承;在分布式系统中,当系统中的单例类被复制运行在多个虚拟机下时,在每一个虚拟机下都会创建一个实例对象,此时如果想知道具体哪个虚拟机下运行着哪个单例对象时很困难的,而且单例类很难实现序列化;
(P79)
在所有的设计模式中,最简单的就数外观模式了。外观模式又叫门面模式,顾名思义,就是对一个系统进行包装,该系统对外的接口统一由外观类进行提供;
【外观模式】
[定义] 外观模式就是为子系统对外提供的一组接口提供一个统一的界面,使得其他系统对该系统的访问都通过这个统一的界面来完成;
[原理] 外观模式主要由3部分组成:抽象外观类、实现抽象外观类的具体外观类和其他子系统;
[使用时机] 当一个复杂的系统需要对外提供接口时,就需要将对外提供的接口统一封装在一个外观类里,供外系统使用;
[优点] 外观模式通过提供一个统一的对外接口,避免了外部系统和子系统之间的直接联系,从而降低了系统间的依赖和复杂度;
[缺点] 限制了外部系统对子系统调用的灵活性,只能按照外观类中提供的方式对子系统进行调用;
(P107)
【适配器模式】
[定义] 适配器模式就是将一个系统的接口转换成另外一种形式,从而使原来不能直接调用的接口变得可以调用;
[原理] 适配器模式主要由3部分组成:目标类、源类和适配器类;
适配器类分为对象适配器和类适配器:对象适配器即实现目标类的接口,依赖适配者类;类适配器即直接继承适配者类,并实现目标类的接口;
[使用时机] 当系统需要使用一个外部接口,而这个外部接口不符合系统需要的时候,就需要使用适配器模式;
[优点] 使用适配器模式,可以将一个系统的接口和本来不相容的另一个系统的类联系起来,从而使得这两个类能够在一起工作,强调了对接口的转换;
[缺点] 对于类适配器来说,不能适配一个类以及它的子类;对于对象适配器来说,重新定义被适配的类的行为比较困难;
(P122)
【代理模式】
[定义] 代理模式就是给一个对象提供一个代理对象,由这个代理对象控制对原对象的引用,使代理类在客户端和原对象之间起到一个中介的作用;
[原理] 代理模式主要由3部分组成:抽象目标类、具体目标类和代理类;
[使用时机] 当系统需要对某个对象进行额外的控制时,就需要使用代理模式;
[优点] 使用代理模式,能够在不改变原来代码功能的基础上对某一对象进行额外的控制,从而更好地体现了面向对象中单一职责的思想;
[缺点] 对于静态代理来说,一个接口只服务于一种类型,如果要代理的方法很多,则要为每个方法定义一个接口;
(P153)
【装饰模式】
[定义] 装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例委托给装饰类。装饰模式是继承关系的一个替代方案;
[原理] 装饰模式主要由4部分组成:抽象的被装饰类、具体的被装饰类、抽象的装饰类和具体的装饰类;
[使用时机] 当系统需要扩展一个类的功能,或者客户端需要动态的给一个对象添加功能,并且此时如果使用继承会很复杂时,就需要使用装饰模式;
[优点] 使用装饰模式,能够提供比使用继承关系更灵活的扩展对象的功能,它可以动态地增加对象的功能,并且可以随意地组合这些功能;
[缺点] 正因为可以随意地组合这些功能,有时候就可能会出现一些不合理的逻辑。使用装饰模式进行系统设计往往会产生许多看上去类似的小对象,这些对象的类或是它们的属性值是一样的,仅仅在它们相互连接的方式上有所不同;
(P171)
桥模式可能是所有设计模式中最难理解的一个模式了;
桥模式中的抽象指的是抽象类及派生类,实现指的是这些抽象类及派生类实现自己的方式;
【桥模式】
[定义] 桥模式就是将抽象与其实现解耦,使它们可以分别独立地变化。桥模式也是继承关系的一个替代方案;
[原理] 桥模式主要由4部分组成:抽象类、抽象类的继承类、实现类和实现类的继承类;
[使用时机] 当系统需要在它的抽象和实现之间增加更多的灵活性,或者一个对象有多于一个的抽象和实现时,就需要使用桥模式;
[优点] 使用桥模式,能够提供比使用继承关系更灵活的功能。它可以使抽象和实现分离开,降低了耦合关系。当有新的抽象或实现方式时,只需要继承一个抽象和继承一个实现即可;
[缺点] 如果要重新抽象出另外一个类型,则需要修改抽象;
(P196)
适配器、代理、装饰和桥模式都是为了解决对象之间的依赖关系,降低对象间的耦合度,给设计增加更多的灵活性;
(P201)
【组合模式】
[定义] 组合模式就是把部分和整体的关系用树形结构来表示,从而使客户端能够把一个一个的部分对象和由它们组合起来的整体对象采用同样的方式来看待。它也是继承的一个替代方案;
[原理] 组合模式主要由3部分组成:抽象类、叶子类和父类;
[使用时机] 当系统要描述的对象是树形结构,并且要在客户端忽略掉子对象和父对象的区别时,就需要使用组合模式;
[优点] 使用组合模式,能够提供比使用继承关系更灵活的功能,并且可以灵活地组合子对象和父对象之间的关系,从而使客户端的调用简单,客户端可以一致地使用组合结构或其中单个对象,用户就不必关心自己处理的是单个对象还是整个组合结构,这简化了客户端代码;
[缺点] 虽然组合模式使得向集合添加新类型的组件变得容易,只要这些组件提供一个相似的编程接口即可,但这也是它的缺点,因为这种做法很难限制某个类;
(P220)
【享元模式】
[定义] 享元模式就是把部分和整体的关系用树形结构来表示,从而使客户端能够把一个一个的部分对象和由它们组合起来的整体对象采用同样的方式来看待。它也是继承的一个替代方案;
[原理] 享元模式主要由3部分组成:享元类、具体的享元类和享元工厂类;
[使用时机] 当系统需要使用大量重复的对象,而且这些对象要消耗很大的内存时,就需要使用享元模式;
[优点] 使用享元模式,可以为系统节省大量的空间;
[缺点] 但是在享元工厂里可以看到,需要维护所有的享元对象,如果要维护的享元很多,在查找的时候要消耗大量的时间。因此,享元模式是典型的以时间换空间;
(P227)
结构型模式主要解决了对象的组成以及对象之间的依赖关系;
(P234)
【模板方法模式】
[定义] 模板方法模式就是定义一个算法执行的骨架,而将具体的算法延迟到子类中来实现;
[原理] 模板方法模式主要由2部分组成:抽象的骨架类和具体实现类;
[使用时机] 当系统中算法的骨架是固定的,而算法的实现可能有很多种的时候,就需要使用模板方法模式;
[优点] 使用模板方法模式,在定义算法的骨架的同时,可以很灵活地实现具体的算法,满足用户灵活多变的需求;
[缺点] 虽然使用模板方法模式可以很自由地实现具体的算法,但如果算法的骨架有改变的话,则需要修改抽象类;
(P270)
【观察者模式】
[定义] 观察者模式就是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新;
[原理] 观察者模式主要由4部分组成:抽象目标类、具体目标类、抽象观察者类和具体观察者类;
[使用时机] 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有所改变,或者说当一个对象必须通知其他对象,而它又不能假定其他对象是谁的时候,就需要使用观察者模式;
[优点] 观察者模式在被观察者和观察者之间建立一个抽象的耦合,每一个具体观察者都符合一个抽象观察者的接口,被观察者并不知道任何一个具体观察者,它只知道它们都有一个共同的接口,从而使得被观察者和观察者耦合度降低,而且观察者模式支持广播通信。被观察者会向所有的注册过的观察者发出通知;
[缺点] 如果一个被观察者对象有很多观察者,通知所有的观察者会耗费很多时间;
(P286)
【状态模式】
[定义] 状态模式就是根据对象的状态不同,将有不同的行为;
[原理] 状态模式主要由3部分组成:抽象状态类、具体状态类和上下文类;
[使用时机] 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为,或者一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态时,就需要使用状态模式;
[优点] 状态模式使代码中复杂而冗长的逻辑判断语句问题得到了解决,而且具体状态角色将具体状态和它对应的行为封装了起来,这使得增加一种新的状态变得十分简单;
[缺点] 使用状态模式时,每个状态对应一个具体的状态类。使结构分散,逻辑不太清晰,阅读代码时比较困难;
(P299)
【策略模式】
[定义] 策略模式就是定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化;
[原理] 策略模式主要由3部分组成:抽象策略类、具体策略类和上下文场景类;
[使用时机] 当系统需要能够在几种算法中快速地切换,或系统中有一些类,它们仅行为不同时,或系统中存在多重条件选择语句时,就可以考虑采用策略模式;
[优点] 使用策略模式,可以替换继承关系的办法,也可以避免使用多重条件转移语句;
[缺点] 使用策略模式时客户端必须知道所有的策略类,并自行决定使用哪一个策略类,如果算法比较多,则会造成很多的策略类;
(P305)
【职责链模式】
[定义] 职责链模式就是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止;
[原理] 职责链模式主要由2部分组成:抽象处理类、具体处理类和上下文场景类;
[使用时机] 当有多个对象处理请求,而且需要动态指定处理者的时候,就可以考虑使用职责链模式;
[优点] 使用职责链模式可以降低类之间的耦合度。使得处理类仅需要保持一个指向其后继者的引用,也使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需知道该请求会被正确地处理,接收者和发送者都没有对方的明确的信息,这种处理方法增强了给对象指派职责的灵活性;
[缺点] 因为对象不知道是其他哪一个对象处理其请求的,所以职责链模式不保证对象被接收,从而使得该请求可能一直到链接的末端都得不到处理;
(P316)
【命令模式】
[定义] 命令模式就是把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能;
[原理] 命令模式主要由4部分组成:抽象命令类、具体命令类、调用者和接收者;
[使用时机] 当需要先将一个函数登记上,然后在以后调用此函数时,就需要使用命令模式,其实这就是回调函数;
[优点] 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开,从而使新的命令可以很容易地被加入到系统里,可以很方便地设计命令队列,也可以很容易地实现对请求的撤销和重做,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令很容易;
[缺点] 使用命令模式会导致某些系统有过多的具体命令类,这使得太多的命令类难于管理;
(P342)
【访问者模式】
[定义] 访问者模式表示一个作用于某对象结构中的各元素的操作。它使开发者可以在不改变各元素的类的前提下定义作用于这些元素的新操作;
[原理] 访问者模式主要由5部分组成:抽象访问者类、具体访问者类、抽象元素类、具体元素类和对象结果类;
[使用时机] 当一个对象结构包含很多类对象,它们有不同的接口,而系统要求这些对象实施一些依赖于其具体类的操作时,就可以考虑使用访问者模式;
[优点] 使用了访问者模式以后,对于原来的类层次增加新的操作,仅仅需要实现一个具体访问者角色就可以了,而不必修改整个类层次,而且每个具体的访问者角色都对应于一个相关操作,因此如果一个操作的需求有变,就不用改动整个类层次,只需修改一个具体访问者角色即可;
[缺点] 如果系统中的类层次发生了变化,就必须修改访问者角色和每一个具体访问者角色,因此访问者模式不适合具体元素角色经常发生变化的情况;
(P348)
【调停者模式】
[定义] 调停者模式就是用一个中介者对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互;
[原理] 调停者模式主要由4部分组成:抽象调停者类、具体调停者类、抽象同事类和具体同事类;
[使用时机] 当一组对象以定义良好但是复杂的方式进行通信,而且这些对象产生的相互依赖关系结构混乱且难以理解,或一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象时,就可以考虑使用调停者模式;
[优点] 当使用调停者模式时,它将各个通信的对象进行解耦,使得原本分布于多个对象间的行为集中在一起,改变这些行为只需生成的协调类即可,这样的关系使得程序更易于理解、维护和扩展;
[缺点] 调停者模式使控制集中化,因为所有的交互行为都集中在调停者类中,使得这个类变得庞大而复杂,从而难以维护;
(P355)
【备忘录模式】
[定义] 备忘录模式就是一个保存另外一个对象内部状态复制的对象,这样以后就可以将该对象恢复到原先保存的状态;
[原理] 备忘录模式主要由2部分组成:源发器类和备忘录类;
[使用时机] 当系统必须要保存一个对象在某一个时刻的状态,以方便需要时能恢复到先前的状态时,就需要考虑使用备忘录模式;
[优点] 使用备忘录模式,可以避免暴露一些只应由源发器管理却又必须存储在源发器之外的信息,而且能够在对象需要时恢复到先前的状态;
[缺点] 使用备忘录可能代价很高。如果源发器在生成备忘录时必须复制并存储大量的信息,或者客户非常频繁地创建备忘录和恢复源发器状态,可能会导致非常大的开销;
(P358)
【迭代器模式】
[定义] 迭代器模式提供一种顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示的方法;
[原理] 迭代器模式主要由4部分组成:迭代器角色、具体迭代器角色、容器角色和具体容器角色;
[使用时机] 当访问一个聚合对象的内容而无需暴露它的内部表示,或者需要支持对聚合对象的多种遍历,或者需要为遍历不同的聚合结构提供一个统一的接口时,就可以考虑使用迭代器模式;
[优点] 迭代器模式分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据;
[缺点] 迭代器模式是为容器而存在的,因此它仅适用于对容器的访问;
(P385)
【解释器模式】
[定义] 解释器模式给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子;
[原理] 解释器模式主要由4部分组成:抽象表达式角色、终结符表达式角色、非终结符表达式和上下文;
[使用时机] 当有一个语言需要解释执行,并且可将该语言中的句子表示为一个抽象语法树时,就可以考虑使用解释器模式;
[优点] 解释器模式提供了一个简单的方式来执行语法,而且容易修改或者扩展语法,但解释器模式比较适用于文法简单并且对处理的效率要求较低的情况;
[缺点] 对于复杂的文法,解释器模式将不是一个很好的选择,因为复杂文法的类层次变得庞大而无法管理,此时语法分析程序生成器这样的工具是更好的选择,它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间;
(P387)
【单一职责原则 (SRP)】
单一职责原则的核心思想就是:系统中的每一个对象都应该只有一个单独的职责,而所有对象所关注的就是自身职责的完成。它的英文缩写是 SRP,英文全称是 Single Responsibility Principle。
其实单一职责原则的意思就是:开发人员经常说的“高内聚、低耦合”。也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。在设计模式中,所有的设计模式都遵循这一原则;
【开闭原则 (OCP)】
开闭原则的核心思想就是:一个对象对扩展开放,对修改关闭。它的英文缩写是 OCP,英文全称是 Open for Extension, Closed for Modification。
其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是改动现有的代码。也就是说,软件开发人员一旦写出了可以运行的代码,就不应该去改变它,而是要保证它能一直运行下去,如何才能做到这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现层则是可以改变和扩展的;
【里氏替换原则 (LSP)】
里氏替换原则的核心思想就是:在任何父类出现的地方都可以用它的子类来替代。它的英文缩写是 LSP,英文全称是 Liskov Substitution Principle。
其实里氏替换原则的意思就是:同一个继承体系中的对象应该有共同的行为特征。里氏替换原则关注的是怎样良好地使用继承,也就是说不要滥用继承,它是继承复用的基石;
【依赖注入原则 (DIP)】
依赖注入原则的核心思想就是:要依赖于抽象,不要依赖于具体的实现。它的英文缩写是 DIP,英文全称是 Dependence Inversion Principle。
其实依赖注入原则的意思就是:在应用程序中,所有的类如果使用或依赖于其他的类,则都应该依赖于这些其他类的抽象类,而不是这些其他类的具体实现类。抽象层次应该不依赖于具体的实现细节,这样才能保证系统的可复用性和可维护性。为了实现这一原则,就要求开发人员在编程时要针对接口编程,而不针对实现编程;
【接口分离原则 (ISP)】
接口分离原则的核心思想就是:不应该强迫客户程序依赖它们不需要使用的方法。它的英文缩写是 ISP,英文全称是 Interface Segregation Principle。
其实接口分离原则的意思就是:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口当中;
【迪米特原则 (LOD)】
迪米特原则的核心思想就是:一个对象应当对其他对象尽可能少的了解。它的英文缩写是 LOD,英文全称是 Law of Demeter。
其实迪米特原则的意思就是:降低各个对象之间的耦合,提高系统的可维护性。在模块之间,应该只通过接口来通信,而不理会模块的内部工作原理,它可以使各个模块耦合程度降到最低,促进软件的复用;
【优先使用组合而不是继承原则 (CARP)】
优先使用组合而不是继承原则的核心思想就是:优先使用组合,而不是继承。它的英文缩写是 CARP,英文全称是 Composite / Aggregate Reuse Principle。
其实优先使用组合而不是继承原则的意思就是:在复用对象的时候,要优先考虑使用组合,而不是继承,这是因为在使用继承时,父类的任何改变都可能影响子类的行为,而在使用组合时,是通过获得对其他对象的引用而在运行时刻动态定义的,有助于保持每个类的单一职责原则;
相关推荐
《易学设计模式》这本书是面向软件开发人员的一本实用指南,旨在帮助读者轻松掌握设计模式这一核心的软件工程概念。设计模式是经过时间和实践验证的解决方案,它们针对在软件设计过程中经常遇到的问题提供了一套标准...
"易学设计模式源码光盘" 提供了一种直观的学习方式,帮助初学者更轻松地理解和应用这些模式。这里我们将深入探讨设计模式的核心理念、主要分类以及一些常见设计模式的实现细节。 首先,设计模式的出现源于对软件...
《易学_设计模式_郭志学》作为一本专注于Java设计模式的书籍,在软件开发领域中占据了举足轻重的地位。设计模式作为软件工程中的一块基石,它不仅仅是代码层面的模板,更是设计思想的结晶。通过学习和应用这些设计...
《Java易学设计模式》全书的随书源码,每一个章节一个压缩包,分别为:工厂模式、命令模式、组合模式、模板方法模式、工厂方法模式例子、状态模式例子、迭代器模式、解释器模式、享元模式、桥模式、装饰模式、代理...
"java-易学设计模式"这个压缩包很可能是包含了一些关于Java设计模式的示例源代码,方便学习者理解和掌握。 首先,我们来讨论一下设计模式的基本分类。设计模式分为三类:创建型模式、结构型模式和行为型模式。 1. ...
《易学设计模式》源码是一份珍贵的学习资源,它基于JAVA语言,为读者提供了书中讲解的各种设计模式的实际实现。设计模式是软件工程中的重要概念,它们是解决常见问题的可复用解决方案,有助于提高代码的可读性、可...
《易学 设计模式》 郭志学 编著 随书源代码 ☆ 章节清单:☆ 第01章 欲速则不达:了解设计模式 第02章 磨刀不误砍柴工:UML语言概述 第03章 术业有专攻:简单工厂模式 (SimpleFactory) 第04章 精益求精:工厂方法...
《易学C++》系列教程是为初学者设计的一套教学资源,旨在帮助读者快速掌握C++编程语言的基础知识。本教程涵盖了C++语言的前五章内容,以PPT格式呈现,便于教学和自学。PPT的设计注重清晰性和易理解性,通过图文并茂...
"易学C++"系列教程可能是为了帮助初学者更轻松地掌握这门语言而设计的。从标题"易学C++6-10章ppt格式"来看,我们可以推断这部分内容涵盖了C++语言的基础到进阶知识,包括第六章到第十章的关键概念。 第六章可能涉及...
绿色风格的学校类网站模板,下载后用户可根据自己需要来在后台调整结构或修改内容,首页采用选项卡设计把多个文章模块整和在一起,整体布局更加简洁明快,可用于各种大学、大中专院校、培训机构、高中、初中学等...
主要功能全部采用自定义模型(专业版本内置产品、文章和反馈三种模型),可以任意扩展字段和自由设计信息排列方式,在原有模块组合功能上增加了标签调用,制作复杂结构就变得轻而易举................... 宽度:1000...
模板介绍: 红色、浅蓝色色调组合风格的学校网站模板,基于pageadmin cms v3制作,风格清晰,极具时尚设计感,可用于职业学校、大专院校等学校网站搭建。 宽度:1000px 对齐:居中 主色:红色、浅蓝色
模板介绍: 褐色风格的的宾馆网站模板,结构简洁,风格清晰,设计感强,适合制作宾馆、酒店,饭店、装修公司等企业网站..... 宽度:1000px 对齐:居中 主色:褐色 结构:div+css 运行环境:asp.net2.0(或以上)
模板介绍: 绿色风格的政府门户网站模板,基于pageadmin v3.0版本制作,风格清新大气,结构布局简洁,...主要功能全部采用自定义模型,可以任意扩展字段和自由设计功能及界面。 宽度:1000px 对齐:居中 主色:绿色
模板介绍: 浅蓝色风格的政府网站模板,色泽轻快,结构布局浑厚大气,下载后用户可根据自己所在单位情况来在后台调整结构和内容,,可适用于一般的政府网站或行政事业单位网站搭建;只需要此风格的用户可以直接复制...
模板介绍: 褐色风格的茶楼网站模板,风格典雅,适合制作餐饮、酒店,饭店、宾馆、茶楼褐色等企业网站搭建。 宽度:990px 对齐:居中 主色:褐色 结构:div+css 运行环境:asp.net2.0(或以上)
模板介绍: 深蓝色风格的政府网站模板,下载后用户可根据自己所在单位情况来在后台调整结构和内容,结构布局浑厚大气,可适用于一般的政府网站或行政事业单位网站搭建;只需要此风格的用户可以直接复制template目录下...