一.前言:

js 的七大设计原则:

1.单一原则

2.开闭原则

3.里氏替换原则

4.依赖倒转原则

5.接口隔离原则

6.合成复用原则

7.迪米尔法则

二.单一原则

1.定义:单一原则就是一个对象或者一个方法,只做一件事。

比如,目前公司的前端框架,如下图:在src中api只是做接口层,assets里面是公共的方法,components是用来放组件的,里面的base和business分别存放的是基础组件和业务组件,mixins是用来存放混入的东西的。store文件时用来放vuex中的东西的,style文件是用来存放样式的。每个文件都有各自的职责,也都只负责一件事情。这就符合单一职责的。

遵循单一职责的优点:

1.可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多。

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

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

三.开闭原则

尽量通过扩展软件实体来解决需求变化,而不是通过修改已有的代码来完成变化。

一个软件产品的生命周期内,都会发生变化,既然变化是一个既定的事实,我们就应该在设计的时候,尽量的适应这些变化。以提高项目的稳定性和灵活性。

四.里氏替换原则

严格的定义:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序p在所有的对象o1都换成o2的时候,程序p的行为没有变化,那么类型T2就是类型T1的子类型。

通俗的定义:所有引用基类的地方必须能透明地使用其子类的功能。

更通俗的定义:子类可以扩展父类的功能,但是不能改变父类原有的功能。

首先来看一个例子,看它是否满足“里氏替换”的原则

//定义一个矩形类

class Rectangle {
constructor() {
this.width=;
this.height=;
}
setWidth(width) {
this.width = width
}
setHeight(height) {
this.height = height
}
getArea() {
return this.width * this.height
}
} //定义一个正方形类,继承于矩形类
class Square extends Rectangle {
constructor() {
super();
}
setWidth(width) {
this.width = width;
this.height = width;
}
setHeight(height) {
this.height = height
this.width = height
}
}
// 执行的方法
function result(rectangles) {
rectangles.forEach((rectangle) => {
rectangle.setHeight()
rectangle.setWidth()
let area = rectangle.getArea()
console.log('area', area)
})
}
let rectangles = [new Rectangle(), new Rectangle(), new Square()];
result(rectangles) //结果是20 ,20, 16

在我当初看到这个代码的时候,我的疑惑点在于为什么正方形求面积是16。其实,仔细看一下上面的代码,我们会发现,其实他是没有遵循“里氏替换”的原则的。因为正方形的类继承了矩形的类,但是它在实现的时候改写了矩形的类。这样子,如果我们将子类替换成父类的时候,结果就是不成功的。所以,里氏替换原则包含以下4层含义:

1.子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象的方法。

2.子类可以增加自己独有的方法

3.当子类覆盖或者实现父类的时候,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。

4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

上面的例子,在正方形的类中的setHeight方法不仅仅改变了height,还改变了width,当功能扩展的时候,子类尽量不要去重写父类的方法,而是另写一个方法。

五.依赖倒置原则

定义:高层模块不应该依赖于 低层模块,二者都应该依赖其抽象;抽象不应该依赖于细节,细节应该依赖于抽象。

怎么理解上面的话呢?

类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

在这里面类A就相当于高层模块,类B和类C就相当于低层模块。所以现在的业务逻辑是不满足“依赖倒置”原则的。为了满足“依赖倒置”的原则,其实,我们应该有一个抽象类o,然后类b,类c是o的实现,然后类A通过o简介与类B,类c 创建联系,这样,就大大降低了修改类A的几率了。

依赖倒置原则基于这样一个事实:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。在Java中,抽象指的是接口或者抽象类,细节就是具体的实现类。使用接口或者抽象类的目的是制定好规范和契约,而不去设计任何具体的操作,把展现细节的任务交给她们的实现类去完成。

六.接口隔离原则

每一个接口都是一个角色,客户端不应该依赖于他不需要的接口。也就是说,一个类对另一个类的依赖应该建立在最小的接口上。

应该把每一个接口都细化,针对类去设计接口。如果一个接口中有 太多的方法,而对很多类来说里面的很多方法都是用不到的,那么,另外的类在实现这个接口时就要实现很多对它来说没用的方法,浪费人力物力。对一个类来说,实现很多它都能用得上的专用接口总比让它实现一个臃肿而又有很多它用不上的方法要来的划算。

采用接口隔离的原则,需要注意以下几点:

1.接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不争的事实,但是,如果过小,则会造成接口数量过多,使得设计复杂化。所以,一定要适度。

2.为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制的服务,才能建立最小的依赖关系。

3.提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

4.运用接口隔离原则,一定要适度。接口设计过大或过小都不好。

七.合成/聚合复用原则

聚合表示一种弱的“拥有”的关系,体现的是A对象可以包含B对象,但是B对象不是A对象的一部分;合成则是一种强的“拥有”的关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。

