Skip to content

Commit f917349

Browse files
committed
单一职能原则
1 parent a7b587a commit f917349

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

eighteen-chapter/index.js

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// 单一职责原则 SRP
2+
// 一个类而言,应该仅有一个引起它变化的原因
3+
// SRP 原则体现为:一个对象(方法)只做一件事情
4+
5+
// SRP 原则在很多设计模式中都有着广泛的运用,例如代理模式、迭代器模式、单例模式和装 饰者模式。
6+
7+
//代理模式
8+
// myImage 负责往页面中添加 img 标签:
9+
var myImage = (function (){} {
10+
var imgNode = document.createElement('img');
11+
document.body.appendChild(imgNode)
12+
return {
13+
setSrc:function(src){
14+
imgNode.src = src;
15+
}
16+
}
17+
})()
18+
19+
// proxyImage 负责预加载图片,并在预加载完成之后把请求交给本体 myImage
20+
var proxyImage = (function(){
21+
var img = new Image();
22+
img.onload = function(){
23+
myImage.setSrc(this.src)
24+
};
25+
return {
26+
setSrc:function(src){
27+
myImage.setSrc('xxx-loading.png');
28+
img.src = src;
29+
}
30+
}
31+
})()
32+
33+
proxyImage.setSrc('http://wwww.baidu/pic/cat.png');
34+
35+
//迭代器模式
36+
var appendDiv = function(data){
37+
for(var i=0,l=data.length;i<l;i++){
38+
var div = document.createElement('div');
39+
div.innerHTML = data[i];
40+
document.body.appendChild(div)
41+
}
42+
}
43+
44+
appendDiv([1,2,3,4,5,6]);
45+
46+
// appendDiv 函数本来只是负责渲染数据,但是在这里它还承担了遍历聚合对象 data 的职责
47+
48+
// 当把迭代聚合对象的职责单独封装在 each 函数中后
49+
var each = function(obj,callback){
50+
var value ,i=0,length = obj.length,isArray = isArrayLike(obj);
51+
52+
if(isArray){
53+
for(;i<length;i++){
54+
callback.call(obj[i],i,obj[i]);
55+
}
56+
}else {
57+
for(i in obj){
58+
value = callback.call(obj[i],i,obj[i]);
59+
}
60+
}
61+
62+
return obj;
63+
}
64+
65+
var appendDiv = function(data){
66+
each(data,function(i,n){
67+
var div = document.createElement('div');
68+
div.innerHTML = n;
69+
document.body.appendChild(div);
70+
})
71+
}
72+
73+
appendDiv( [ 1, 2, 3, 4, 5, 6 ] );
74+
appendDiv({a:1,b:2,c:3,d:4} );
75+
76+
//单例模式
77+
//惰性单例
78+
var createLoginLayer = (function(){
79+
var div;
80+
return function(){
81+
if(!div){
82+
div = document.createElement('div');
83+
div.innerHTML = '我是登录浮窗';
84+
div.style.display = 'none';
85+
document.body.appendChild(div)
86+
}
87+
return div;
88+
}
89+
})()
90+
91+
// 把管理单例的职责和创建登录浮窗的职责分别封装在两个方法里,这两个方法可以 独立变化而互不影响
92+
var getSingle = function(fn){
93+
var result;
94+
return function(){
95+
return result || (result = fn.apply(this,arguments))
96+
}
97+
}
98+
99+
var createLoginLayer = function(){
100+
var div = document.createElement('div');
101+
div.innerHTML = '我是登录浮窗';
102+
document.body.appendChild(div)
103+
return div;
104+
}
105+
106+
var createSingleLoginLayer = getSingle(createLoginLayer);
107+
var loginLayer1 = createSingleLoginLayer();
108+
var loginLayer2 = createSingleLoginLayer();
109+
alert ( loginLayer1 === loginLayer2 );
110+
111+
// 装饰者模式
112+
// 装饰者模式可以为对象动态增加职责,从另一个角度来看, 这也是分离职责的一种方式
113+
Function.prototype.prototype.after = function(afterfn){
114+
var __self = this;
115+
return function(){
116+
var ret = __self.apply(this,arguments);
117+
afterfn.apply(this,arguments);
118+
return ret;
119+
}
120+
};
121+
122+
var showLogin = function(){
123+
console.log('打开登录浮层')
124+
}
125+
126+
var log = function(){
127+
console.log("上报标签为 xxx");
128+
}
129+
130+
document.getElementById('button').onclick = showLogin.after(log);
131+
132+
133+
134+
// SRP 原则的应用难点就是如何去分离职责
135+
// 一方面,如果随着需求的变化,有两个职责总是同时变化,那就不必分离他们
136+
// 另一方面,职责的变化轴线仅当它们确定会发生变化时才具有意义
137+
// SRP 原则的优点是降低了单个类或者对象的复杂度,按照职责把对象分解成更小的粒度,
138+
// 这有助于代码的复用,也有利于进行单元测试
139+
// SRP 原则也有一些缺点,最明显的是会增加编写代码的复杂度
140+
// 我们按照职责把对象 分解成更小的粒度之后,实际上也增大了这些对象之间相互联系的难度

0 commit comments

Comments
 (0)