js设计模式之路--简单工厂

第一个需求

1、用户名输入框,这里用户如果输入的内容不符合久自定义个警示信息“用户名不能多于16个字母和数字”。

我的代码:

1 var LoginAlert = function(text) {
2     this.content = text;
3 }
4 LoginAlert.prototype.show = function() {
5     //显示警示框
6 }
7 
8 var userNameAlert = new LoginAlert('用户名不能多于16个字母和数字');
9 userNameAlert.show();
第一次代码

2、现在用户密码也有一个需求,就是当用户输入密码错误的时候提示“输入的密码不正确”。

心里窃喜上面谢了一个类了,简单:

1 var passwordAlert = new LoginAlert('输入的密码不正确');
2 passwordAlert.show();
密码需求

3、用户登录时如果用户名不存在,提示“你的用户名不存在,请重新输入”。不过这里有个变化,就是在提示框中添加一个注册按钮。

。。。添加注册按钮???傻眼了。这个功能没办法复用了,在创建一个新的类:

1 var LoginConfirm = function(text) {
2     this.content = text;
3 }
4 LoginConfirm.prototype.show = function() {
5     //显示确认框
6 }
7 var loginFailConfirm = new LoginConfirm('你的用户名不存在,请重新输入');
8 loginFailConfirm.show();
用户名不存在

4、用户登录成功给出一个自定义框,除了有确认和取消外,也提示一句“欢迎回来,请输入你今天的心情”。

。。。有是一个新类:

1 var LoginPrompt = function(text) {
2     this.content = text;
3 }
4 LoginPrompt.prototype.show = function() {
5     //显示登录成功信息提示框
6 }
7 var loginSuccessConfirm = new LoginPrompt('欢迎回来,请输入你今天的心情');
8 loginSuccessConfirm.show();
登录成功提示

比人复用你的代码

现在和别人合作同时别人想用我的代码,我将LoginAlert、LoginConfirm、LoginPrompt,这三个类告诉别人。

A:“怎么这么多类,而且名字都是以Login开头的,这样吧你写个简单工厂给我吧。”

B:“简单工厂?什么东西?”

A:“是一种模式,你给我三个类,每次创建的时候我还得去找对应的类,这样很麻烦,并且注册提示框(regist)你用登录(login)也不合适。所以你最好封装在一个函数里面,我只要记住这个函数,然后通过调用这个函数就能创建我需要的对象,不是更好。使用你的人不用去关注这些对象到底以来那个基类创建的,而我们只知道这个函数就可以。这种函数我们通常叫工厂函数。这种模式就是我们的工厂模式。”

“举个例子吧,比如说体育商店卖体育器材,里面很多提月用品,以及相关的介绍,你去店里卖东西,只需要问售货员,他会帮你找到你所需要的东西。”

 1 // 篮球基类
 2 var Basketball = function() {
 3     this.intro = '篮球盛行于美国';
 4 }
 5 
 6 Baskeball.prototype = {
 7     getMember: function() {
 8         console.log('每个队需要5名队员');
 9     },
10     getBallSize: function() {
11         console.log('篮球尺寸很大');
12     }
13 }
14 
15 // 足球基类
16 var Football = function() {
17     this.intro = '足球再世界范围很流行';
18 }
19 
20 Football.prototype = {
21     getMember: function() {
22         console.log('每个队需要11名队员');
23     },
24     getBallSize: function() {
25         console.log('足球很大');
26     }
27 }
28 
29 // 网球基类
30 var Tennis = function() {
31     this.intro = '每年都有很多网球系列比赛';
32 }
33 
34 Tennis.prototype = {
35     getMember: function() {
36         console.log('每个队需要1名队员');
37     },
38     getBallSize: function() {
39         console.log('网球很小');
40     }
41 }
42 
43 // 运动工厂(运动商店)
44 var SportsFactory = function(name) {
45     switch(name){
46         case 'NBA':
47             return new Baketball();
48         case 'wordCup':
49             return new Football();
50         case 'FrenchOpen':
51             return new Tennis();
52     }
53 }
54 
55 // 使用
56 var footnall = SportsFactory('wordCup');
57 console.log(footnall);
58 console.log(footnall.intro);
59 footnall.getMember();
体育商店

A:好了,简单吧,你去将你前面的代码修改下。

 1 var PopFactory = function(name) {
 2     switch (name) {
 3         case 'alert':
 4             return new LoginAlert();
 5         case 'confirm':
 6             return new LoginConfirm();
 7         case 'prompt':
 8             return new LoginPrompt();
 9     }
10 }
修改后代码

一个对象也可以代替许多类

A:你发现你的三个类中有很多方法是相同的,你觉得没?比如都有关闭按钮,都有提示文案等。

A:你要将这些相同的提出来,不同的针对处理。举个例子。比如你想创建一些书,书都有相似的地方,比如目录、页码等,有些地方不同,如书名、出版社、书的类型等。我们处理不同:

 1 function createBook(name, time, type) {
 2     var o = new Object();
 3     o.name = name;
 4     o.time = time;
 5     o.type = type;
 6     o.getName = function() {
 7         console.log(this.name);
 8     }
 9     
10     return o;
11 }
12 var book1 = createBook('js book', 2000, 'js');
13 var book2 = createBook('css book', 2008, 'css');
14 
15 book1.getName();
16 book2.getName();
处理书不同属性

所以将之前的三个类改成工厂模式就比较简单。首先抽取他们的相同点,比如 this.content和原型共有方法show。当然也有不同点,比如提示框和确定框的确定按钮,提示框的输入框等等。因此可以想下面这样:

 1 function createPop(type, text) {
 2     var o = new Object();
 3     o.content = text;
 4     o.show = function() {
 5         // 显示信息
 6     };
 7     if(type == 'alert') {
 8         // 警示框差异部分
 9     }
10     if (type == 'prompt') {
11        // 提示框差异部分 
12     }
13     if (type == 'prompt') {
14        // 确认框差异部分
15     }
16     
17     return o;
18 }
19 
20 var userNameAlert = new createPop('alert', '用户名只能16个字母或数字');
工厂模式处理登录信息

你的理解决定你选择的方式

  • 第一种是通过类实例化对象创建的。
  • 第二种是通过创建新的对象,然后包装增强其属性和功能来实现。这也叫寄生式继承,只不过这里函数内部创建的o对象没有继承任何类和对象。

他们之间的差异:

    1、通过类创建的对象,如果父类继承一个对象,那么他们的父类原型上的方法是可以共用的。

    2、通过寄生方式创建的对象是一个新的个体。所以他们的方法就不能共用。

具体选择那种工厂方式来实现,要看你是如何分析需求的。

 

posted on 2017-07-27 19:15  jayafs  阅读(89)  评论(0)    收藏  举报

导航