本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8287784.html,记录一下学习过程以备后续查用。

写代码也是有原则的,我们之所以使用设计模式,主要是为了适应变化,提高代码复用率,使软件更具有可维护性和可扩展性。如果我们能更好的理

解这些设计原则,对我们理解面向对象的设计模式也是有帮助的,因为这些模式的产生是基于这些原则的。

设计原则包括:单一职责原则(SRP)、开闭原则(OCP)、里氏替换原则(LSP)、依赖倒置原则(DIP)、接口隔离原则(ISP)、合成复用原

则(CRP)、迪米特法则(LoD)。

下面我们就分别介绍这七种设计原则:

一、单一职责原则(SRP)

1)SRP(Single Responsibilities Principle)的定义:就一个类而言,应该仅有一个引起它变化的原因。简而言之,就是功能要单一。

2)如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其它职责的能力。这种耦合会导致

脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。(敏捷软件开发)

3)软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。

小结:单一职责原则(SRP)可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的

原因。责任过多,引起它变化的原因就越多,这样就会导致职责依赖,大大损伤其内聚性和耦合度。

二、开闭原则(OCP)

1)OCP(Open-Close Principle)的定义:就是说软件实体(类、方法等等)应该可以扩展(扩展可以理解为增加),但是不能在原来的方法或者类上修

改,也可以这样说,对增加代码开放,对修改代码关闭。

2)OCP的两个特征: 对于扩展(增加)是开放的,因为它不影响原来的,这是新增加的。对于修改是封闭的,如果总是修改,逻辑会越来越复杂。

小结:开闭原则(OCP)是面向对象设计的核心思想。遵循这个原则可以为我们面向对象的设计带来巨大的好处:可维护(维护成本小、做管理简

单、影响最小)、可扩展(有新需求,增加就好)、可复用(不耦合,可以使用以前代码)、灵活性好(维护方便、简单)。开发人员应该仅对程序中

出现频繁变化的那些部分做出抽象(但是不能过激,对应用程序中的每个部分都刻意地进行抽象同样也不是一个好主意,拒绝不成熟的抽象和抽象本身

一样重要)。

三、里氏替换原则(LSP)

1)LSP(Liskov Substitution Principle)的定义:子类型必须能够替换掉它们的父类型。更直白的说,LSP是实现面向接口编程的基础。

小结:任何基类可以出现的地方,子类一定可以出现,所以我们可以实现面向接口编程。 LSP是继承复用的基石,只有当子类可以替换掉基类,软件

的功能不受到影响时,基类才能真正被复用,而子类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充,实现开闭原则的关键步

骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

里氏替换原则的经典反例:正方形不是长方形、玩具枪不能杀人、鸵鸟不会飞。

四、依赖倒置原则(DIP)

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

编程。

2)高层模块不应该依赖低层模块,两个都应该依赖抽象,因为抽象是稳定的。抽象不应该依赖具体(细节),具体(细节)应该依赖抽象。

小结:依赖倒置原则其实可以说是面向对象设计的标志,如果在我们编码的时候考虑的是面向接口编程,而不是简单的功能实现,体现了抽象的稳定

性,只有这样才符合面向对象的设计。

五、接口隔离原则(ISP)

1)接口隔离原则(Interface Segregation Principle, ISP)指的是使用多个专门的接口比使用单一的总接口要好。也就是说不要让一个单一的接口承担

过多的职责,而应把每个职责分离到多个专门的接口中,进行接口分离,过于臃肿的接口是对接口的一种污染。

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

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

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

5)“不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,再通俗点说,不要强迫客户使用它们

不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。

小结:接口隔离原则(ISP)告诉我们,在做接口设计的时候,要尽量设计的接口功能单一,功能单一,使它变化的因素就少,这样就更稳定。其实这

体现了高内聚、低耦合的原则,这样做也避免接口的污染。

六、合成复用原则(CRP)

1)组合复用原则(Composite Reuse Principle, CRP)就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分,新对象通过向这些

对象的委派达到复用已用功能的目的。简单地说,就是要尽量使用合成/聚合,尽量不要使用继承。

2)要使用好组合复用原则,首先需要区分”Has--A”和“Is--A”的关系。“Is--A”是指一个类是另一个类的“一种”,是属于的关系,而“Has--A”则不同,它表

示某一个角色具有某一项责任。导致错误的使用继承而不是聚合的常见的原因是错误地把“Has--A”当成“Is--A”。例如:鸡是动物,这就是“Is-A”的表现,

某人有一支手枪,People类型里面包含一个Gun类型,这就是“Has-A”的表现。

小结:合成复用原则可以使系统更加灵活,类与类之间的耦合度降低,一个类的变化对其他类造成的影响相对较少,因此一般首选使用合成来实现复

用;其次才考虑继承,在使用继承时,需要严格遵循里氏替换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统构

