设计模式六大原则
单一职责原则( Single responsibility principle )
- 解释: 就一个类而言,应该仅有一个引起它变化的原因。简单来说,一个类中应该是一组相关性很高的函数,数据的封装。
- 目的: 类的复杂性降低,可读性提高,可维护性提高。
开闭原则(Open Close Principle)
勃兰特·梅耶(Bertrand Meyer)在1988年出版的《面向对象软件构造》一书中提出这一原则----开闭原则。这一想法认为程序一旦开发完成,程序中一个类的实现只应该因错误而被修改,新的或者改变的特性应该通过新建不同的类实现,新建的类可以通过继承的方式来重用原类的代码。
- 解释:软件模块应该对扩展开放,对修改关闭。
- 举例:在程序需要进行新增功能的时候,不能去修改原有的代码,而是新增代码,实现一个热插拔的效果(热插拔:灵活的去除或添加功能,不影响到原有的功能)。
- 目的:为了使程序的扩展性好,易于维护和升级。
里氏替换原则(Liskov Substitution Principle)
里氏替换原则是Barbara Liskov 女士在1988年发表的[ASD],具体的数学定义比较复杂,翻译成白话文就是 一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它觉察不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变化。
- 解释: 子类型必须能够替换掉它们的父类型。
- 举例:球类,原本是一种体育用品,它的衍生类有篮球、足球、排球、羽毛球等等,如果衍生类替换了基类的原本方法,如把体育用品改成了食用品(那么软件单位的功能受到影响),就不符合里氏代换原则。
- 目的: 对实现抽象化的具体步骤的规范。
依赖倒置原则(Dependence Inversion Principle)
- 解释: 针对接口编程,不要依赖实现编程。
- 关键点:
- 高层模块不应该依赖底层模块。两个应该都依赖于抽象。
- 抽象不应该依赖于细节。细节应该依赖于抽象。
- 举例:以计算机系统为例,无论主板、CPU、内存、硬件都是在针对接口设计的,如果针对实现来设计,内存就要对应到针对某个品牌的主板,那么会出现换内存需要把主板也换掉的尴尬。
- 目的:降低模块间的耦合。
接口隔离原则(Interface Segregation Principle)
接口隔离原则(缩写:ISP)指明客户(client)应该不依赖于它不使用的方法。
- 解释: 接口隔离原则(ISP)拆分非常庞大臃肿的接口成为更小的和更具体的接口,这样客户将会只需要知道他们感兴趣的方法。这种缩小的接口也被称为角色接口(role interfaces)。
- 举例:比如:登录,注册时属于用户模块的两个接口,比写成一个接口好。
- 目的: 接口隔离原则(ISP)的目的是系统解开耦合,从而容易重构,更改和重新部署。
迪米特原则(Demeter Principle)
1987年秋天由美国Northeastern University的Ian Holland提出,被UML的创始者之一Booch等普及。后来,因为在经典著作《 The Pragmatic Programmer》而广为人知。
- 解释: 一个类应该对其他对象有最少的了解。通俗的讲,一个类应该对自己需要耦合或调用的类知道得最少,类的内部如何实现与调用者或者依赖者没有关系,调用者或者依赖者只需要知道它需要的方法即可,其他的可一概不用管。类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
- 举例:一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也就越大。
- 目的: 降低类之间的耦合,减少对其他类的依赖。
24种设计模式分类
1.创建型模式
创建型模式,就是创建对象的模式,抽象了实例化的过程。它帮助一个系统独立于如何创建、组合和表示它的那些对象。关注的是对象的创建,创建型模式将创建对象的过程进行了抽象,也可以理解为将创建对象的过程进行了封装,作为客户程序仅仅需要去使用对象,而不再关系创建对象过程中的逻辑。
社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和对象的使用分开也就成为了必然趋势。因为对象的创建会消耗掉系统的很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题。这里有6个具体的创建型模式可供研究,它们分别是:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
- 创建者模式(Builder)
- 原型模式(Prototype)
- 单例模式(Singleton)
简单工厂模式不是GoF总结出来的23种设计模式之一
2.结构型模式
结构型模式是为解决怎样组装现有的类,设计它们的交互方式,从而达到实现一定的功能目的。结构型模式包容了对很多问题的解决。例如:扩展性(外观、组成、代理、装饰)、封装(适配器、桥接)。
在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了开发人员关注的焦点,因为如何设计对象的结构、继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性等。对象结构的设计很容易体现出设计人员水平的高低,这里有7个具体的结构型模式可供研究,它们分别是:
- 外观模式/门面模式(Facade门面模式)
- 适配器模式(Adapter)
- 代理模式(Proxy)
- 装饰模式(Decorator)
- 桥梁模式/桥接模式(Bridge)
- 组合模式(Composite)
- 享元模式(Flyweight)
3.行为型模式
行为型模式涉及到算法和对象间职责的分配,行为模式描述了对象和类的模式,以及它们之间的通信模式,行为模式刻划了在程序运行时难以跟踪的复杂的控制流可分为行为类模式和行为对象模式。
- 行为类模式使用继承机制在类间分派行为。
- 行为对象模式使用对象聚合来分配行为。一些行为对象模式描述了一组对等的对象怎样相互协作以完成其中任何一个对象都无法单独完成的任务。
在对象的结构和对象的创建问题都解决了之后,就剩下对象的行为问题了,如果对象的行为设计的好,那么对象的行为就会更清晰,它们之间的协作效率就会提高,这里有11个具体的行为型模式可供研究,它们分别是:
- 模板方法模式(Template Method)
- 观察者模式(Observer)
- 状态模式(State)
- 策略模式(Strategy)
- 职责链模式(Chain of Responsibility)
- 命令模式(Command)
- 访问者模式(Visitor)
- 调停者模式(Mediator)
- 备忘录模式(Memento)
- 迭代器模式(Iterator)
- 解释器模式(Interpreter)
三者之间的区别和联系
创建型模式提供生存环境,结构型模式提供生存理由,行为型模式提供如何生存。
- 创建型模式为其他两种模式使用提供了环境。
- 结构型模式侧重于接口的使用,它做的一切工作都是对象或是类之间的交互,提供一个门。
- 行为型模式顾名思义,侧重于具体行为,所以概念中才会出现职责分配和算法通信等内容。
参考:
https://www.jianshu.com/p/e063ecad9587
《Head First 设计模式》
《Android 源码设计模式解析与实战》
《大话设计模式》