几种简单的设计模式

第一章.设计模式简介

作用:JavaScript设计模式的作用 - 提高代码的重用性,可读性,使代码更容易的维护和扩展。

一般只用于大型的项目.

设计模式有六大原则:

  1. 开闭原则。就是说模块应对扩展开放,而对修改关闭。
  2. 里氏代换原则。如果调用的是父类的话,那么换成子类也完全可以运行。
  3. 依赖倒转原则。把父类都替换成它的子类,程序的行为没有变化。
  4. 接口隔离原则,每一个接口应该是一种角色,不多不少,不干不该干的事,该干的事都要干。
  5. 单一职责原则。
  6. 迪米特法则。 最少知识原则。

第二章:常见设计模式

1.聚合

1
2
3
4
5
6
7
8
9
10
function A(){
this.say = function(){
console.log('a');
}
}
function B(){
this.a = new A();
}
var b = new B();
b.a.say();

2.单例

1
2
3
4
5
6
7
8
9
10
11
1.
function A(){
this.say = function(){
console.log('a');
}
}
function B(){
this.a = new A();
}
var b = new B();
b.a.say();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2.
var createPerson = (function(){
function Person(name) {
this.name = name;
}

var p;
return function (name) {
if(!p){
p = new Person(name);
}else {
p.name = name;
}
return p;
}
}());
var p1 = createPerson('张三');
var p2 = createPerson("李四");
console.log(p1);
console.log(p1==p2);
=>李四
=>true

后传入的是谁就是谁
1
2
3
4
5
6
7
8
9
10
11
function Person(name){
var p = this;
p.name = name;
Person = function(){
return p;
}
}AQ
var person1 = new Person('张三');
var person2 = new Person("李四");
console.log(person1);
console.log(person2);

3.替换构造函数法

1
2
3
4
5
6
7
8
9
复写了构造函数Person

function Person(){
var p = this;
p.name = name;
Person = function(){
return p;
}
}

4.适配器模式

用法:在不更改原有功能的前提下,来试用新的变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<p id="p1"></p>
<p id="p2"></p>

<script type="text/javascript" src="myAjax.js"></script>
<script>
myAjax.get('data5.json',function(result){
showMsg(JSON.parse(result),p1)
});
myAjax.get('data4.json',function(result){
showMsgAdapter(JSON.parse(result),p2)
});
function showMsg(obj,p){
p.innerHTML = obj.name;
}
//适配器模式:
function showMsgAdapter(arr,p){
showMsg(arr[0],p)
}
</script>

5.观察者模式

开服务器才行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<button id="btn1">发布</button>
<script>
var publisher = {
register:function (subscriber) {
this.subscriber = subscriber;
},
publish:function (msg) {
this.subscriber(msg);
}
};
//向发布者订阅信息,订阅者使用函数来充当
publisher.register(function (msg) {
console.log(msg);
});
btn1.onclick=function(){
publisher.publish("我是发布的信息");
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<button id="btn1">发布1</button>
<button id="btn2">发布2</button>
<script>
var publisher = {
register:function (event,subscriber) {
if(typeof subscriber != "function") return;
//先判断event是否存在
if(!this[event]) this[event] = [];
this[event].push(subscriber);
},
publish:function (event,msg) {
if(!(event in this)) return;
for(var sub of this[event]) {
sub(msg)
}
},
remove:function(event,sub){
if(!this[event] ||this[event].indexOf(sub)==-1) return;
this[event].splice(this[event].indexOf(sub),1)
}
};
//向发布者订阅信息,订阅者使用函数来充当
var f1 = function(msg){
console.log("我是第一个订阅者:"+msg)
};
var f2 = function (msg) {
console.log("我是第二个订阅者:"+msg);
};
publisher.register('first',f1);
publisher.register('second',f2);
btn1.onclick=function(){
publisher.publish('first',"发布1");
};
//我是第一个订阅者:发布1
btn2.onclick=function () {
publisher.publish('second',"发布2")
};
//我是第二个订阅者:发布2
publisher.remove('first',f1);
//点击按钮1失去效果
</script>

例:利用观察者模式来给按钮添加三击事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<script>
//在按钮的原型对象中添加addMyEventListener方法,这个方法用来给按钮添加自定义事件.
HTMLButtonElement.prototype.addMyEventListener = function(event,f){
if(!this[event]) this[event] = [];
this[event].push(f);
};
//调用addMyEventListener函数给按钮1添加自定义三击事件
btn1.addMyEventListener('threeclick',function(){
console.log("您三击了");
});
//定义变量times用来记录三次点击事件的时间
var times =[];

function step() {
if(times.length ==3){
times.shift();
}
times.push(new Date());
if(times.length ==3){
if(times[2]-times[0]<=1000){
times.length = 0;
for(tc of this.threeclick){
tc();
}
}
}
}
//给俩个按钮都添加三击事件
btn1.addEventListener('mousedown',step);
btn2.addEventListener('mousedown',step);
//只有按钮1才有三击事件,按钮2会报错
</script>

评论