面向对象设计模式概述

什么是设计模式

设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结

使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。

设计模式七大原则

开闭原则OCP(Open Close Principle)

一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

在设计一个模块的时候,应当对这个模块可以在不被修改的前提下被扩展。换言之,应当可以在不必修改源代码的情况下改变这个模块的行为,在保持系统一定稳定性的基础上,对系统进行扩展。

为了满足开闭原则,需要对系统进行抽象化设计,抽象化是开闭原则的关键。在很多面向对象编程语言中都提供了接口、抽象类等机制,可以通过它们定义系统的抽象层,再通过具体类来进行扩展。

单一职责原则SRP(Simple Responsibility Principle)

就一个类而言,它的功能应该是相对固定的,一个类只负责一个功能领域中的相应职责,应该只有一个引起它变化的原因。

多于一个动机去改变一个类,那么这个类就具有多于一个职责,这时候就应该考虑类的职责分离,即需要将这个类进行拆分。

一个类承担的职责过多,就等于把这些职责耦合在一起。一个职责的变化可能会削弱或者限制这个类完成其他职责的能力。即内部耦合度高,可维护性差。

单一职责原则是实现高内聚、低耦合的指导方针,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实践经验。

依赖倒转原则DIP(Dependency Inversion Principle)

抽象不应该依赖于具体类,具体类应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程

依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等

为了确保该原则的应用,一个具体类应当只实现接口或抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法。

里氏代换原则LSP(Liskov Substitution Principle)

所有引用基类对象的地方能够透明地使用其子类的对象,子类可以替代父类,由于子类的可替代性才使得父类的模块在无需修改的情况下就可以拓展。

里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立。

里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

接口隔离原则ISP(Interface Segregation Principle)

使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口

一个类对另外一个类的依赖是建立在最小的接口上。尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法。要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

在使用接口隔离原则时,我们需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护。接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。

迪米特原则LKP(Least Knowledge Principle)

一个软件实体应当尽可能少地与其他实体发生相互作用,强调降低类之间的耦合性

如果一个系统符合迪米特法则,那么当其中某一个模块发生修改时,就会尽量少地影响其他模块,扩展会相对容易。若两个类不必直接通信,那么这两个类就不应该发生直接的相互作用。若其中一个类需要调用另一个类的某个方法时,可以通过第三方转发调用。

类之间的耦合性越低,越有利于复用,一个弱耦合的类被修改,不会对与其有关系的类造成很大的影响。

合成聚合复用原则CARP(Composite/AggregateReuse Principle)

尽量使用组合/聚合代替继承,有助于保持类的封装及单一职责,且使得类和类的继承层次会保持较小的规模。

聚合是一种“弱”拥有关系:A可以包含B,但B不是A的一部分,合成则是一种“强”拥有关系:A是B的一部分,A与B的生命周期一致。

在使用继承时,一定要在是“is-a"的关系时再考虑使用。

设计模式的分类

创建型模式(Creational Pattern)

创建型模式主要用于描述如何创建对象,它的主要特点是将对象的创建与使用分离,为了使结构更加清晰,外界对于这些对象只需要知道它们共同的接口,而不清楚其具体的实现细节,使整个系统的设计更加符合单一职责原则。

创建型模式包括:

简单工厂模式(Simple Factory Pattern)

专门定义一个类(工厂类)来负责创建其他类的实例。可以根据创建方法的参数来返回不同类的实例,被创建的实例通常都具有共同的父类。

工厂方法模式(Factory Method Pattern)

工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,即通过不同的工厂子类来创建不同的产品对象。

抽象工厂模式(Abstract Factory Pattern)

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

建造者模式(Builder Pattern)

它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

单例模式(Singleton Pattern)

单例模式确保某一个类只有一个实例,并提供一个访问它的全剧访问点。

原型模式

使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。

结构型模式(Structural Pattern)

结构型模式主要用于描述如何实现类或对象的组合,就像搭积木,可以通过简单积木的组合形成复杂的、功能更为强大的结构。

结构型模式可以分为类结构型模式和对象结构型模式:

  • 类结构型模式关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。
  • 对象结构型模式关心类与对象的组合,通过关联关系使得在一 个类中定义另一个类的实例对象,然后通过该对象调用其方法。

结构型模式包括:

装饰者模式(Decorator Pattern)

不改变原有对象的前提下,动态地给一个对象增加一些额外的功能。

外观模式(Facade Pattern)

外观模式定义了一个高层接口,为子系统中的一组接口提供一个统一的接口。

代理模式(Proxy Pattern)

为某个对象提供一个代理,并由这个代理对象控制对原对象的访问。

享元模式(Flyweight Pattern)

运用共享技术复用大量细粒度的对象,降低程序内存的占用,提高程序的性能。

桥接模式(Bridge Pattern)

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

适配器模式(Adapter Pattern)

将一个接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

组合模式(Composite Pattern)

将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性。

行为型模式(Behavioral Pattern)

行为型模式主要用于描述类或对象怎样交互以及怎样分配职责。行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。通过行为型模式,可以更加清晰地划分类与对象的职责,并研究系统在运行时实例对象之间的交互。

行为型模式包括:

职责链模式(Chain of Responsibility Pattern)

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

命令模式(Command Pattern)

将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。

解释器模式(Interpreter Pattern)

定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。

迭代器模式(Iterator Pattern)

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

中介者模式(Mediator Pattern)

定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。

备忘录模式(Memento Pattern)

在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

观察者模式(Observer Pattern)

定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

状态模式(State Pattern)

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

策略模式(Strategy Pattern)

该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。

模板方法模式(Template Method Pattern)

定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

访问者模式(Visitor Pattern)

提供一个作用于某对象结构中的各元素的操作表示,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

参考资料

分类

开发
    --go (9)
    --java (5)
    --php (11)
    --mysql (9)
    --javascript (3)
    --html (1)
    --算法 (6)
架构
    --理论 (9)
    --网络 (3)
    --服务器 (2)
    --消息队列 (3)
    --容器 (5)
    --监控 (1)
    --搜索引擎 (3)
    --大数据 (0)
    --测试 (1)
系统
    --linux (10)
    --mac (2)
    --windows (1)
足球
    --世界杯 (60)
    --欧洲杯 (28)
    --文迷 (3)
大学时光
    --校园生活 (96)
    --假期生活 (17)
    --广院杯那些事 (14)
    --北京奥运 (6)
    --胡思乱写 (17)


最近发布

零拷贝技术介绍

服务网格技术简介

C语言标准和标准库简介

Kubernetes简介及环境搭建

Go语言开发的顶级项目


归档

2006 (109)
2007 (40)
2008 (47)
2009 (10)
2010 (6)
2012 (10)
2013 (14)
2014 (27)
2015 (15)
2016 (6)
2017 (8)
2018 (11)
2019 (17)
2020 (5)