Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content

Commit 3af9e03

Browse files
重构
1 parent 3611dbf commit 3af9e03

5 files changed

Lines changed: 411 additions & 498 deletions

File tree

06-设计模式/20.1 开放-封闭原则.html

Lines changed: 18 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -16,99 +16,28 @@
1616
});
1717
</script>
1818

19+
2. 用对象的多态性消除条件分支
20+
参见 1.3 多态
1921

22+
3. 找出变化的地方
23+
封装程序中变化的部分
24+
例如:动物的叫声不同,而动物都会叫这是不变的,于是封装 makeSound 成一个稳定和封闭的函数
2025

26+
其他辅助实现开闭原则代码的方法:
27+
3.1 放置挂钩(hook)
28+
参见 11.2 钩子方法
29+
3.2 使用回调函数
30+
函数可以作为参数传递给另外一个函数,这是高阶函数的意义之一,我们通常会把这个函数称为回调函数。
31+
在 JavaScript 版本的设计模式中,策略模式和命令模式等都可以用回调函数轻松实现。
32+
回调函数是一种特殊的挂钩,我们可以把一部分易于变化的逻辑封装在回调函数里,然后把回调函数当作参数传入一个稳定和封闭的函数中。
2133

34+
4. 设计模式中的开放-封闭原则
35+
4.1 发布-订阅模式
2236

37+
4.2 模板方法模式
2338

39+
4.3 策略模式
2440

41+
4.4 代理模式
2542

26-
27-
<script>
28-
var makeSound = function( animal ){
29-
if ( animal instanceof Duck ){
30-
console.log( '嘎嘎嘎' );
31-
}else if ( animal instanceof Chicken ){
32-
console.log( '咯咯咯' );
33-
}
34-
};
35-
36-
var Duck = function(){};
37-
var Chicken = function(){};
38-
makeSound( new Duck() ); // 输出:嘎嘎嘎
39-
makeSound( new Chicken() ); // 输出:咯咯咯
40-
41-
42-
43-
var makeSound = function( animal ){
44-
if ( animal instanceof Duck ){
45-
console.log( '嘎嘎嘎' );
46-
}else if ( animal instanceof Chicken ){
47-
console.log( '咯咯咯' );
48-
}else if ( animal instanceof Dog ){ // 增加跟狗叫声相关的代码
49-
console.log('汪汪汪' );
50-
}
51-
};
52-
53-
54-
55-
var Dog = function(){};
56-
makeSound( new Dog() ); // 增加一只狗
57-
58-
var makeSound = function( animal ){
59-
animal.sound();
60-
};
61-
var Duck = function(){};
62-
Duck.prototype.sound = function(){
63-
console.log( '嘎嘎嘎' );
64-
};
65-
var Chicken = function(){};
66-
Chicken.prototype.sound = function(){
67-
console.log( '咯咯咯' );
68-
};
69-
makeSound( new Duck() ); // 嘎嘎嘎
70-
makeSound( new Chicken() ); // 咯咯咯
71-
/********* 增加动物狗,不用改动原有的makeSound 函数 ****************/
72-
var Dog = function(){};
73-
Dog.prototype.sound = function(){
74-
console.log( '汪汪汪' );
75-
};
76-
makeSound( new Dog() ); // 汪汪汪
77-
78-
</script>
79-
80-
81-
<script>
82-
83-
var getUserInfo = function( callback ){
84-
$.ajax( 'http:// xxx.com/getUserInfo', callback );
85-
};
86-
getUserInfo( function( data ){
87-
console.log( data.userName );
88-
});
89-
getUserInfo( function( data ){
90-
console.log( data.userId );
91-
});
92-
93-
var arrayMap = function( ary, callback ){
94-
var i = 0,
95-
length = ary.length,
96-
value,
97-
ret = [];
98-
for ( ; i < length; i++ ){
99-
value = callback( i, ary[ i ] );
100-
ret.push( value );
101-
}
102-
return ret;
103-
}
104-
var a = arrayMap( [ 1, 2, 3 ], function( i, n ){
105-
return n * 2;
106-
});
107-
var b = arrayMap( [ 1, 2, 3 ], function( i, n ){
108-
return n * 3;
109-
});
110-
111-
console.log( a ); // 输出:[ 2, 4, 6 ]
112-
console.log( b ); // 输出:[ 3, 6, 9 ]
113-
114-
</script>
43+
4.5 职责链模式
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
面向接口编程,而不是面向实现编程
2+
接口是对象能响应的请求的集合
3+
4+
静态类型语言通常设计为可以“向上转型”, 对象的具体类型被隐藏在“超类型”身后
5+
当对象类型之间的耦合关系被解除之后,这些对象才能在类型检查系统的监视下相互替换使用,这样才能看到对象的多态性。
6+
7+
总而言之,不关注对象的具体类型,而仅仅针对超类型中的“契约方法”来编写程序,可以产生可靠性高的程序,
8+
也可以极大地减少子系统实现之间的相互依赖关系
9+
10+
<button id="exeCommand">执行菜单命令</button>
11+
<script>
12+
var RefreshMenuBarCommand = function(){};
13+
RefreshMenuBarCommand.prototype.execute = function(){
14+
console.log( '刷新菜单界面' );
15+
};
16+
17+
var AddSubMenuCommand = function(){};
18+
AddSubMenuCommand.prototype.execute = function(){
19+
console.log( '增加子菜单' );
20+
};
21+
22+
var DelSubMenuCommand = function(){};
23+
//
24+
25+
var refreshMenuBarCommand = new RefreshMenuBarCommand(),
26+
addSubMenuCommand = new AddSubMenuCommand(),
27+
delSubMenuCommand = new DelSubMenuCommand();
28+
var setCommand = function( command ){
29+
document.getElementById( 'exeCommand' ).onclick = function(){
30+
if ( typeof command.execute !== 'function' ){
31+
throw new Error( "command 对象必须实现 execute 方法" );
32+
}
33+
command.execute();
34+
}
35+
};
36+
setCommand( refreshMenuBarCommand ); // 点击按钮后输出:"刷新菜单界面"
37+
setCommand( addSubMenuCommand ); // 点击按钮后输出:"增加子菜单"
38+
setCommand( delSubMenuCommand ); // 点击按钮后报错。Uncaught TypeError: undefined is not a function
39+
</script>
40+
41+
typescript 实现 interface
42+
<script type="text/javascript">
43+
interface Command{
44+
execute: Function;
45+
}
46+
47+
class RefreshMenuBarCommand implements Command{
48+
constructor (){
49+
}
50+
execute(){
51+
console.log( '刷新菜单界面' );
52+
}
53+
}
54+
class AddSubMenuCommand implements Command{
55+
constructor (){
56+
}
57+
execute(){
58+
console.log( '增加子菜单' );
59+
}
60+
}
61+
class DelSubMenuCommand implements Command{
62+
constructor (){
63+
}
64+
// 忘记重写 execute 方法
65+
}
66+
var refreshMenuBarCommand = new RefreshMenuBarCommand(),
67+
addSubMenuCommand = new AddSubMenuCommand(),
68+
delSubMenuCommand = new DelSubMenuCommand();
69+
refreshMenuBarCommand.execute(); // 输出:刷新菜单界面
70+
addSubMenuCommand.execute(); // 输出:增加子菜单
71+
delSubMenuCommand.execute(); // 输出:Uncaught TypeError: undefined is not a function
72+
</script>

0 commit comments

Comments
 (0)