Skip to content

Commit 75cb60b

Browse files
committed
添加详细的描述
1 parent afa826d commit 75cb60b

20 files changed

Lines changed: 498 additions & 16 deletions

File tree

JavaScript-Design-Patterns/Chaining/Introduction to chaining.js renamed to JavaScript-Design-Patterns/Chaining/1-Introduction to chaining.js

File renamed without changes.

JavaScript-Design-Patterns/Chaining/Building a chainable JavaScript library.js renamed to JavaScript-Design-Patterns/Chaining/3-Building a chainable JavaScript library.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// Include syntactic sugar to help the development of our interface.
2+
23
Function.prototype.method = function(name, fn) {
34
this.prototype[name] = fn;
45
return this;

JavaScript-Design-Patterns/Chaining/The structure of the chain.js renamed to JavaScript-Design-Patterns/Chaining/3-The structure of the chain.js

File renamed without changes.

JavaScript-Design-Patterns/Chaining/Using callbacks.js renamed to JavaScript-Design-Patterns/Chaining/4-Using callbacks.js

File renamed without changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
方法的链式调用<br />
2+
Javascript中的对象是作为引用被传递的,所以可以让每个方法都传回对象的引用,即返回this值;<br />
3+
这种编程风格可以简化代码的编写工作,让代码更简洁易读,<br />
4+
<a href="">示例程序</a><br />
5+
<br />
6+
为了解决命名冲突,使用指定的API,可以为框架提供一个安装器<br />
7+
<a href="">示例程序</a><br />
8+
<br />
9+
如果想让getter和setter方法都支持链式调用,可以在getter方法中使用回调技术,
10+
<a href="">示例程序</a>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
适配模式可用来在现有接口和不兼容的类之间进行适配,使用这种模式的对象又叫包装器(wrapper),因为它们是在用一个新的接口包装另一个对象。<br />
2+
从表面上看,适配器模式很像外观模式。它们都要对别的对象进行包装并改变其呈现的接口。二者的差别在于它们如何改变接口。外观元素展现的是一个简化的接口,它并不提供额外的选择,而且有时为了方便完成常见任务它还会做出一些假定。而适配器则要把一个接口转换为另一个接口,它并不会滤除某些能力,也不会简化接口。如果客户系统API不可用,就需要用到适配器。<br />
3+
PS2-to-USB适配器就是一个例子。<br />
4+
示例:<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Adapter-Pattern/1%20-%20Characteristics%20of%20an%20adapter.js">
5+
创建一个简单的适配器方法,修改传入参数的方式
6+
</a>
7+
<br />
8+
示例:
9+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Adapter-Pattern/1%20-%20Characteristics%20of%20an%20adapter.js">
10+
适配两个库
11+
</a>
12+
<br />
13+
示例:
14+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Adapter-Pattern/3%20-%20Adapting%20an%20email%20API.html">
15+
适配电子邮件API
16+
</a>
17+
<br />
18+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Adapter-Pattern/4%20-%20More%20on%20adapting%20an%20email%20API.js">
19+
添加适配器
20+
</a>
21+
<br />
22+
1.1、适配器模式的适用场合:<br />
23+
适配器适用于客户系统期待的接口与现有API提供的接口不兼容这种场合。适配器所适配的两个方法执行的应该是类似的任务,否则的话就解决不了问题。就像桥接元素和外观元素一样,通过创建适配器,可以把抽象与其实现隔离开来,以便二者独立变化。<br />
24+
1.2、适配器模式之利:<br />
25+
用一个新的接口对现有类的接口进行包装,这样客户程序就能使用这个并非为其量身打造的类而又无需为此大动手术。<br />
26+
1.3、设配器模式之弊:<br />
27+
有人认为适配器是一种不必要的开销,完全可以通过重写现有代码避免。此外适配器模式也会引入一批需要支持的新工具。如果现有API还未定形,或者新接口还未定形,那么适配器可能不会一直管用。<br />
28+
在涉及大型系统和遗留框架的情况下,它的优点往往比缺点更突出。
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
按照GoF的定义,桥接模式的作用在于“将抽象与其实现隔离开来,以便二者独立变化”。这种模式对于Javascript中常见的事件驱动的编程大有裨益。<br />
2+
桥接模式最常见和实际的应用场合之一是事件监听器回调函数。 example:事件监听器,把事件处理的语句封装到回调函数中,通过接口而不是实现进行编程。<br />
3+
桥接模式的其他例子:<br />
4+
除了在事件回调函数与接口之间进行桥接外<br />
5+
桥接模式也可以用于连接公开的API代码和私用的实现代码<br />
6+
此外,它还可以用来把多个类联结在一起。从类的角度来看,这意味着把接口作为公开的代码编写,而把类的实现作为私用代码编写。<br />
7+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Bridge-Pattern/2%20-%20Other%20examples%20of%20bridges.js" target="_black">
8+
example:用桥接模式收集某些私用性的信息 </a><br />
9+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Bridge-Pattern/3%20-%20Bridging%20multiple%20classes%20together.js" target="_black">
10+
example:用桥接模式联结多个类 使用桥接模式,让Class1和Class2能够独立于BridgeClass而发生改变。
11+
</a>
12+
<br />
13+
构建一个Ajax请求队列,把请求存储在浏览器内存中的一个队列 化数组中,刷新队列时,每个请求都会按“先入先出”的顺序被发送给一个后端的Web服务。<br />
14+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Bridge-Pattern/4%20-%20Building%20an%20XHR%20connection%20queue.js">
15+
该Ajax请求队列的框架实现:example
16+
</a>
17+
<br />
18+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Bridge-Pattern/5%20-%20XHR%20connection%20queue%20example%20page.html">
19+
该Ajax请求队列的使用例子:example<br />
20+
</a>
21+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Bridge-Pattern/6%20-%20Where%20have%20bridges%20been%20used_.js">
22+
添加桥接方法的例子:example<br />
23+
</a>
24+
这个应用程序到处都有桥接元素的身影,最明显的是,事件监听器回调函数并不直接与队列打交道,而是使用了桥接函数。<br />
25+
在供用户执行刷新和暂停操作的部分,我们提供了一个动作调度函数,其作用就是桥接用户操作所包含的输入信息并将其委托给恰当的处理代码。在DOM脚本编程中,这种技术也称为事件委托。click事件所代表的用户操作与DED.Queue实现完全分开的结果就是,后者的方法并不直接与那些事件耦合在一起,因此你可以在任何地方执行这些方法。<br />
26+
2.1、适用场合:<br />
27+
这里的要诀是要让接口“可桥接”,实际上也就是可适配。<br />
28+
2.2、优点:<br />
29+
把抽象与实现隔离开,有助于独立地管理软件的各组成部分。<br />
30+
2.3、缺点:<br />
31+
每使用一个桥接元素都要增加一次函数调用,这对应用程序的性能会有一些负面影响。提高了系统的复杂程度。如果一个桥接函数被用于连接两个函数,而其中某个函数根本不会在桥接函数之外被调用,那么此时这个桥接函数就不是非要不可的。<br />
32+
桥接模式“将抽象与实现隔离开来,以便二者独立变化”。它可以促进代码的模块化、促成更简洁的实现并提高抽象的灵活性。它可以用来把一组类和函数连接起来,而且提供了一种借助于特权函数访问私用数据的手段。

‎JavaScript-Design-Patterns/The-Chain-of-Responsibility-Pattern/1 - PublicLibrary class.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// 首先定义一些接口
33
var Publication = new Interface('Publication', ['getIsbn', 'setIsbn', 'getTitle',
44
'setTitle', 'getAuthor', 'setAuthor', 'getGenres', 'setGenres', 'display']);
5-
var Library = new Interface('Library', [‘addBook’, 'findBooks', 'checkoutBook',
5+
var Library = new Interface('Library', ['addBook', 'findBooks', 'checkoutBook',
66
'returnBook']);
77
var Catalog = new Interface('Catalog', ['handleFilingRequest', 'findBooks',
88
'setSuccessor']);

‎JavaScript-Design-Patterns/The-Chain-of-Responsibility-Pattern/7 - DynamicGallery class with optimization.js‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@ var DynamicGallery = function(id) { // implements Composite, GalleryItem
44
//todo
55
}
66
DynamicGallery.prototype = {
7-
add: function(child) { //todo },
8-
remove: function(child) { //todo },
9-
getChild: function(i) { //todo },
7+
add: function(child) {
8+
//todo
9+
},
10+
remove: function(child) {
11+
//todo
12+
},
13+
getChild: function(i) {
14+
//todo
15+
},
1016
hide: function() {
1117
// 优化:从hide方法中删除将方法调用传递给子节点的那部分代码
1218
this.element.style.display = 'none';
1319
},
14-
show: function() { //todo },
15-
getElement: function() { //todo }
20+
show: function() { //todo
21+
},
22+
getElement: function() { //todo
23+
}
1624
};
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
1、职责链模式<br />
2+
1.1、职责链的结构<br />
3+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Chain-of-Responsibility-Pattern/1%20-%20PublicLibrary%20class.js">
4+
首先来看一个图书馆增加图书的例子
5+
</a><br />
6+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Chain-of-Responsibility-Pattern/2%20-%20PublicLibrary%20class%20with%20hard-coded%20catalogs.js">
7+
添加目录类
8+
</a><br />
9+
addBook方法中的代码固化了对5个不同类的依赖。如果想增加更多图书类别,那就需要修改构造函数和addBook方法这两处的代码。此外,把这些目录类别固化在构造函数中也没有多大意义。<br />
10+
使用职责链模式进行
11+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Chain-of-Responsibility-Pattern/3%20-%20PublicLibrary%20class%20with%20chain%20of%20responsibility%20catalogs.js">
12+
改进
13+
</a>
14+
<br />
15+
分类目录对象的具体
16+
<a href="https://github.com/arthinking/Javascript/blob/master/Pro-JavaScript-Design-Patterns/Chapter17-The-Chain-of-Responsibility-Pattern/17.04%20-%20GenreCatalog%20and%20SciFiCatalog%20classes.js">
17+
实现代码
18+
</a>
19+
<br />
20+
1.2、传递请求<br />
21+
在链上传递请求有许多不同的方法,最常见的做法要么是使用一个专门的请求对象,要么是根本不使用参数,只依靠方法自身传递消息(第6节的例子)。本节讨论第一种方法。<br />
22+
在图书馆中根据分类搜索图书的例子,在GenreCatalog的findBoos()方法中进行传递请求的示例<br />
23+
1.3、在现有层次中实现职责链<br />
24+
在现有层次体系中实现这种模式往往更容易,在此情况下它经常与组合模式搭配使用。犹豫组合模式已经建立了一个对象层次体系,因此在此基础上添加一些用来处理(或传递)请求的方法很简单。<br />
25+
在组合模式结合了职责链之后,方法调用就不再总是不加分辨地往下一直传到叶对象。此时每一层都要对请求进行分析,以判断当前对象应该处理它还是应该把它往下传。组合对象实际上也会承担部分工作,而不是单纯依靠叶对象执行所有操作。这样一来就不用单独实现一些对象来作链上的环节,也不用手工设定下家对象。通过规定在某些场合下一些方法调用可以再层次体系中较高的层次上得到处理,并且组织较低层次的节点和叶节点获取这些调用,可以让组合模式变得更加健壮。<br />
26+
职责链模式和组合模式的结合对双方都是一种优化。由于职责链是现成的,所以设置代码的数量和用于职责链的额外对象的数目都减少了。由于在组合层次体系中某个方法可能会在高层得到处理,所以在整个树上执行该方法所需的计算量也降低了。<br />
27+
1.4、事件委托<br />
28+
Javascript语言使用了职责链模式来决定如何处理事件。事件被触发时要经历两个阶段:事件捕获阶段,事件沿HTML层次体系向下传播,直到到达被点击元素;事件冒泡阶段,在这个阶段事件会历经同一批元素升回到顶层祖先。绑定在经过的这些元素上的事件监听器既可以停止事件传播,也可以让其继续沿层次体系向上或向下传播。这里传递请求对象称为事件对象,它包含着与事件有关的所有信息。<br />
29+
事件模型本质是作为职责链实现的所以事件模型也可以遵循如下经验:最好在层次体系较高层次上处理请求,假设有一个无序列表包含着几打列表项。与其为其中的每一个li元素绑定一个click事件监听器,不如只为ul元素绑定一个这种事件监听器,这样脚本会运行的更快,内存消耗得更少,而且以后维护起来也更容易,这种技术称为时间委托,这是职责链方面的知识有助于优化代码的情况之一。<br />
30+
1.5、职责链模式的适用场合<br />
31+
如果事先不知道在几个对象中有哪些能够处理请求,那么这就属于应该适用职责链的情况;<br />
32+
如果这批处理器对象在开发期间不可知,而是需要动态指定的话,那么也应该使用这种模式;<br />
33+
该模式还可以用在对于每个请求都不止有一个对象可以对它进行处理这种情况下。<br />
34+
使用这种模式,可以把特定的具体类与客户端隔离开,并代之以一条由弱耦合的对象组成的链,它将隐式地对请求进行处理,这有助于提高代码的模块程度和可维护性。<br />
35+
1.6、图片库的进一步讨论<br />
36+
组合模式实现的
37+
<a href="https://github.com/wchaowu/javascript-code/blob/master/JavaScript-Design-Patterns/The-Chain-of-Responsibility-Pattern/6%20-%20DynamicGallery%20class%20from%20Chapter%209.js">
38+
图片库代码
39+
</a>
40+
<br />
41+
<a href="https://github.com/arthinking/Javascript/blob/master/Pro-JavaScript-Design-Patterns/Chapter17-The-Chain-of-Responsibility-Pattern/17.07%20-%20DynamicGallery%20class%20with%20optimization.js">
42+
1.6.1、用职责链提高组合对象的效率
43+
</a>
44+
<br />
45+
在组合对象中,hide和show方法先对本层次的一个样式属性进行设置,然后将调用传递给所有子对象。这种做法慎密但效率不高,更好的做法是将这些方法作为沿职责链传递的请求实现,hide请求根本不用传递,show则总是需要传递。<br />
46+
优化一:从hide方法中删除将方法调用传递给子节点的那部分代码<br />
47+
1.6.2、为图片添加标签<br />
48+
添加标签,提供搜索功能。<br />
49+
通过职责链模式在组合对象中查找包含某个标签的所有对象,分别在组合对象和也对象中添加getPhotosWithTag()方法<br />
50+
1.7、职责链模式之利<br />
51+
可以动态选择由哪个对象处理请求。可以比试图在开发期间静态指定处理请求的对象高效得多。可以使用这种模式消除发出请求的对象与处理请求的对象之间的耦合。<br />
52+
在已有现成的链或层次体系的情况下,职责链模式更加有效。与组合模式的结合使用就属于这种情况。<br />
53+
1.8、职责链模式之弊<br />
54+
请求与具体的处理程序被隔离开啦,因此无法保证它一定会被处理,而不是径直从链尾离开。这种模式的接收者都是隐式的,因此无法得知如果请求能够得到处理的话具体将由哪个对象处理它。可以通过创建一个通用的catch-all接收者并将其添加到所有链的尾端来解决,但这个办法很繁琐,失去随时在链尾添加新环节的灵活性。<br />
55+
职责链与组合对象类的搭配使用可能有点令人困惑。组合模式期望组合对象节点完全可以与叶节点互换使用,而且客户代码看不出其中的差别,所有方法调用都被组合对象往层次体系的下层传递。而职责链模式引入后,有些方法会在组合对象进行处理,而不会进行往下传。

0 commit comments

Comments
 (0)