首页 > 代码库 > 精通JavaScript--05设计模式:创建型

精通JavaScript--05设计模式:创建型

使用设计模式的要诀时把它们看作你编程工具箱中的多种工具,每一种都有一个特定的用途。在尝试应用设计模式至代码之前,你首先要熟悉各种现有的设计模式以及每一种所应用的场合(应用了错误的工具将导致不必要的麻烦和时间的浪费)。这些章节将帮助你来实现这一点。除非你是一个特别老练的JavaScript开发者,不然,在你开始为应用程序编写代码时头脑是没有特定的设计模式的。随着代码的不断积累,你将发现需要对代码进行改变以使日后的开发更易于管理,同时还要对代码库中的文件按照一定的结构和规律进行管理。此过程通常称为“重构”。通常,就是在开发的此阶段要考虑应用特定的设计模式或架构模式至代码,以简化后续的开发工作。要谨慎对待那些坚持要在项目启动时就要在头脑中保持某个特定的设计模式来开展编码工作或在开始时就使用某种特定的预建的JavaScript框架的人员。原因是,除非他们是非常有经验的专业人员,不然,这等同于在能识别出解决问题所需使用的工具之前就直接选用一种全新的没有使用经验的工具。

你应该熟练掌握这里每一章所介绍的设计模式和架构模式,仔细学习每一种模式并领会其使用的方式方法。随着时间的积累,你会将逐渐识别出代码所需要应用的特定模式,进而改进代码的可维护性,并在某种情况下提升效率。

5.1  什么是设计模式

设计模式时经过尝试和测试,通过验证,通过验证的代码编写和组织方法。通过开发者提供清晰的结构,移除不必要的复杂性,并将大型代码库中的不同部分的连接进行解耦 ,使得代码更易于理解,易于维护。各种设计模式就好比编程工具箱中的各种工具。

介绍23种不同的设计模式,这些模式可划分为3大类:创建型,结构型和行为型。

 

5.2  创建型设计模式

创建型设计模式为你描述了用于创建对象的“类”或方法,而不需要你自己直接创建对象。在决定何对象或何种对象的类型才是与你所面对的特定情况和需求最为相关的时,此抽象层给了你以及你的代码以更高的灵活性。在这里,我将为你介绍5种创建型设计模式,每种设计模式都配有相应的例子。你会发现这些设计模式对你的代码非常有用。

5.21  工厂模式

利用工厂模式,可以实现在不指定特定的“类”而创建出对象。在之前的章节,当涉及“类”时,我们需要直接使用JavaScript关键字new来创建某特定“类”或子类的实例。而利用工厂模式,对象的创建处理过程被予以抽象,使得相对复杂的对象创建处理过程得以封装于简单的接口之下,而不需要使用new关键字。此抽象意味着,用作创建各实例的后台“类”的类型和方法可以随时被完全替换,而不需要改变接口来适应类的创建。从其他开发者角度来说,并不需要例会接口底下所发生的变化。如果预知到在将来可能需要作出许多更改,但又不希望必须重写散步在大量其他代码中的“类”的实例化代码,则使用工厂模式是很理想的做法。

代码清单5-1显示了工厂模式的例子。当中根据工厂方法的不同输入参数,实现了基于若干不同的“类”进行对象的实例化。

代码清单5-1  工厂模式

 

 1             //定义一个工厂,它会基于所输入的内容,使用最适合的“类”来为我们创建出相应的表单域对象
 2             var FormFieldFactory={
 3                 //makeField方法使用一下2个选项
 4                 // -type,定义所创建的表单域对象类型,例如text,email或button
 5                 // -displayText,基于对象的类型,定义表单域的placeholder(占位符)文本或按钮上所显示的文本
 6                 makeField:function(options){
 7                     var options=options ||{},
 8                         type=options.type||"text",
 9                         displayText=options.displayText ||"",
10                         field;
11                     //基于所提供的类型使用最适合的“类”来创建对象实例
12                     switch (type){
13                         case "text":
14                             field=new TextField(displayText);
15                             break;
16                         case "email":
17                             field=new EmailField(displayText);
18                             break;
19                         case "button":
20                             field=new ButtonField(displayText);
21                             break;
22                         //如果不确定,则使用TextField“类”
23                         default:
24                             field=new TextField(displayText);
25                             break;
26                     }
27                     return field;
28                     
29                 }
30             };
31             //定义TextField“类”,用于创建<input type="text">表单元素
32             function TextField(displayText){
33                 this.displayText=displayText;
34             }
35             
36             //getElement方法将利用所提供的placeholder文本值来创建一个DOM元素
37             TextField.prototype.getElement=function(){
38                 var textField=document.createElement("input");
39                 textField.setAttribute("type","text");
40                 textField.setAttribute("placeholder",this.displayText);
41                 return textField;
42             }
43             
44             //定义EmailField类,用于创建<input type="email">表单元素
45             function EmailField(displayText){
46                 this.displayText=displayText;
47             }
48             //getElement方法将利用所提供的placeholder文本值来创建一个DOM元素
49             EmailField.prototype.getElement=function(){
50                 var emailField=document.createElement("input");
51                 emailField.setAttribute("type","email");
52                 emailField.setAttribute("placeholder",this.displayText);
53                 return emailField;
54             };
55             
56             //定义ButtonField“类”,用于创建<button>表单元素
57             function ButtonField(displayText){
58                 this.displayText=displayText;
59             }
60             //getElement方法将利用所提供的placeholder文本值来创建一个DOM元素
61             ButtonField.prototype.getElement=function(){
62                 var button=document.createElement("button");
63                 button.setAttribute("type","submit");
64                 button.innerHTML=this.displayText;
65                 return button;
66             };

代码清单5-2演示了如何在应用程序中使用代码清单5-1所创建的工厂。

代码清单5-2  使用工厂模式

 

 1             //使用工厂来创建一个文本输入表单域,一个email表单域和一个提交按钮。请留意我们如何在不需要知道
 2             //底层的那些“类”或它们的特定输入的情况下创建表单域的。FormFieldFactory对该方式进行了抽象
 3             var textField=FormFieldFactory.makeField({type:"text",displayText:"Enter the first line of your address"}),
 4                 emailField=FormFieldFactory.makeField({type:"email",displayText:"Enter your email address"}),
 5                 buttonField=FormFieldFactory.makeField({type:"button",displayText:"Submit"});
 6             
 7             //等到浏览器的load事件触发后,把由这三个新创建的对象所表示的DOM元素添加至当前页面
 8             window.addEventListener("load",function(){
 9                 var bodyElement=document.body;
10                 
11                 //使用每个对象的getElement()方法,获得对其DOM元素的引用,以将其添加至页面
12                 bodyElement.appendChild(textField.getElement());
13                 bodyElement.appendChild(emailField.getElement());
14                 bodyElement.appendChild(buttonField.getElement());
15             },false);

在需要在代码的其余所有部分通过屏蔽较为复杂的对象创建方法来简化某些特定对象的创建过程时,使用工厂模式最适合不过了。

 

5.2.2  抽象工厂模式

 

精通JavaScript--05设计模式:创建型