优先使用对象的合成/聚合将有助于保持每个类的封装,并被几种在单个任务上。这样类和类继承层次会保持较小的规模,并且不太可能增长到不可控制的庞然大物上。

八.迪米特法则

也叫最小知识原则,一个对象应该对其他对象有尽可能少的了解。

总结:

单一职责原则告诉我们实现类要职责单一;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合。而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。

js 的七大原则--单一原则、开闭原则、替换原则(一)的更多相关文章

  1. C#软件设计——小话设计模式原则之:开闭原则OCP

    前言:这篇继续来看看开闭原则.废话少说,直接入正题. 软件设计原则系列文章索引 C#软件设计——小话设计模式原则之:依赖倒置原则DIP C#软件设计——小话设计模式原则之:单一职责原则SRP C#软件 ...

  2. 六大设计原则(二)LSP里氏替换原则

    里氏替换原则LSP(Liskov Subsituation Principle) 里氏替换原则定义 所有父类出现的地方可以使用子类替换并不会出现错误或异常,但是反之子类出现的地方不一定能用父类替换. ...

  3. ZT 设计模式六大原则(2):里氏替换原则

    设计模式六大原则(2):里氏替换原则 分类: 设计模式 2012-02-22 08:46 23330人阅读 评论(41) 收藏 举报 设计模式class扩展string编程2010 肯定有不少人跟我刚 ...

  4. 【设计模式六大原则6】开闭原则(Open Close Principle)

      定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 问题由来:在软件的生命周期内,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不 ...

  5. 【面向对象设计原则】之开闭原则(OCP)

    开闭原则是面向对象设计的一个重要原则,其定义如下: 开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修改关闭.即软件实体应尽量在不修改原有代码的情况下进 ...

  6. 面向对象设计原则二:开闭原则(OCP)

    开闭原则(OCP)定义:对扩展开发,对修改关闭.好处:      适应性和灵活性.      稳定性和延续性.      可复用性与可维护性. 解释说明:开闭原则指的是两方面:对功能扩展开发,对修改进 ...

  7. 设计模式六大原则(2):里氏替换原则(Liskov Substitution Principle)

    肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.事实上原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:假设对每 ...

  8. Java设计模式(1:软件架构设计七大原则及开闭原则详解)

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

  9. 第2章 面向对象的设计原则(SOLID):6_开闭原则

    6. 开闭原则(Open Closed Principle,OCP) 6.1 定义 (1)一个类应该对扩展开放,对修改关闭.要求通过扩展来实现变化,而且是在不修改己有的代码情况下进行扩展,也不必改动己 ...

  10. [设计模式]<<设计模式之禅>>关于开闭原则

    开闭原则是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的.灵活的系统,先来看开闭原则的定义: Software entities like classes,modules and fun ...

随机推荐

  1. Java 自定义异常

    新建类CustomException继承 Exception /** * Create by on 2019-07-30 * 自定义类需要继承Exception * @author lsw */ pu ...

  2. uniapp - 关于调试跨域

    [] 1.右键Chrome图标 2.选中属性(R) 3.在目标(T) chrome.exe后添加 --disable-web-security --user-data-dir --allow-runn ...

  3. 上传图片 展示进度条 bootstrap

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <title>Bo ...

  4. mongo 笔记

    mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options ...

  5. EasyNVR摄像机网页H5全平台无插件直播流媒体播放服务二次开发之接口鉴权示例讲解

    背景需求 EasyNVR的使用者应该都清楚的了解到,EasyNVR一个强大的功能就是可以进行全平台的无插件直播.主要原因在于rtsp协议的视频流(默认是需要插件才可以播放的)经由EasyNVR处理可以 ...

  6. 【SSH进阶之路】Spring的AOP逐层深入——AOP的基本原理(六)

    经过我们对Spring的IOC不断的深入学习,Spring的面貌逐渐变得清晰,我们对Spring的了解也更加的深入.从这篇博文开始我们学习Spring的第二大核心内容:AOP. 什么是AOP AOP( ...

  7. smb文件共享

    一.服务端: #安装 yum install samba samba-common samba-client -y systemctl start smb ##开启samba服务 systemctl ...

  8. ProtoStuff无法反序列化Deprecated注解成员问题记录

    在开发过程中,遇到一个鬼畜的问题,在DO的某个成员上添加@Deprecated注解之后,通过ProtoStuff反序列化得到的DO中,这个成员一直为null:花了不少时间才定位这个问题,特此记录一下 ...

  9. SpringBoot 的拦截器

    首先注册我们要有完整的一个可以开始的开发环境 先自己创建一个配置类 InterceptorConfig, 实现springboot自带的拦截器接口 WebMvcConfigurer. package ...

  10. DHCP的配置方法

    1.实验拓扑图: 2.配置命令: AR2: <Huawei>system-view[Huawei]dhcp enable      #开启DHCP服务[Huawei]interface G ...