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 ...
随机推荐
- 2015-2016-2《Java程序设计》团队博客2
简易画图板介绍 一.功能结构图 二.主类设计 1.总体设计:在设计简易画图板时,根据程序功能的分类,包含了十二个文件,包括SimpleDraw.java,MenuContainer.java,Dra ...
- 在mybatis中写sql语句的一些体会
本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...
- 剑指offer:扑克牌顺子
题目描述: LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他 ...
- service和Dao层有什么关系
Dao层:主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类 ...
- mysql用户添加执行存储过程权限
- Intellij idea 告警:'while' statement cannot complete without throwing an exception
有时候这个告警是多余的,例如我们手写的监控线程. 如果有消除告警强迫症.在线程的执行方法上加入注解. @SuppressWarnings("InfiniteLoopStatement&quo ...
- EOS测试链智能合约部署调用
ETH与EOS两者智能合约进行简单的对比. 1.编译智能合约(合约编译成.wasm与.abi格式后即可部署到区块链) [root@C03-12U-26 testcontract]# cat testc ...
- CentOS 7镜像下载
官网下载链接:http://isoredirect.centos.org/centos/7/isos/x86_64/ step1: 进入下载页,选择阿里云站点进行下载 Actual Country ...
- js知识体系
- SpringBoot @Autowired中注入静态方法或者静态变量
注:用static去定义一个注入的方法或者配置文件值变量,编译时不会有任何异常,运行时会报空指针. Spring官方不推荐此种方法. 原理: https://www.cnblogs.com/chenf ...