设计模式原则

设计模式原则,其实就是程序员在编程时,应当遵守的原则,
也是各种设计模式的基础(即:设计模式为什么这样设计的依据)
设计模式常用的七大原则有:

  1. 单一职责原则
  2. 接口隔离原则
  3. 依赖倒转(倒置)原则
  4. 里氏替换原则
  5. 开闭原则
  6. 迪米特法则
  7. 合成复用原则

一、单一职责原则

一个类尽量只负责一个功能
1、目的
降低代码复杂度、降低系统耦合度、提高可读性

2、定义
对于一个类,只有一个引起该类变化的原因;该类的职责是唯一的,且这个职责是唯一引起其他类变化的原因。

3、具体实现
将不同的职责封装到不同的类或者模块中,当有新的需求将现有的职责分为颗粒度更小的职责的时候,应该及时对现有代码进行重构。

4、优点
(1)降低类的复杂度,一个类只负责一个职责。这样写出来的代码逻辑肯定要比负责多项职责简单得多。

(2)提高类的可读性,提高系统的可维护性。

(3)降低变更引起的风险。变更是必然的,如果单一职责原则遵守得好,当修改一个功能的时候可以显著降低对其他功能的影响。

5、注意事项和细节
(1)降低类的复杂度,一个类只负责一项职责;

(2)提高类的可读性,可维护性;

(3)降低变更引起的风险;

(4)通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单、才可以在代码级违反单一职责原则,只有类中的方法足够少,才可以在类中保持方法级别的单一职责原则。

二、接口隔离原则

实现类尽量减少不必要的实现,可以把接口分开
1、目的
避免接口过于臃肿

2、定义
客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上。

3、具体实现
适度细化接口,将臃肿的接口拆分为独立的几个接口。

4、优点
(1)将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。

(2)接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性。

(3)使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义。

(4)能减少项目工程中的代码冗余。过大的大接口里面通常放置许多不用的方法,当实现这个接口的时候,被迫设计冗余的代码。

5、注意事项和细节
如果接口的粒度大小定义合理,能够保证系统的稳定性;但是,如果定义过小,则会造成接口数量过多,使设计复杂化;如果定义太大,灵活性降低,无法提供定制服务,给整体项目带来无法预料的风险。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CEjfqrHx-1663766499022)(imgs/Pasted%20image%2020220917122600.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TKzxRaVt-1663766499023)(imgs/Pasted%20image%2020220917122619.png)]

三、依赖倒转原则

对于依赖关系,尽量使用接口或抽象类
1、目的
避免需求变化导致过多的维护工作

2、定义
高层模块不应该依赖底层模块,二者都应该依赖其抽象;
抽象不应该依赖细节;
细节应该依赖抽象。
每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块(一般是接口,抽象类),原子逻辑的组装就是高层模块。在Java语言中,抽象就是指接口和或抽象类,两者都不能被直接实例化。细节就是实现类,实现接口或继承抽象类而产生的类就是细节,可以被直接实例化。

3、具体实现
面向接口编程,使用接口或者抽象类制定好规范和契约,而不去设计任何具体的操作,把展现细节的任务交给他们的实现类去完成。

4、DIP的好处
采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。

5、DIP的几种写法
(1)接口声明依赖对象;

(2)构造函数传递依赖对象;

在类中通过构造函数声明依赖对象(好比spring中的构造器注入),采用构造器注入。

(3)Setter方法传递依赖对象

在抽象中设置setter方法声明依赖对象(spring中的方法注入)

6、深入理解
依赖倒转原则的本质就是通过抽象使各个类或模块实现彼此独立,不互相影响,实现模块间的松耦合。

在项目中使用这个规则需要以下原则:

(1)每个类尽量都要有接口或抽象类:依赖倒转的基本要求,有抽象才能依赖倒转;

(2)变量的表明类型尽量是接口或者抽象类;

(3)任何类都不应该从具体类派生;

(4)尽量不要重写基类已经写好的方法(里氏替换原则);

(5)结合里氏替换原则来使用:

接口负责定义public属性和方法,并且声明与其他对象的依赖关系;

抽象类负责公共构造部分的实现;

实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化;

一句话,依赖倒转原则就是面向接口编程。

