—-慢慢来比较快,虚心学技术—-

设计模式简介

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

分字诀

道生一,一生二,二生三,三生万物

七大设计原则

23种设计模式的总纲领,23种设计模式正是为了满足这七大设计原则而产生的

单一职责原则(Single Responsibility Principle,SRP;又称单一功能原则)

官方**:**一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分

解释**:每个类、每个方法、每个框架都只负责一件事**

优点**:**代码可读性高,可重用性高

示例应用场景**:**方法体内应该是同一级别,抽象统一抽象,细节统一细节

里氏替换原则(Liskov Substitution Principle,LSP)

官方**:**继承必须确保超类所拥有的性质在子类中仍然成立。

解释**:任何能使用父类对象实现的地方,都应该能够透明的替换成子类对象,即子类对象能够随时随地替换父类对象且替换完以后语法不会报错,业务逻辑也不会有问题。**里氏替换原则象化的具体步骤的规范。

优点**:**克服了继承中重写父类造成的可复用性变差的缺点,

示例应用场景**:**继承(子类方法的访问修饰符不可以比父类严格,子类方法抛出的异常不可以比父类的更多,这是为了满足里氏替换原则,子类透明替换父类)

依赖倒置原则(Dependence Inversion Principle,DIP)

官方**:**上(高)层模块不应该依赖下(低)层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象

解释**:要面向接口编程,不要面向实现编程

上(高)层:调用对象的模块,如A调用B的demo方法,A为上(高)层

下(低)层:提供对象的模块,如A调用B的demo方法,B为下(低)层

面向实现编程:上(高)层调用下(低)层,上层依赖于下(低)层,当下(低)层剧烈变动时上(高)层也要跟着变动,这就会导致模块的复用性降低而且大大提高了开发的成本

面向接口编程**:上(高)层调用下(低)层实现的接口,下(低)层依赖于接口,当下(低)层剧烈变动时上(高)层无需变动,因为上(高)层调用的是接口抽象,而不是实体细节。

优点**:降低类之间的耦合性,提高系统稳定性,提高代码可读性**

示例应用场景**:**A初始调用B的demo方法,后续需求变更可能调用C的demo方法,D的demo方法…….,此时如果去更改A的方法,将会违反开闭原则,同时A的代码冗余,所以应该让A依赖于B,C,D的统一接口I,而不是直接依赖于BCD

开闭原则(Open Closed Principle,OCP)

官方**:**软件实体应当对扩展开放,对修改关闭

解释**当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。
对扩展新功能开放,对修改原功能关闭**(如要某个类的某个方法符合新的需求,不应该去改该类的原代码使其失去原有功能,而是应该新建子类继承该类并重载该方法,调用该方法即可),比如,有时候我们手头并没有拿到源码,只是拿到了某些类的字节码文件(如mysql driver包),而要进行定制开发则无法改变该类的代码,只能进行继承重载

优点**:**提高代码可重用性,提高代码可维护性,便于测试(扩展后只需要测试扩展的部分,而原有代码依旧正常运行)

示例应用场景**:**扩展源码功能

注**:尽量别改别人的源代码,而应该去扩展,因为你不知道改的那部分会引起什么样的影响**

迪米特法则(Law of Demeter,LoD,又叫最少知道原则,Least Knowledge Principle,LKP)

官方**:**一个对象应当对其他对象有尽可能少的了解,不和陌生人说话(Talk only to your immediate friends and not to strangers)(只和朋友通信,对朋友可以有深入的了解)

解释**:**如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。实质就是封装,比如人对于电脑的关机操作,不需要知道里面到底是怎么执行的,执行顺序如何,只需要点击关机按钮即可,关机按钮(方法)由电脑封装提供。
什么是朋友?
- 类中的成员
- 方法的参数
- 方法的返回值
- 方法中实例化出来的对象

优点**:**降低类之间的耦合度,提高模块的相对独立性

缺点**:**可能多了很多小方法,只是作为中间传递,而与业务逻辑无关

示例应用场景**:封装,门面模式和中介者模式**

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

官方**:**客户端不应该被迫依赖于它不使用的方法 一个类对另一个类的依赖应该建立在最小的接口上

解释**:**使用多个专门的接口,比使用一个总接口要好,避免一个类实现它并不需要实现的方法

优点**:**提高系统灵活性和可维护性,多个专门接口体现对象的层次,减少代码冗余,提高可读性

示例应用场景**:**一个接口只服务于一个子模块或业务逻辑。如用户操作接口应该只服务于用户操作,而不应该包含其他服务的操作

组合优于继承原则(Composition/Aggregate Reuse Principle,CARP;组合/聚合复用原则)

官方**:**要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现

解释**:什么是组合(这里说的是关联,即什么是关联)?
类的关系分为三种:继承、依赖和关联,关联指的是两个分开的类通过对象或实例建立的关系,如A和B两个类,B作为A中的成员变量存在
其中,关联可以分为两种:组合与聚合
聚合:代表了has-a的关系,是一种单向关系,而且一个实例的存在不会影响另一个实例的存在。如公寓里面可以有学生,但是学生里面不可以有公寓
组合:代表了part-of的关系,实例是彼此依赖的,一个实例的存在必定依赖于另一个实例的存在。如鸟与翅膀的关系

为什么组合(关联)由于继承?
继承的弊端:破坏了类的封装性,因为继承会暴露父类的细节给子类;子类与父类的耦合度高,父类的任何改变都会影响到子类;
如:现有A类为父类,B类继承A类并重写了A类的方法,一来如果有其他类调用了A类的方法,则B可能撼动了A类的业务逻辑稳定;而来如果将来A类增加或减少某些实现方法,则B类也要随之改变以适应需求,十分不利于维护。
组合的优点:维持了类的封装性,因为旧类作为成员存在于新类中,新类并不了解旧类的细节
新旧类之间的耦合度较低,因为任何旧类的更改都不会直接影响到新类的实现,新旧类之间的沟通仅仅是通过调用新类的方法调用

示例应用场景**:自己不是旧类的作者(无法控制类的未来变化)时,尽量不要使用继承,如果自己是旧类的作者,则可随意使用继承和组合
JDK中的反面教材:Stack类

23种设计模式

设计模式前言 - 图1

如有贻误,还请评论指正