建和维护的难度以及系统的复杂度,因此需要慎重使用继承复用。

七、迪米特法则(Law of Demeter)

1)迪米特法则(Law of Demeter,LoD)又叫最少知识原则(Least Knowledge Principle,LKP),指的是一个对象应当对其他对象有尽可能少的了

解。也就是说,一个模块或对象应尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立,这样当一个模块修改时,影响的模块就会越少,

扩展起来更加容易。

2)关于迪米特法则其他的一些表述有:只与你直接的朋友们通信,不要跟“陌生人”说话。

3)外观模式(Facade Pattern)和中介者模式(Mediator Pattern)就使用了迪米特法则。

小结:迪米特法则的初衷是降低类之间的耦合,实现类型之间的高内聚、低耦合,这样可以解耦。但是凡事都有度,过分的使用迪米特原则,会产生

大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。

设计原则博文推荐:https://www.cnblogs.com/ckka/p/11432413.html

C#设计模式学习笔记:设计原则的更多相关文章

  1. java设计模式学习笔记--接口隔离原则

    接口隔离原则简述 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应建立在最小的接口上 应用场景 如下UML图 类A通过接口Interface1依赖类B,类C通过接口Interface1依赖类 ...

  2. java设计模式学习笔记--单一职责原则

    单一职责原则注意事项和细节 1.降低类的复杂度,一个类只负责一项职责 2.提高可读性,可维护性 3.降低变更引起的风险 4.通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单 ...

  3. Java设计模式学习笔记(二) 简单工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...

  4. Java设计模式学习笔记(三) 工厂方法模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...

  5. Java设计模式学习笔记(四) 抽象工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...

  6. Java设计模式学习笔记(五) 单例模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 使用单例模式的原因 以Windows任务管理器为例,在Windows系统中,任务管理器是唯 ...

  7. 7 种 Javascript 常用设计模式学习笔记

    7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...

  8. C#设计模式学习笔记:(3)抽象工厂模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7596897.html,记录一下学习过程以备后续查用. 一.引言 接上一篇C#设计模式学习笔记:简单工厂模式( ...

  9. C#设计模式学习笔记:(2)工厂方法模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7567880.html,记录一下学习过程以备后续查用. 一.引言 接上一篇C#设计模式学习笔记:简单工厂模式( ...

  10. 设计模式学习笔记--备忘录(Mamento)模式

    写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方式,这就是软件模式:每个模式描写叙述了一个在我们程序设计中常常发生的问题,以及该问题的解决方式:当我们碰到模 ...

随机推荐

  1. [PowerShell]Python虚拟环境激活失败

    用Activate.ps1激活还是失效的情况下, 用ISE打开发现路径中的中文乱码了. 所以解决方案有两种, 一是把中文路径改成英文 二是把Activate.ps1脚本用记事本打开另存为ANSI编码即 ...

  2. python批量删除子文件夹中的空子文件夹

    例如A文件夹下有许多子文件夹,我需要获得的是子文件夹中的图片,但是现在子文件夹中不光有图片,还混入了空的文件夹(在使用OpenImages工具箱的时候,按照检索的方式下载的图片文件中是带有label的 ...

  3. ugligy 转

    3.配置gulpfile.js 3.1.基本使用 JavaScript 1 2 3 4 5 6 7 8 var gulp = require('gulp'),     uglify = require ...

  4. zip压缩包伪加密技术

    一个 ZIP 文件由三个部分组成: 压缩源文件数据区 + 压缩源文件目录区 + 压缩源文件目录结束标志 压缩源文件数据区: 50 4B 03 04:这是头文件标记(0x04034b50) 14 00: ...

  5. Java面试题之“==”和“equals()”方法的区别?

    一.“== ”:运算符 1.可以使用在基本数据类型变量和引用数据类型变量中. 2.如果比较的是基本数据类型变量:比较的是两个变量保存的数据是否相等.(不一定类型要相同) 3.如果比较的是引用数据类型变 ...

  6. 07-SpringMVC01

    今日知识 1. SpringMVC入门 2. SpringMVC的注解开发 SpringMVC入门 1. 简介: * Spring MVC是Spring提供的一个强大而灵活的web框架.借助于注解,S ...

  7. React中ref的使用

    直接获取DOM元素时使用的,一般情况下尽量不要使用ref

  8. js 细节

    1.js中var a=s=1和var a=1,s=1的区别 function fl() { ; } function fl1() { , s = ; } 看出问题所在了吗? var q=w=1 中的s ...

  9. C语言基础二 练习

    指出正确标识符 命名 l 只能由26个英文字母的大小写.10个阿拉伯数字0~9.下划线_组成 l 严格区分大小写,比如test和Test是2个不同的标识符 l 不能以数字开头 l 不可以使用关键字作为 ...

  10. C#设计模式学习笔记:(21)访问者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8135083.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第九个模式--访 ...