面向对象设计模式5大基本原则

article/2025/10/28 21:41:41

 “宇宙万物之中,没有一样东西能像思想那么顽固。”        一爱默生

首先明确模式是针对面向对象的,它的三大特性,封装、继承、多态。

面向对象设计模式有5大基本原则:单一职责原则、开发封闭原则、依赖倒置原则、接口隔离原则、Liskov替换原则。

而设计模式都是在面向对象的特性以及5大基本原则的基础上衍生而来的具体实现。

1、单一职责原则(SRP)

  1.1,SRP(Single Responsibilities Principle)的定义:就一个类而言,应该仅有一个引起它变化的原因。简而言之,就是功能要单一。
  1.2,如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其它职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。(敏捷软件开发)
  1.3,软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。(敏捷软件开发)

小结:

单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。职责过多,可能引起它变化的原因就越多,这样导致职责依赖,相互之间就会产生原因,大大损伤其内聚性和耦合度。

2、开放-封闭原则(OCP):

  2.1,OCP(Open-Close Principle)的定义:就是说软件实体(类,方法等等)应该可以扩展,但是不能修改。它是软件设计中也是最重要的一种设计原则。
  2.2,OCP的两个特征:
    2.2.1> 对于扩展是开放的。
    2.2.2> 对于修改是封闭的。

  2.3,什么时候应用OCP原则呢?
    在我们最初编写代码时,假设变化不会发生,当变化发生时,我们就创建抽象(比如抽象类,接口等等)来隔离以后发生的同类变化。
  2.4,开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护,可扩展,可复用,灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。
  2.5,OCP的UML图:

 

小结:

开放封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处:可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样也不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。“需求总是变化”没有不变的软件,所以需要用开放封闭原则来封闭变化满足需求,同时还能保持软件内部的封装体系稳定,不被需求的变化影响。

3、依赖倒转原则(DIP):

  3.1,DIP(Dependence Inversion Principle)的定义:抽象不应该依赖细节,细节应该依赖于抽象。简单说就是,我们要针对接口编程,而不要针对实现编程。

           3.1. 1 高层模块不应该依赖低层模块。两个都应该依赖抽象。

           3.1.2 抽象不应该依赖具体(细节)。具体(细节)应该依赖抽象。


  3.2、反面例子UML图:

      
  缺点:高层模块太依赖低层模块,耦合太紧密。低层模块发生变化会影响到高层模块。
  解决方法:利用依赖倒置原则使高层模块和低层模块都依赖于抽象(接口或抽象类)。
  3.3、修改后的UML图如下:
  
  优点:这样的话修改低层模块不会影响到高层模块,减小了它们之间的耦合度,增强系统的稳定性。

小结:

依赖倒置原则其实可以说是面向对象设计的标志,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了。

4、接口隔离原则:

使用多个专门的接口比使用单一的总接口要好。

一个类对另外一个类的依赖性应当是建立在最小的接口上的。

一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。

“不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,再通俗点说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。

 小结:

接口隔离的方法有两种(分享客户就是分离接口):
1、使用委托(此委托非.net委托[delegate])分离接口
使用委托即,创建一个委托类,用此类去实现分离后的其它接口中的方法。
2、使用多重继承分离接口、
此方法,即将现有“胖”接口分成供不同客户程序调用的两个或多个接口,而需要实现多个接口的客户程序,则使用多重继承来实现。

5、Liskov(里氏)替换原则(LSP)

5.1,LSP(Liskov Substitution Principle)的定义:子类型必须能够替换掉它们的父类型。简单地说,这是因为子类型继承了父类,所以子类可以以父类的身份出现。

  实例UML图:

 

小结:

任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

补充:

迪米特法则(LoD):

     自从我们接触编程开始,就知道了软件编程的总的原则:低耦合,高内聚。无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率。低耦合的优点不言而喻,但是怎么样编程才能做到低耦合呢?那正是迪米特法则要去完成的。

