设计模式六大原则

简介: 设计模式六大原则

上篇文章说了工厂模式的单例模式和创建模式,单例模式如何在懒加载的情况下保证线程安全性,创建模式通过接口和抽象类,来完成开闭原则。

创建型模式--设计模式详解?


单一职责原则,开闭原则,里氏替换原则,依赖导致原则,接口隔离原则,迪米特原则。


一、单一职责原则(single responsibility principleSRP


定义:一个类只负责一个功能领域中相应的职责,或者定义为,就一个类而言,应该只有一个引起他变化的原因。


问题原因是类A有两个不同职责方法,当修改其中一个的时候导致其他方法出现问题。


单一职责就是实现高内聚、低耦合的知道方针,当一个类里承担的责任越多,他被复用的可能性就越小,因此要将一些职责分离,将不同的职责封装在方法或者类里。发现类的职责需要设计人员较强的分析能力和相关经验。


需不需要拆分,取决于是否会发生变化,如果修改其中一个职责,不影响其他职责,则不需要拆分,否则则需要拆分。


所以SRP单一职责不光使用与接口和类,也适用于方法。


优点:

1、降低类的复杂度,逻辑比负责多项职责简单。

2、提高类的高复用性。

3、风险降低,修改一个职责的时候,影响范围更小。


二、开闭原则(open-closed principleOCP


定义:一个软件实体应当对扩展开放,对修改关闭。在不修改的情况下可以扩展。


问题原因是因为任何一个需求不可能一成不变,随着时间的推进,业务会增加,这时候再增加新的需求时候,不能影响以前的需求,导致以前的需求不可用。


为了满足开闭原则,需要对系统进行抽象化设计,这是开闭原则的关键。当需要扩展的时候,只需要实现这个抽象类即可,无需对抽象类进行任何改动,实现不修改已有代码的基础进行扩展。


当代码有很多ifelse的时候,可以建立一个抽象的基类,然后如果有新的可以增加,则只需要增加集成的子类即可,不需要改变原有的代码。


优点:

1、开闭原则非常有名,只要是面向对象编程,都会有开闭原则。

2、当如同上面的抽象设计之后,开闭原则大大提高了复用性,在面向对象编程中,所有逻辑都是从原子逻辑组合而来的,而不是在一个类中独立实现的一套业务逻辑。逻辑的颗粒度越小,则越可以考虑复用。

3、提高系统的维护性和扩展性,当维护人员去维护系统的时候,更多的是希望扩展一个类,而不是修改原有的代码。

4、万物皆对象,我们把所有的事物抽象成对象,然后针对对象操作。设置之初尽可能考虑到所有场景,这需要开发人员的全局掌握和工作经验。


如何使用开闭原则呢?


通过抽象来约束,

1、通过接口或者抽象类来约束,对扩展进行边界限定,不允许出现抽象类不存在的public方法。

2、参数引用对象尽量使用接口或者抽象类,而不是实现类,这主要是里氏替换原则,后面会详细介绍。

3、抽象类必须保证稳定,确定后就不要修改。


三、里氏替换原则(Liskov Substutution Principle,LSP


定义:所有引用基类的地方必须透明的使用其子类对象。


继承优点:减少代码工作量,提高代码重用性,子类可以形似父类,但异于父类,提高可扩展性。


继承缺点:继承有侵入性,当父类代码修改过后,必须要考虑是否影响到其他子类的职责是否会异常,缺乏代码规范的情况下,这时候会造成大量的重构改动。


如何克服上面的缺陷,于是里氏替换原则。


里氏替换原则告诉我们,软件中将一个基类替换成它的子类对象,不会有任何异常,但如果把子类替换成基类,则不成立的,因为子类有很多属于自己的其他东西。


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


使用需要注意几点:

1、子类所有方法必须在父类中声明,或者子类必须实现父类中声明的所有方法。为了保证程序扩展性,在程序中通常用父类来定义,如果一个方法只存在子类,则肯定不可以用父类来调用。

2、我们在运用时候,尽量把基类设置成接口或者抽象类,当需要扩展的时候,只需要新增集成的子类,不需要修改原有的代码。


四、依赖倒置原则(Dependence inversion principleDIP


定义:需要面向接口编程,而不是面向实现,高层模块和底层模块不应该依赖,而是依赖抽象,抽象不应该依赖细节,细节依赖抽象。


依赖倒置原则是我们在程序代码传递参数关联时,尽量引用高层次的抽象类,为了确保这一原则,所以具体类应该只实现接口或者抽象类存在的方法,否则都发通过接口来调用子类新增的方法。


引用接口和抽象类,系统更具有灵活性,这样一来,系统发生变化,在抽象类或者接口进行扩展。


实现依赖倒置我们需要DI依赖注入的方式,常用的有构造函数注入和接口注入。


优点:

1、降低系统耦合度。

2、减少并行的风险。

3、提高代码可读性和维护性。

用的时候,子类的所有方法必须在父类中有,这也就是必须遵循里氏替换原则,尽量把父类设计成接口或者抽象类,或者都有。


五、接口隔离原则(interface segregation principle ISP


定义:使用多个专门的接口,不使用单一总接口,客户端不应该依赖那些不需要的接口。


当一个接口太大的时候,我们需要将它分割成一些更细小的接口,客户端仅仅需要知道相关的方法即可。每个接口承担独立的角色。这里的接口有两层定义,一种是类具有的方法和特征,逻辑上的接口隔离。一种是某种语言定义的接口,如java interface接口。


如果是第一种,则ISP代表着角色隔离接口,根据不同的业务逻辑来区分。


如果是第二种,理解成语言的接口,那么ISPD代表为客户端提供的行为。在面向对象语言中,实现一个接口就要实现该接口所有方法,所以应该尽可能小的提供接口。


优点:

1、将臃肿的接口拆分为小的,提高可复用性和可维护性。

2、降低了接口系统的耦合性。

3、如果接口的颗粒度合理,则可以保证系统的稳定性,如果定义太小会造成接口数多。

4、减少代码冗余量。


六、迪米特法则(law of demeter lod


定义:一个软件实体尽可能少的与其他实体发生相互作用。


该定义是由一个迪米特的研究项目来命名的,一个对象只能与直接朋友发生交互,不要与陌生人直接发生交互,这样可以做到降低系统耦合度,改变则不会影响其他对象。


比如项目中每个功能尽可能的不要相互依赖,而是去使用某个功能的时候,才去调用用到它。


优点:

1、降低类之间的耦合度,提高独立性。

2、进而又提高了复用性和扩展性。


但是在使用的时候会出现很多中介类,从而使系统更加复杂,所以需要反复衡量。


单一职责让我们的类各司其职,职责单一,里氏替换告诉我们优化继承体系,依赖倒置是面向接口编程,通过构造函数等其它方式注入,接口隔离告诉我们设计接口要单一,迪米特告诉我们要解耦,最后达到我们的开闭原则,遵循扩展开发,修改关闭。

相关文章
|
4月前
|
设计模式
设计模式七大原则
这篇文章介绍了设计模式中的七大原则,特别强调了单一职责原则,即一个类应该只有一个引起其行为变化的原因,以确保类功能的高内聚和低耦合。
|
4月前
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
6月前
|
设计模式 供应链
设计模式六大原则之迪米特法则
设计模式六大原则之迪米特法则
|
6月前
|
设计模式
设计模式六大原则之依赖倒置原则
设计模式六大原则之依赖倒置原则
|
3月前
|
设计模式 Java 关系型数据库
设计模式——设计模式简介和七大原则
设计模式的目的和核心原则、单一职责原则、接口隔离原则、依赖倒转原则、里氏替换原则、开闭原则、迪米特法则、合成复用原则
设计模式——设计模式简介和七大原则
|
4月前
|
设计模式 算法 开发者
设计模式问题之最小知识原则(迪米特法则)对代码设计有何影响,如何解决
设计模式问题之最小知识原则(迪米特法则)对代码设计有何影响,如何解决
|
4月前
|
设计模式 前端开发 JavaScript
React开发设计模式及原则概念问题之什么是HOC(Higher-order component),HOC遵循的设计原则都有哪些
React开发设计模式及原则概念问题之什么是HOC(Higher-order component),HOC遵循的设计原则都有哪些
|
4月前
|
设计模式 前端开发 JavaScript
React开发设计模式及原则概念问题之什么是设计模式,单一职责原则如何理解
React开发设计模式及原则概念问题之什么是设计模式,单一职责原则如何理解
|
6月前
|
设计模式 uml
设计模式学习心得之前置知识 UML图看法与六大原则(下)
设计模式学习心得之前置知识 UML图看法与六大原则(下)
46 2
|
6月前
|
设计模式 Java 数据库
深入理解设计模式六大原则
深入理解设计模式六大原则