一、设计原则

  1. 单一职责原则
    一个类,只有一个引起它变化的原因。应该只有一个职责。每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离。

  2. 开闭原则(Open Close Principle)
    开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

  3. 里氏代换原则(Liskov Substitution Principle)
    里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。from:百度百科

  4. 依赖倒转原则(Dependence Inversion Principle)
    所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

    实现开闭原则的关键是抽象化,并且从抽象化导出具体化实现,如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要手段。 from:百度百科

  5. 接口隔离原则(Interface Segregation Principle)
    这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。

  6. 合成复用原则(Composite Reuse Principle)
    合成复用原则就是指在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用其已有功能的目的。简言之:要尽量使用组合/聚合关系,少用继承。

  7. 迪米特法则(最少知道原则)(Demeter Principle)
    为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。也就是说一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。

二、设计模式


  1. 创建型:除了直接new来实例化对象外,提供了多种隐藏创建逻辑的生成对象的方法
  2. 结构型:通过对象和类的组合,得到新的结构和功能
  3. 行为型:解决对象之间的通行和功能职责分配

- 创建型 5种

  1. 简单工厂(算不上模式)

    就是一个静态工厂类,提供一个产品族,工厂通过传入的产品类型参数,决定实例化具体的产品。 (日志记录器,依据保存地点生成对应的日志记录器)
  2. 工厂方法模式
    一个产品对应一个工厂,便于扩展新的产品,只需要增加新的产品子类和工厂子类就可以。
  3. 抽象工厂模式

    引入产品树,一个工厂实例对应一系列产品。与工厂方法模式的区别就是,工厂方法只有一个产品接口,而抽象工厂有多个产品接口。(JDBC驱动)
  4. 单例模式

    提供全局的一个唯一实例,避免频繁的创建和销毁。(序列号生成器,计数器),实现方式有懒汉式,饿汉式,双重校验锁,静态内部类,枚举
  5. 建造者模式

    关注产品的组装和次序。(快餐店基本食品相对固定,可以组装出多种套餐)
  6. 原型模式

    使用克隆的方法来生成对象。(类初始化西药消耗较多资源时,比如在使用不可变类的时候,生成副本)

- 结构型 7种

  1. 适配器模式

    接口转换。适配器其实更像个代理类,实现目标接口,然后将目标接口的方法转给被适配的接口的方法。
  2. 桥接模式

    就是原来通过派生子类来实现的变化改为组合的方式来实现。比如一个图形类,实现两个子类,一个画红圈,一个画绿圈,改为抽取一个draw借口,实现两个reddraw和greendraw类,原来的图形类组合draw类过滤器模式,对对象的流式操作。参考jdk8的stream api
  3. 组合模式

    使用一个元素类型,形成一个树结构,元素类型中包含自己元素数组域。
  4. 装饰器模式

    实现被装饰类接口,并且代理被装饰类的方法,在代理方法的同时加入装饰代码。实现方式和适配器差不多,不过目的不一样,只不过适配器代理的是不兼容的接口,而装饰器代理的是被装饰接口
  5. 外观模式

    屏蔽复杂系统,提供统一接口简化客户端调用。这个比较符合地米特最少知道法则。
  6. 享元模式

    对象池,共享对象。比如线程池,连接池。同时也是一种缓存思想。
  7. 代理模式

    spring aop,控制对象访问。光看uml,和适配器,装饰器非常像,区别在于应用场景上。