四、里氏替换原则

尽量子类不重写父类的方法,如果重写的太多,可以让子类和父类都继承一个超类
1、目的
避免系统继承体系被破坏

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

3、具体实现
(1)子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法;

(2)子类可以增加自己特有的方法;

(3)当子类覆盖或实现父类的抽象方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松;方法的后置条件(即方法的返回值)要比父类更严格。

(4)如果子类不能完整地实现父类的方法,或者父类的一些方法在子类中已经发生畸形,则建议断开继承关系,采用依赖,聚合,组合等关系继承。

五、开闭原则

可以增加一个类,但是尽量不要修改一个类
可以修改一个类,但是尽量不要影响原来调用它的类
1、目的
提高扩展性、便于维护

2、定义
对扩展开放(对提供方),对修改关闭(对使用方)。

当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现。

开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统,开闭原则只定义了对修改关闭,对扩展开放。

因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保证架构的稳定。而软件中易变的细节,我们用从抽象派生的实现类来进行扩展,当软件需要发生变化时,我们只需要根据需求重新派生一个实现类来扩展就可以了,当然前提是抽象要合理,要对需求的变更有前瞻性和预见性。

六、迪米特法则

局部变量尽量不要出现不再方法声明中的陌生类
1、目的
降低类与类之间的耦合度

2、定义
迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好,对于依赖的类不管有多复杂,都尽量将逻辑封装在类的内部,对外除了提供public方法,不泄漏任何信息。

更简单的说法:只与直接朋友通信。

直接朋友:每个对象都会与其它对象有耦合关系,耦合的方式有很多,依赖、关联、组合、聚合等。我们称出现在成员变量,方法参数,方法返回值中的类称为直接朋友,而出现在局部变量中的类不能称为直接朋友,也就是说,陌生的类不要以局部变量的形式出现在类的内部。

3、注意事项和细节
(1)在类的结构设计上,尽量降低类成员的访问权限;

(2)在类的设计上,优先考虑将一个类设计成不变类;

(3)在类的引用上,将引起其他类的次数降到最低;

(4)不暴露类的属性成员,而应该提供相应的访问器(getter、setter);

(5)谨慎使用序列化(serializable)功能;

过分的使用迪米特原则,会产生大量这样的中介和传递类,类之间需要通信就通过第三方转发的方式,就会造成系统的不同模块之间的通信效率降低、使系统的不同模块之间不容易协调等缺点,同时大大增加了系统的复杂度。所以在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。

七、合成复用原则

尽量使用聚合不要使用继承
1、目的
防止类的体系庞大

2、定义
它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

如果要使用继承关系,则必须严格遵循里氏替换原则。合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。

3、注意事项和细节
(1)通常的复用分为继承复用和合成复用,继承复用虽然有简单和易实现的优点,但它也有如下的缺点:

继承复用破坏了类的封装性
因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为“白箱”复用。

子类和父类的耦合度高
父类的改变会直接影响子类,不利于类的扩展和维护。

限制了复用的灵活性
从父类继承而来的实现是静态的,在编译时已经定义,运行时无法发生变化。

(2)采用组合或聚合复用时,可以将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能,它有以下优点。

维护了类的封装性
因为成分对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。

低耦合
这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口。

复用的灵活性高
这种复用可以在运行时动态进行,新对象可以动态地引用与成员对象类型相同的对象。

