js 的七大原则--单一原则、开闭原则、替换原则(一)
一.前言:
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 的七大原则--单一原则、开闭原则、替换原则(一)的更多相关文章
- C#软件设计——小话设计模式原则之:开闭原则OCP
前言:这篇继续来看看开闭原则.废话少说,直接入正题. 软件设计原则系列文章索引 C#软件设计——小话设计模式原则之:依赖倒置原则DIP C#软件设计——小话设计模式原则之:单一职责原则SRP C#软件 ...
- 六大设计原则(二)LSP里氏替换原则
里氏替换原则LSP(Liskov Subsituation Principle) 里氏替换原则定义 所有父类出现的地方可以使用子类替换并不会出现错误或异常,但是反之子类出现的地方不一定能用父类替换. ...
- ZT 设计模式六大原则(2):里氏替换原则
设计模式六大原则(2):里氏替换原则 分类: 设计模式 2012-02-22 08:46 23330人阅读 评论(41) 收藏 举报 设计模式class扩展string编程2010 肯定有不少人跟我刚 ...
- 【设计模式六大原则6】开闭原则(Open Close Principle)
定义:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 问题由来:在软件的生命周期内,因为变化.升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不 ...
- 【面向对象设计原则】之开闭原则(OCP)
开闭原则是面向对象设计的一个重要原则,其定义如下: 开闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开放,对修改关闭.即软件实体应尽量在不修改原有代码的情况下进 ...
- 面向对象设计原则二:开闭原则(OCP)
开闭原则(OCP)定义:对扩展开发,对修改关闭.好处: 适应性和灵活性. 稳定性和延续性. 可复用性与可维护性. 解释说明:开闭原则指的是两方面:对功能扩展开发,对修改进 ...
- 设计模式六大原则(2):里氏替换原则(Liskov Substitution Principle)
肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.事实上原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:假设对每 ...
- Java设计模式(1:软件架构设计七大原则及开闭原则详解)
前言 在日常工作中,我们使用Java语言进行业务开发的时候,或多或少的都会涉及到设计模式,而运用好设计模式对于我而言,又是一个比较大的难题.为了解决.克服这个难题,笔主特别开了这个博客来记录自己学习的 ...
- 第2章 面向对象的设计原则(SOLID):6_开闭原则
6. 开闭原则(Open Closed Principle,OCP) 6.1 定义 (1)一个类应该对扩展开放,对修改关闭.要求通过扩展来实现变化,而且是在不修改己有的代码情况下进行扩展,也不必改动己 ...
- [设计模式]<<设计模式之禅>>关于开闭原则
开闭原则是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的.灵活的系统,先来看开闭原则的定义: Software entities like classes,modules and fun ...
随机推荐
- ldap和phpldapadmin的安装部署
LDAP 安装 一.安装LDAP 1. 安装包 yum install openssl-devel gcc libtool-ltdl-devel -y yum install openldap-ser ...
- [转]Maven 全局配置文件settings.xml详解
原文地址:https://www.jianshu.com/p/110d897a5442 概要 settings.xml有什么用? 如果在Eclipse中使用过Maven插件,想必会有这个经验:配置se ...
- [转]使用 curl 发送 POST 请求的几种方式
HTTP 的 POST 请求通常是用于提交数据,可以通过这篇文章来了解各种提交方式:四种常见的 POST 提交数据方式.做 Web 后端开发时,不可避免地要自己给自己发请求来调试接口,这里要记录的内容 ...
- 【Linux】使用 walle + docker-compose 部署上线单获取不到分支的解决办法
背景: 使用walle+docker 自动化部署项目.在新建上线单时候拉取不到分支,并提示有错误.但是没有错误信息 错误排查: 首先确保远程仓库已添加宿主机公钥,且一定先在宿主机手动连接一下远程仓库, ...
- Please enable using preview .net core sdks
工具=>选项=>环境=>预览功能=>使用.net core sdk的预览
- clipboard 在 vue 项目中,on 事件监听回调多次执行
clipboard 定义一个全局变量 import ClipboardJS from "clipboard"; if(clipboard){ clipboard.destroy() ...
- 【linux基础】Ubuntu16.04桌面突然卡住怎么办?
使用Ctrl+Alt+F1先进入命令行模式,然后根据问题进行相应的操作. re 1. Ubuntu16.04桌面突然卡住怎么办; 2. Ubuntu下图形界面卡死解决办法; end
- Eclipse安装Properties Editor插件
安装步骤 1.打开eclispe编辑器help-->install new soft 2.输入软件地址 name:properties editor Location:http://proped ...
- Deploy != Release(第一部分):部署与发布的区别,以及为什么这很重要
原文地址:http://ju.outofmemory.cn/entry/351873 翻译自: Deploy != Release (Part 1): The difference between d ...
- testNG的安装
1,testNG介绍 TestNG ( Testing Next Generation ,下一代测试技术) testNG的强大之处在于它是 利用注释(注解) 来强化测试功能的测试框架,可以用来做接口测 ...