迪米特法则又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出。通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

   1,LoD(Law of Demeter)的定义:如果两个类不必彼此直接通信,那么这两个类就不应当直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

   2,在类的结构设计上,每一个类都应当尽量降低成员的访问权限,也就是说,一个类包装好自己的private状态,不需要让别的类知道的字段或行为(方法)就尽量不要公开。

定义:一个对象应该对其他对象保持最少的了解。

问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

解决方案:尽量降低类与类之间的耦合。

举例:有一个集团公司,下属单位有分公司和直属部门,现在要求打印出所有下属单位的员工ID。先来看一下违反迪米特法则的设计。

现在这个设计的主要问题出在CompanyManager中,根据迪米特法则,只与直接的朋友发生通信,而SubEmployee类并不是CompanyManager类的直接朋友(以局部变量出现的耦合不属于直接朋友),从逻辑上讲总公司只与他的分公司耦合就行了,与分公司的员工并没有任何联系,这样设计显然是增加了不必要的耦合。按照迪米特法则,应该避免类中出现这样非直接朋友关系的耦合。

修改后,为分公司增加了打印人员ID的方法,总公司直接调用来打印,从而避免了与分公司的员工发生耦合。

小结:

迪米特法则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免与非直接的类通信,但是要通信,必然会通过一个“中介”来发生联系,例如本例中,总公司就是通过分公司这个“中介”来与分公司的员工发生联系的。过分的使用迪米特原则,会产生大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。


http://chatgpt.dhexx.cn/article/jP4Icwuw.shtml

相关文章

面向对象六大设计原则

