设计模式
[toc]
前言
对象收编变量
当有同一种功能、或者同属于一类的变量时,可以创建一个对象用来收编这些同一类的功能或者变量。例如表单检验功能。
原:
let checkName = function(){...} let checkEmail = function(){...} let checkPassword = function(){...}
改:
let check = { checkName:function(){...}, checkEmail:function(){...}, checkPassword:function(){...}, }
但是这样的话,当别人想用我的对象就比较麻烦,因为他不能复制一份,所以可以采用下面的方法:
改:
let checkFn = function(){ return { checkName:function(){...}, checkEmail:function(){...}, checkPassword:function(){...}, } }; //使用 let check = checkFn();
这样的话,每次调用函数都会产生一个新的对象,别人调用的时候都是一个新的对象。这样每个人都互不影响了。当然,也可以将它改成类的写法。
类:
let CheckObject = function(){} CheckObject.prototype.checkName = function(){...} ... //使用 let check = new CheckObject();
链式调用
上述方法在调用的时候需要写多个check,很不方便,因此,可以在函数内部return this,来进行链式创建。即:
let CheckObject = function(){} CheckObject.prototype.checkName = function(){ ... return this; } ... //使用 let check = new CheckObject(); check.checkName().checkEmail().checkPassword();
动态添加方法与链式添加方法
动态添加方法可以在Function的prototype属性上下手,例如,我们可以定义一个添加方法的方法.
Function.prototype.addMethods = function(name,fn){ this[name] = fn; }
这样就可以进行动态添加了.
let check = function(){}; check.addMethods("checkName",function(){}); ...
当然这种方法也是支持链式添加方法的.只需要在Function.prototype.addMethods中返回 return this即可.
简单工厂模式
简单工厂模式就是如果用来实现一个相同或相似功能的类太多,那么只提供一个.
例如,对于一个需求,要求对登录模块进行处理.需求主要是:用户名过长提示警告,密码错误提示警告,用户名未注册提示警告并添加一个注册按钮,登陆成功提示并嵌入输入框输入今日心情.
如果不用设计模式,我们可以将以上需求写成以下几个类:
//用户名和密码错误alert class LoginAlert { constructor(message){ this.message = message; } show() { ...//用户名和密码错误alert } } //没有用户的alert class NoUserAlert { constructor(message){ this.message = message; } show() { ...//没有用户的alert } } //登陆成功的alert class LoginSsAlert { constructor(message){ this.message = this.message; } show() { ...//登陆成功的alert } }
但是如果这样写,另一个人在写注册模块,那么他就可以直接使用你写的功能类.但是你写的太多的话,就非常不方便,此时,我们就可以写一个简单工厂.简单工厂就是将所有的实现相同功能或相似功能的多个类封装到一个函数里,这样,其他人只需要引入这个函数,然后通过这个函数就可以创建需要的对象即可.这样其他人实现的时候都不再关注创建这些对象到底依赖于哪个基类了,而只是知道这个函数就可以了.
实现简单工厂有两种方式:
- 方式一:依旧写多个类,但是在简单工厂函数里只返回一个需要的类.
//仍旧是以上三个类 ... //简单工厂函数 factory.js export const PopFactory = (name,message) => { switch(name){ case 'LoginAlert': return new LoginAlert(message); case 'NoUserAlert': return new NoUserAlert(message); case 'LoginSsAlert': return new LoginSsAlert(message); } } //使用简单工厂函数 main.js import { PopFactory } from '../desiginPatton/EasyFactory' const userError = PopFactory('LoginAlert',"用户名不能多余10个长度"); const passWordError = PopFactory('LoginAlert',"密码错误");
这种方式适合三个类的实现代码不太相同,不太能复用的情况.
- 方法二:只写一个类,在这个类中,相同的地方抽取出来成为公共的,不同的部分分别实现.
//新的工厂类 class CreatePop { constructor(type,message){ this.type = type; this.message = message; } show(){ switch(this.type){ case 'LoginAlert': show1(this.message); //三者不同的show方法 break; case 'NoUserAlert': show2(this.message); //三者不同的show方法 break; case 'LoginSsAlert': show3(this.message); //三者不同的show方法 break; } } } export const CreFactory = (type,message) => { return new CreatePop(type,message); } //使用 import {CreFactory} from '../desiginPatton/EasyFactory' const NoUserAlert = CreFactory('NoUserAlert',"没有用户,注册一个?"); const LoginSsAlert = CreFactory('LoginSsAlert',"请输入心情..");
这种方式适合三个类的实现代码很多地方都是相同的,是可以抽取出来成为公共的.