设计模式中的设计原则之单一职责原则(Single Responsibility Principle - SRP)
2018-05-15 21:45
507 查看
1、what
只有一个引起它变化的原因,应该只有一个职责适用于方法、类、包、模块,对于前端更多用在方法和对象上面
2、why
易于维护降低耦合
提高内聚
减少脆弱:一个地方修改导致其他地方不可预期的后果
组织代码更容易
代码改变更容易
解释:拿方法举例。如果一个方法承担了过多的职责,在需求变迁的过程中改动这个方法的可能性就会变大。那么,这个方法就是一个不稳定的方法。修改代码总是一件危险的事情,特别是两个职责耦合在一起的时候。一个职责发生变化可能会影响到其他职责的实现,造成意想不到的破坏。这是一种低内聚和脆弱的设计。
易于复用
易于调试
易于测试
3、如何识别SRP被破坏
类有太多依赖类的构造器有太多参数,意味着测试有太多依赖,需要制造mock太多测试输入参数,通常意味着已经破坏SRP了。
方法有太多参数
类似类的构造器,方法参数意味着依赖。
测试类变得复杂
如果测试有太多变量,意味着这个类有太多职责。
类或方法太长
如果方法太长,意味着内容太多,职责过多。 一个类不超过 200-250
描述性名称
如果你需要描述你的类 方法或包,比如使用"xxx和xxx"这种语句,意味着可能破坏了SRP.
低聚合Cohesion的类
聚合Cohesion是一个很重要的概念,虽然聚合是有关结构概念,但是聚合和SRP非常相关,如前面论坛案例,如果一个类不代表一个高聚合,意味着低凝聚low Cohesion,它就可能意味破坏SRP。一个低凝聚的特点: 一个类有两个字段,其中一个字段被一些方法使用;另外一个字段被其他方法使用。
在一个地方改动影响另外一个地方
如果在一个代码地方加入新功能或只是简单重构,却影响了其他不相关的地方,意味着这个地方代码可能破坏了SRP.
猎枪效果Shotgun Effect
如果一个小的改变引起一发动全身,这意味SRP被破坏了。
不能够封装模块
比如使用Spring框架,你使用@Configuration or XML 配置,如果你不能在一个配置中封装一个Bean。意味着它有太多职责,Spring配置应该隐藏内部bean,暴露最少接口,如果你因为多个原因需要改变Spring配置,可能破坏了SRP.
4、SRP与模式(使用广泛)
单一职责与代理//图片的加载 未引入代理模式 var delayLoad = (function () { var myImg = document.getElementById('img'); myImg.src = './loading.gif'; var newImg = document.createElement('img'); newImg.onload = function () { myImg.src = newImg.src; } return function (src) { newImg.src = src; } })(); delayLoad('./download.jpeg'); //为了扩展性考虑,我们可以参考单一职责原则,修改如下: var delayLoad = (function () { var myImg = document.getElementById('img'); return { setSrc: function (src) { myImg.src = src; } } })(); var proxy = (function () { var newImg = document.createElement('img'); newImg.onload = function () { delayLoad.setSrc(newImg.src); } return { setSrc: function (src) { delayLoad.setSrc('./loading.gif'); newImg.src = src; } } })(); proxy.setSrc('./download.jpeg');
单一职责与节点渲染(加入迭代器模式)
向后台请求相关的数据,然后将数据渲染到页面
var data = { img:"http://7xpsmd.com1.z0.glb.clouddn.com/16-1-24/19756676.jpg", title:"JS权威指南", author:"David Flaagan" } http.getBooks = function(url,callback){ $.ajax(url) .then((data)=>{ itera(data,callback); }) } //要知道,这里的data可能不只一个,我们需要进行遍历 var itera = function(data,callback){ for(var i = 0,book;book = data[i++];){ callback(data); //渲染data } } //请求数据,并且渲染数据 http.getBooks("www.example.com",function(){ console.log("渲染数据"); });
从大的方面来看,职责确实只有两个,但是我们实现的时候,会发现,本体中嵌套一个for循环,会把添加节点函数带入,这样耦合性会增大,所以这里加了一个迭代器模式,让迭代器来表示循环,即,我的渲染函数只和迭代器发生关系,而你原来的ajax请求是怎么实现的我并不清楚。
单一职责与获取单例
//将单例类和获取单例的工厂分开来 //工厂可以无限制使用,单例类也可以执行他独特的行为 var Weather = function() {} var getSingle = (function() { var single; return function(obj) {//传入构造函数更好,但是要多判断 if (single === undefined) { return single = obj; } return single; } })(); var weather1 = getSingle(new Weather()); //原始的Weather var weather2 = getSingle(new Weather()); //存储的single //这个是缓存一个功能函数的结果,应用场景主要在加载额外的模板文件时使用 var getSingle = function(fn){ var result; return function(){ return result || (result = fn.apply(this,arguments)); } }
单一职责与AOP(面向切面编程)
AOP我们应该算是阅人无数的级别了, 在很多地方都是用过他,职责链模式,装饰者模式等。
而AOP也是完美体现SRP原则的。
Function.prototype.before = function (fn) { var _self = this; return function () { fn.apply(this, arguments);//保证this不被劫持 return _self.apply(this, arguments); } } Function.prototype.after = function (fn) { var _self = this; return function () { var ret = _self.apply(this, arguments); fn.apply(this, arguments); return ret; } }
5、如何运用SRP原则
this is sometimes hard to see
一方面受设计原则的指导,一方面未必要在任何时候一成不变的遵守原则。
可能方便性与稳定性之间要有一个取舍。
6、SRP的优缺点
最明显的是增加了编写代码的复杂度。按照职责把对象分解成更小的粒度之后,实际上也是增大了这些对象之间相互联系的难度。
参考:
设计模式之六大设计原则https://www.jianshu.com/p/15edb371c0b5
《JavaScript设计模式与开发实践》曾探著 Alloy Team
相关文章推荐
- IOS设计模式的六大设计原则之单一职责原则(SRP,Single Responsibility Principle)
- IOS设计模式的六大设计原则之单一职责原则(SRP,Single Responsibility Principle)
- 设计模式六大原则—— 单一职责原则(SRP,Single Responsibility Principle)
- [设计模式原则]单一职责原则(Single Responsibility Principle,SRP)
- IOS设计模式的六大设计原则之单一职责原则(SRP,Single Responsibility Principle)
- IOS设计模式的六大设计原则之单一职责原则(SRP,Single Responsibility Principle)
- "围观"设计模式(1)--单一职责原则(SRP,Single Responsibility Principle)
- "围观"设计模式(1)--单一职责原则(SRP,Single Responsibility Principle)
- 设计模式六大原则(1):单一职责原则SRP(Single Responsibility Principle)
- Java设计模式之单一职责原则(Single Responsibility Principle)
- 设计模式六大原则(1)单一职责原则(Single Responsibility Principle)
- OO设计原则 — Single Responsibility Principle:OO设计的SRP单一职责原则
- 设计模式原则篇:(1)单一职责原则--Single Responsibility Principle
- 设计模式原则篇:(1)单一职责原则--Single Responsibility Principle
- 设计模式六大设计原则之单一职责原则(Single Responsibility Principle)
- [设计模式之禅读书笔记]001_设计模式六大原则(一):单一职责原则(Single Responsibility Principle)
- 设计模式六大原则(1)单一职责原则(Single Responsibility Principle)
- 设计模式6大原则之单一职责原则(Single Responsibility Principle)
- Single Responsibility Principle (SRP) - OO设计的单一职责原则
- 【设计模式六大原则1】单一职责原则(Single Responsibility Principle)