目录 1 、单一职责(Single Responsibility Principle) 2 、开闭原则(Open Close Principle) 3、里氏替换原则(Liskov Substitution Principle) 4、接口隔离原则(Interface Segregation Prin…

阿里巴巴编码规范解读(六、七)-工程结构及设计规约

工程结构 应用分层 1.【推荐】 图中默认上层依赖于下层,箭头关系表示可直接依赖,如:开放接口层可以依赖于 Web层,也可以直接依赖于 Service层,依此类推。 开放接口层:可直接封装 Service 方法暴露成RPC…

面向对象设计的七大设计原则详解

面向对象的七大设计原则 文章目录 面向对象的七大设计原则简述七大原则之间的关系 一、开闭原则(The Open-Closed Principle ,OCP)概念理解系统设计需要遵循开闭原则的原因开闭原则的实现方法一个符合开闭原则的设计开闭原则的相对性 二、 里…

Android Binder机制简述

一、Android binder是什么? Android平台上的一种跨进程通信(IPC)机制 从OpenBinder演化而来 从Android应用层角度来说,Binder是客户端和服务端进行通信的媒介 二、IPC原理 每个Android进程,只能运行在自己的进程所…

不得不说的Android Binder机制与AIDL

说起Android的进程间通信,想必大家都会不约而同的想起Android中的Binder机制。而提起Binder,想必也有不少同学会想起初学Android时被Binder和AIDL支配的恐惧感。但是作为一个Android开发者,Binder是我们必须掌握的知识。因为它是构架整个Andr…

FrameWork-进程间通信之Binder机制AIDL

进程间通信之Binder机制 Binder是什么?为什么要使用Binder?Binder原理Binder使用实战 1、Binder是什么 Binder 是一种进程间通信机制,基于开源的 OpenBinder 实现;OpenBinder 起初由 Be Inc. 开发,后由 Plam Inc. 接…

Android 应用是如何启动 binder 机制的?

文章目录 应用是什么时候支持 binder 机制的应用大致启动流程是什么总结问题 应用是什么时候支持 binder 机制的 binder 都知道是用来做跨进程服务的,应用内可以通过binder 跟系统组件进行交互。如 AMS Service aidl 等那么可以思考一下,当 Activity on…

Android Binder机制介绍

转载于:http://www.cnblogs.com/zc9527/p/5638688.html 备注:该博客简单介绍类型的 做过Android开发的同学可能有些体会,入门初期,工作内容主要是实现各式各样的UI界面,以及实现应用的业务逻辑。在这个阶段&#xff0c…

Android跨进程通信Binder机制与AIDL实例

文章目录 进程通信1.1 进程空间划分1.2 跨进程通信IPC1.3 Linux跨进程通信1.4 Android进程通信 Binder跨进程通信2.1 Binder简介2.2 Binder驱动2.3 Binder原理 AIDL编程Demo3.1 服务端3.2 客户端 在操作系统中,进程与进程间的内存和数据都是不共享的。这样做的目的&…

Android-Binder机制

Binder机制是什么: Binder机制是​ Android系统中进程间通讯(IPC)的一种方式,Android中ContentProvider、Intent、aidl都是基于Binder。 为什么要用Binder机制: 在提及Binder之前,我们先看看我们平时开发…

深入理解Binder机制

Binder框架 Binder是什么 1.Binder是一种进程间通信机制; 2.Binder是一个虚拟物理设备驱动; 3.Binder是一个能发起通信的Java类; Binder与传统IPC对比 Binder共享内存Socket性能内存拷贝一次无需拷贝内存拷贝两次特点基于C/S架构 易用性高…

Android Binder机制原理

一 Android与Linux通信机制的比较 虽然Android继承使用Linux的内核,但Linux与Android的通信机制不同。 在Linux中使用的IPC通信机制如下: 1.管道(Pipe):点对点通信,因为采用存储转发方式,需要拷…

Android——Binder机制

1.简介 Binder是什么? 机制:Binder是一种进程间通信的机制 驱动:Binder是一个虚拟物理设备驱动 应用层:Binder是一个能发起进程间通信的JAVA类 Binder就是Android中的血管,在Android中我们使用Activity,Service等组…

Android Binder机制之一(简介)

目录 前言 一、Android 进程间通信方式 二、Binder架构图 三、Binder涉及角色 3.1 Binder驱动 3.2 Binder实体 3.3 Binder引用 3.4 远程服务 3.5 ServiceManager守护进程 四、涉及源码 前言 这是本人第N次看Binder 相关知识了,其实每次看都有新的收获&…

binder机制原理android,Binder机制1---Binder原理介绍

1.Binder通信机制介绍 这篇文章会先对比Binder机制与Linux的通信机制的差别,了解为什么Android会另起炉灶,采用Binder。接着,会根据 Binder的机制,去理解什么是Service Manager,在C/S模型中扮演什么角色。最后&#x…

理解Binder机制

前言 ​ Android中Binder机制的重要性不言而喻,从IPC角度来看, Binder是一种跨进程通信方式,Binder也可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder;从Android framework角度来说,Binder是Serv…

Android--Binder机制

Android--Binder机制 1.简介 Binder是什么? 机制:Binder是一种进程间通信的机制 驱动:Binder是一个虚拟物理设备驱动 应用层:Binder是一个能发起进程间通信的JAVA类 Binder就是Android中的血管,在Android中我们使用…

Binder 机制

Binder 是 Android 系统进程间通信(IPC:Internet Process Connection)方式之一。Linux 已经拥有的 IPC 手段包括: 管道(Pipe)、信号(Signal)、跟踪(Trace)、插…

Android Binder机制

Android Binder机制 什么是BinderBinder一般的IPC原理动态内核可加载模块内存映射运行机制四大角色注册服务使用服务 对象的传递Binder通信 什么是Binder 要理解binder,先要知道IPC,Inter-process communication ,也就是进程中相互通信,Bind…

Binder机制

直观来讲,Binder是Android中的一个类,它实现了IBinder接口。从IPC角度来看,Binder是Android中一种跨进程通信方式,Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder,该通信方式在Linux中没…