- 行为型

  1. 责任链模式

    参考tomcat的pipeline。每个责任链组件都持有者下一个组件的应用,当前组件处理方法之后调用下一个组件的处理方法。,
  2. 命令模式

    将行为请求者和行为实现者解耦,将行为抽象为对象。还是以遥控器和电视机举例子,按一般的使用思路,遥控器持有电视机实例,遥控器通过每个具体的方法来操作电视机。引入命令模式后,遥控器持有命令列表(这样才能支持撤销/恢复),命令持有电视机对象,一个命令对应电视机一个操作,遥控器执行命令即可,可作为遥控器的使用者,就往遥控器里面添加命令对象,遥控器执行命令对象。 将行为请求者和行为实现者解耦,将行为抽象为对象。还是以遥控器和电视机举例子,按一般的使用思路,遥控器持有电视机实例,遥控器通过每个具体的方法来操作电视机。引入命令模式后,遥控器持有命令列表(这样才能支持撤销/恢复),命令持有电视机对象,一个命令对应电视机一个操作,遥控器执行命令即可,可作为遥控器的使用者,就往遥控器里面添加命令对象,遥控器执行命令对象。
  3. 解释器模式

  4. 迭代器模式

    将集合对象的存储数据和遍历数据职责分离。“用于顺序访问集合对象的元素,不需要知道集合对象的低层表示”,即你可以使用迭代器顺序访问hashtable的key,而不需要知道key在hashtable中是如何组织的。即将遍历的责任交给迭代器(Hashtable返回的key迭代器,value迭代器)。设计上来说,迭代器类会是容器类的内部类,生成的内部类实例持有者外部类的引用。将集合对象的存储数据和遍历数据职责分离。“用于顺序访问集合对象的元素,不需要知道集合对象的低层表示”,即你可以使用迭代器顺序访问hashtable的key,而不需要知道key在hashtable中是如何组织的。即将遍历的责任交给迭代器(Hashtable返回的key迭代器,value迭代器)。设计上来说,迭代器类会是容器类的内部类,生成的内部类实例持有者外部类的引用。
  5. 中介者模式

    解耦对象之间的交互(MVC中的C就是M和V的中介,消息中间件的订阅)解耦对象之间的交互(MVC中的C就是M和V的中介,消息中间件的订阅)
  6. 备忘录模式

    类似savepoint。主要有三个角色:状态类(单个savepoint),操作类(读取或保存savepoint),状态列表类(savepoint列表)类似savepoint。主要有三个角色:状态类(单个savepoint),操作类(读取或保存savepoint),状态列表类(savepoint列表)
  7. 观察者模式

    事件分发,异步。简单的观察者实现时维护状态的对象持有并维护一个观察者列表,状态发生时逐个通知。不过现在较通用的是通过消息中间件的消息订阅的方式,来通知变更。事件分发,异步。简单的观察者实现时维护状态的对象持有并维护一个观察者列表,状态发生时逐个通知。不过现在较通用的是通过消息中间件的消息订阅的方式,来通知变更。
  8. 状态模式

    将状态抽象为类,形成一个状态树。改变状态时,替换上下文中的状态类,这样上下文中,看起来,状态改变时,行为也改变了。将状态抽象为类,形成一个状态树。改变状态时,替换上下文中的状态类,这样上下文中,看起来,状态改变时,行为也改变了。
    空对象模式,提供空对象而不是Null。这个在实战中比较有用,可以避免大量的是否等于NULL的判断,比如流程申请页面,第一次申请和退回到申请页面,如果不是用空对象,页面就要增加很多空判断。如果使用空对象,则可以一致处理。
  9. 策略模式

    封装算法,任意替换。实现上和状态模式非常像。仅仅是抽象的对象不同,状态模式抽象的是状态,策略模式抽象的是算法,都是通过替换上下文中对应的类,来达到改变行为的目的。封装算法,任意替换。实现上和状态模式非常像。仅仅是抽象的对象不同,状态模式抽象的是状态,策略模式抽象的是算法,都是通过替换上下文中对应的类,来达到改变行为的目的。
  10. 模板模式

    定义算法/流程骨架,一些步骤延迟到子类去实现,由子类来定义算法的某个具体步骤。大多框架均适用模板模式,比如spring的容器实现,或是tomcat的容器初始化,由上层定义通用过程,每一层的子类逐步完整整个骨架内的步骤定义算法/流程骨架,一些步骤延迟到子类去实现,由子类来定义算法的某个具体步骤。大多框架均适用模板模式,比如spring的容器实现,或是tomcat的容器初始化,由上层定义通用过程,每一层的子类逐步完整整个骨架内的步骤
  11. 访问者模式

    将数据结构和数据操作分离。BUT HOW?数据对象提供方法,接纳访问者对象,然后在访问者对象的访问方法中,将this传入,这样,在访问者中,就可以访问该类,并进行操作了。对一个对象可以提供多种不同行为的访问者,这样数据存储和数据操作之间就解耦了。这种模式,在spring的bean初始化的时候有使用,将reader传入factory,然后将this传入reader,reader加载完beandefinition后,再将之添加进factory将数据结构和数据操作分离。BUT HOW?数据对象提供方法,接纳访问者对象,然后在访问者对象的访问方法中,将this传入,这样,在访问者中,就可以访问该类,并进行操作了。对一个对象可以提供多种不同行为的访问者,这样数据存储和数据操作之间就解耦了。这种模式,在spring的bean初始化的时候有使用,将reader传入factory,然后将this传入reader,reader加载完beandefinition后,再将之添加进factory

一句话总结

  • 创建型
0. 简单工厂(不算模式):
1. 工厂模式:由子类决定要创建的具体类是哪一个
2. 抽象工厂模式:允许客户创建对象的家族,而无需指定他们的具体类
3. 单例模式:确保有且只有一个对象被创建
4. 原型模式:clone, 深拷贝,浅拷贝
5. 建造者模式:隐藏具体的建造过程及细节
  • 结构型
1. 适配器模式:封装对象,并提供不同的接口
2. 装饰者模式:给对象附加不同的责任或功能
3. 外观模式:简化一群类的接口
4. 组合模式:客户用一致的方式处理对象集合和单个对象
5. 桥接模式:抽象与实现分离以实现不同的
6. 代理模式:你的经纪人
7. 享元模式:共享技术,支持大量细粒度的对象
  • 行为型
1. 策略模式:封装可以互换的行为,并使用委托来决定要使用哪一个。
2. 观察者模式:让对象能够在状态改变时被通知
3. 模板方法模式:由子类决定如何实现一个算法中的步骤
4. 命令模式:封装请求成为对象
5. 状态模式:封装了基于状态的行为,并使用委托在行为之间切换
6. 迭代器模式:在对象的集合之间游走,而不暴露集合的实现
7. 责任链模式:和链表有点像,每个责任者都保存了要设置的下一个处理对象的指针或引用
8. 中介者模式:联合国,处理各国纠纷
9. 解释器模式:编译器
10. 备忘录模式: 游戏存档
11. 访问者模式:最复杂的模式,适用于数据结构相对稳定的系统
10-09 04:23