一、 设计原则概述
设计模式中主要有六大设计原则,简称为SOLID ,是由于各个原则的首字母简称合并的来(两个L算一个,solid 稳定的),六大设计原则分别如下:
1、单一职责原则(Single Responsibitity Principle)
2、开放封闭原则(Open Close Principle)
3、里氏替换原则(Liskov Substitution Principle)
4、接口分离原则(Interface Segregation Principle)
5、依赖倒置原则(Dependence Inversion Principle)
6、迪米特法则(Law Of Demter)
软件开发中我们要基于这六个原则,设计建立稳定、灵活、健壮的程序。
二、设计原则分
2.1 单一职责
单一职责原则的定义描述非常简单,也不难理解。一个类只负责完成一个职责或者功能。
也就是说在类的设计中 我们不要设计大而全的类,而是要设计粒度小、功能单一的类.
比如 我们设计一个类里面既包含了用户的一些操作,又包含了支付的一些操作,那这个类的职责就不够单一,应该将该类进行拆分,拆分成多个功能更加单一的,粒度更细的类.
2.2 开闭原则
定义:对扩展开放,对修改关闭
对扩展开放和对修改关闭表示当一个类或一个方法有新需求或者需求发生改变时应该采用扩展的方式而不应该采用修改原有逻辑的方式来实现。因为扩展了新的逻辑如果有问题只会影响新的业务,不会影响老业务;而如果采用修改的方式,很有可能就会影响到老业务受影响。
开闭原则是所有设计模式的最核心目标,也是最难实现的目标,但是所有的软件设计模式都应该以开闭原则当作标准,才能使软件更加的稳定和健壮。
优点:
-
新老逻辑解耦,需求发生改变不会影响老业务的逻辑
-
改动成本最小,只需要追加新逻辑,不需要改的老逻辑
-
提供代码的稳定性和可扩展性
2.3 里氏替换原则
如何理解里氏替换原则?
要理解里氏替换原则,其实就是要理解两个问题:
- 什么是替换?
- 什么是与期望行为一致的替换(Robert Martin所说的“必须能够替换”)?
1 ) 什么是替换 ?
替换的前提是面向对象语言所支持的多态特性,同一个行为具有多个不同表现形式或形态的能力。
以JDK的集合框架为例,
List
接口的定义为有序集合,List
接口有多个派生类,比如大家耳熟能详的ArrayList
,LinkedList
。那当某个方法参数或变量是List
接口类型时,既可以是ArrayList
的实现, 也可以是LinkedList
的实现,这就是替换。
2 ) 什么是与期望行为一致的替换?
在不了解派生类的情况下,仅通过接口或基类的方法,即可清楚的知道方法的行为,而不管哪种派生类的实现,都与接口或基类方法的期望行为一致。
不需要关心是哪个类对接口进行了实现,因为不管底层如何实现,最终的结果都会符合接口中关于方法的描述(也就是与接口中方法的期望行为一致).
或者说接口或基类的方法是一种契约,使用方按照这个契约来使用,派生类也按照这个契约来实现。这就是与期望行为一致的替换。
2.4 接口隔离原则
要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。
接口隔离原则与单一职责原则的区别
接口隔离原则和单一职责都是为了提高类的内聚性、降低它们之间的耦合性,体现了封装的思想,但两者是不同的:
- 单一职责原则注重的是职责,而接口隔离原则注重的是对接口依赖的隔离。
- 单一职责原则主要是约束类,它针对的是程序中的实现和细节;接口隔离原则主要约束接口,主要针对抽象和程序整体框架的构建。
2.5 依赖倒置原则
依赖倒置原则是实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。
- 高层级的模块应该依赖的是低层级的模块的行为的抽象,取决于具体编程语言,可以是抽象类或者接口等技术;
- 第2句话其实很简单,只有一个意思:只要依赖了实现,就是耦合了代码,所以我们需要始终依赖的是抽象,而不是实现。
-
传统的自定向下的设计
传统设计方式采用自顶向下的原则, 逐级依赖,中层模块和高层模块的耦合度很高,如果需要修改其中的一个模块,则可能会导致其它很多模块也需要修改,牵一发动全身,不易于维护。
不使用依赖反转的系统构架,控制流和依赖关系流的依赖箭头是一个方向的,由高层指向底层,也就是高层依赖底层
-
依赖倒置原则
依赖倒置原则的好处:
- 减少类间的耦合性,提高系统的稳定性 . (根据类与类之间的耦合度从弱到强排列:依赖关系、关联关系、聚合关系、组合关系、泛化关系和实现关系 )
- 降低并行开发引起的风险 (两个类之间有依赖关系,只要制定出两者之间的接口(或抽象类)就可以独立开发了)
- 提高代码的可读性和可维护性
2.6 迪米特法则
大部分设计原则和思想都非常抽象,有各种各样的解读,要想灵活地应用到 实际的开发中,需要有实战经验的积累。迪米特法则也不例外。
简单来说迪米特法则想要表达的思想就是: 不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口。
如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。