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、通过寄生方式创建的对象是一个新的个体。所以他们的方法就不能共用。
具体选择那种工厂方式来实现,要看你是如何分析需求的。
浙公网安备 33010602011771号