【设计模式】设计模式的七大原则相关推荐

  1. 设计模式常用的七大原则总结

    设计模式常用的七大原则: 单一职责原则 在方法上(方法很少,逻辑足够简单)或类上遵守单一职责原则都可以. 可以降低类的复杂性 接口隔离原则 客户端不应该依赖他不需要的接口,即一个类对另一个类的依赖应该 ...

  2. Java设计模式---设计模式概述及七大原则

    网课指路:尚硅谷Java设计模式(图解+框架源码剖析)_哔哩哔哩_bilibili 设计模式介绍         1) 设计模式是程序员在面对同类软件工程设计问题所总结出来的有用的经验, 模式不是代码 ...

  3. 设计模式-软件架构设计七大原则及开闭原则详解

    前言 在日常工作中,我们使用Java语言进行业务开发的时候,或多或少的都会涉及到设计模式,而运用好设计模式对于我而言,又是一个比较大的难题.为了解决.克服这个难题,Remi酱特别开了这个博客来记录自己 ...

  4. 大话设计模式之设计模式遵循的七大原则

    最近几年来,人们踊跃的提倡和使用设计模式,其根本原因就是为了实现代码的复用性,增加代码的可维护性.设计模式的实现遵循了一些原则,从而达到代码的复用性及增加可维护性的目的,设计模式对理解面向对象的三大特 ...

  5. 设计模式-软件设计七大原则

    目录 综述 1.开闭原则 1.1开闭原则的定义 1.2开闭原则的作用 1.3开闭原则的实现方法 2.里氏替换原则 2.1里氏替换原则的定义 2.2里氏替换原则的作用 2.3里氏替换原则的实现方法 3. ...

  6. 设计模式中的七大原则(代码 + 图解)

    文中涉及的代码:链接:提取码:tqjq 文章目录 设计模式 1. 目的 2. 分类 3. 原则 3.1单一职责原则 3.2 接口隔离原则 3.3 依赖倒转原则 3.4 里氏替换原则 3.5 开闭原则 ...

  7. java设计模式——浅显易懂之七大原则

    大家好,我是老王.一名正在学java设计模式的大三学生.准备连载java设计模式系列供自己以后复习和大家学习讨论.由于本人是初学者,站的角度更多是它是什么,我们要怎么做的角度进行思考,有出错的地方欢迎 ...

  8. 设计模式常用的七大原则

    1) 单一职责原则 2) 接口隔离原则 3) 依赖倒转原则 4) 里氏替换原则 5) 开闭原则 ocp 6) 迪米特法则 7)  合成复用原则 设计模式的目的 编写软件过程中,程序员面临着来自 耦合性 ...

  9. 设计模式(5)之七大原则之开闭原则

    一.定义 开闭原则(Open Closed Principle,OCP)由勃兰特·梅耶(Bertrand Meyer)提出,他在 1988 年的著作<面向对象软件构造>(Object Or ...

  10. 设计模式系列之七大原则之——迪米特法则

    ①一个对象应该对其他对象保持最少的了解 ②类与类关系越密切,耦合度越大 ③迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好(对于一类被依赖的类,不管是多么复杂,对外只提供方法即可,不去 ...

最新文章

  1. linux0.11内核编译,编译Linux-0.11内核
  2. 云计算机基地有辐射吗,服务器机房有辐射大吗
  3. namespace命名空间的理解C++
  4. 编译错误 fatal error C1010: unexpected end of file while looking for precompiled header directive
  5. 贝塞尔曲线 java_贝塞尔曲线理论及实现——Java篇
  6. ROS笔记(37) 抓取和放置
  7. 大咖说中台 | 中台不是“银弹”!
  8. MYSQL主从不同步延迟原理分析及解决方案
  9. matlab 纹理映射
  10. “没有足够的可用内存来运行此程序”怎么解决
  11. 关于投资收益和风险的例题(线性规划)
  12. 传统算法与神经网络算法,神经网络是谁提出的
  13. c mysql_stmt游标移动_MySql数据库--stmt语句(续)
  14. 网易云音乐8.0版本背后的野心
  15. 多通道声源定位方法之GCC-PHAT:原理及matlab实现
  16. iQQ 基于WebQQ3.0协议Java开发 跨平台QQ客户端
  17. 护理疑难病例讨论PPT模板
  18. 第1次作业:调查市场软件
  19. Meet The Greeks
  20. Educational Codeforces Round 124 (Rated for Div. 2)

热门文章

  1. Nodejs+vue网上鲜花店销售信息系统express+mysql
  2. FPN (特征金字塔) 的原理和代码
  3. 线上会议竞品调研报告
  4. 密码加盐(salt)
  5. 跨国药企在中国 | 京东健康与卫材成立合资公司;西门子医疗、富士胶片参展中国国际医疗器械展...
  6. 查找自己电脑上的空闲端口号
  7. SW3518快充方案
  8. 【已解决】PyLaTeX 编译中文出现乱码
  9. 苹果手机上的python编程软件-Python编程软件有哪些?
  10. 【leetcode刷题】找到需补充粉笔的学生编号