写在前面:人生的时光很短暂 ,有的时候莫要为不可掌控的事情进行愁闷,专心做自己就好
今天要分享的是javascript的“创建型”设计模式,最近沉迷于设计模式,
导语:创建型设计模式是一种类处理对象创建的设计模式,通过某种方式控制对象的创建来避免基本对象创建时可能导致的设计上的问题或增加设计上的复杂度
1.简单工厂模式
意思:静态工厂方法,由一个工厂对象决定创建某一种产品的实例,主要用来创建某一种产品对象类的实例。
前提需求功能:表单输入 并弹出警示框
初始代码:
var LoginAlert = function(text){ this.content = text; } LoginAlert.prototype.show=function(){ alert(this.content) } //检验姓名 var userNameAlert = new LoginAlert("请输入正确的名字"); userNameAlert.show(); //检验木密码 var passwordAlert =new LoginAlert("请输入正确的密码"); passwordAlert.show();
新增需求:此时需要增加一个确认信息框
var LoginMsgConfirm = function(text){ this.content = text; } LoginMsgConfirm.prototype.show = function(){ alert(this.content); } var loginConfirm = new LoginMsgConfirm(); loginConfirm.show();
在项目中C人对A说要复用这个表单输入判断,于是A将这三个类名字全部告诉A,这对C而言,这么多类名字无疑是无用的,而且每次调用时候,都要分别调用,单独创建一次重复度较高。
var PopFactory = function(name){ switch(name){ case 'alert': return new LoginAlert(); break; case 'confirm':return new userNameAlert(); break; case 'prompt': return new LoginMsgConfirm();break; } }
这样调用的时候只需要知道一个PopFactory 和调用的类型就可以了,但是对于提示框部分 有许多重复的方法,比如show方法,这也是简单的工厂函数,用来创建相似的对象
//对于输入框的部分 function createPop(type,text){ var o =new Object; o.content =text; o.show =function(){ //显示方法 } if(type == 'alert'){ //提示框部分 } if(type == 'prompt'){ //确认框部分 } return o; } var userNameAlert =createPop('alert','请输入正确的名字')
在开发中少量的创建全局变量,对于同一类的对象在不同的需求中重复性的使用,很多时候不需要重复创建,代码复用是面向对象编程的一条准则。通过简单工厂创建可以让这些对象共用一些资源而又私有一些资源,
2.工厂方法模式
// 工厂模式:本意就是将实际创建对象推迟到子类中,采用安全的工厂方法 避免别人在使用的时候少创建了这样的一个类没有使用new方法调用该类 var Factory =function(type,content){ if(this instanceof Factory){ var s =new this[type](content); return s; }else{ return new Factory(type,content); } } Factory.prototype ={ BasketBall:function(content){ //内容 }, Football:function(content){ //内容 }, Badminton:function(content){ this.content =content; (function(content){ var div =document.createElement('div'); div.innerHTML =content; div.style.color="#rrr"; document.getElementsByTagName("body").appendChild(div); })() } } //调用 var data = [ {type:'BasketBall',content:'uuuu'}, {type:'Football',content:'Football 啦啦啦啦阿拉'}, ]
安全模式类:就是屏蔽使用类造成错误,比如 写了一个Demo类,但是其他人调用的时候可能不知道这是一个构造函数,因此可能会导致错误等
通过工厂模式方法我们可以轻松创建多个类的实例对象,这样的工厂方法对象在创建对象的方式上也避免类使用者与对象类之间的耦合,用户不必关心创建该对象的具体类,只需要调用工厂方法即可。
3.抽象工厂模式
通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责某一类的创建,将具有相同属性和行为的类抽出来在一起
var VehicleFactory =function(subType,superType){ if(typeof VehicleFactory[superType] == 'function'){ function F(){} F.prototype =new VehicleFactory[superType](); subType.constructor = subType; subType.prototype = new F(); }else{ throw new Error("没有该抽象类"); } } //小汽车抽象类 VehicleFactory.Car = function(){ this.type = 'car' } VehicleFactory.Car.prototype={ getPrice:function(){ return new Error("抽象方法不能调用") }, getSpeed:function(){ return new Error("抽象方法不能嗲用") } }
//...汽车抽象类、卡车抽象类
使用抽象类
var AD = function(price,speed){ this.price =price; this.speed =speed; } //抽象工厂对car的继承 VehicleFactory(AD,"Car"); AD.prototype.getPrice=function(){ return this.price; } AD.prototype.getSpeed =function(){ return this.speed; }
var Human =function(params){ this.skill = params && params.skill || '保密'; this.hobby =params && params.hobby || '不方便透露'; } Human.prototype ={ getSkill:function(){ return this.skill; }, getHobby:function(){ return this.hobby } } var Named =function(name){ var that =this; //构造函数解析姓名的姓和名字 (function(name,that){ that.wholeName =name; if(name.indexOf(' ')>-1){ that.firstName = name.slice(0,name.indexOf(' ')); that.secondName = name.slice(name.indexOf(' ')); } })(name,that) }
使用该类
// 基本类完成后 构建一个应聘 var Person = function(name){ //创建应聘者缓存对象 var _person =new Human(); _person.name = new Name(name); ret return _person; } //使用的时候 var peoson =new Person("吗 u");
建造者模式比起工厂模式更加的复杂
建造者和工厂的共同点:创建的结果都是一个完整的个体,我们对创建过程不得而知,我们只了解到创建结果对象,
构造者模式:我们关注的对象的创建过程,因此通常将创建对象的类模块化,这样被创建的类的每一个模块都可以得到灵活的运用和高质量的复用
5.原型模式
用原型实例指向创建对象的类,使用于创建新的对象的类的共享原型对象的属性和方法,原型模式就是将原型对象指向创建对象的类,使这些类共享原型对象的方法和属性
原型模式就是将可复用的、可共享的、耗时大的从基类中提出来然后放在其原型中,然后子类通过组合继承或者寄生组合式而将方法和属性继承下来。
让多个对象分享同一个原型对象的属性和方法
6.单例模式
单例模式又称为单体模式,是只允许实例化一次的对象类,其实就是用一个对象来规划一个命名空间,井井有条的管理对象上的属性与方法
var Yan ={ g:function(id){ return document.getElementById(id); }, css:function(id,key,value){ this.g(id).style[key] = value; }, utils:{ util:function(){ }, util2:function(){ } } }
通过单例模式来管理代码库的各个模块
单例模式的其他作用,定义静态变量,
var Yan ={ name:33, age:45, }
但是这样定义的变量,在外面能够访问并且能够改变其的值,所以如果想要这些是静态变量不变,
var Conf =(function(){ var conf ={ MAX_NUM :100, COUNT:200, } return { get:function(name){ return conf[name] ? conf[name]:null } } })();
这样只定义在对象内部,只提供取值方法,不提供赋值的方法,这样外界就不会改变来值了
模式 | 作用 | 优点 | 缺点 |
简单工厂模式 | 静态工厂方法,由一个工厂对象决定创建某一种产生对象的实例 | 代码复用 | |
工厂方法模式 | 对产品类的抽象使其创建业务主要负责用户创建多累产品的实例,采用安全模式创建的工厂类有利于创建对的对象 | 轻松创建多个类的实例对象 | |
抽象工厂模式 | 对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建某一类产品的实例 | 制定类类的结构,也就区别与简单工厂模式创建单一对象 | |
建造者模式 | 将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示 | 每一个模块都可以得到灵活的运用与高质量的复用 | |
原型模式 | 指向创建对象的类,适用于创建新的对象的类共享原型对象的属性和方法 | 让多个对象分享同一个原想对象的属性和方法 | |
单例模式 | 单体模式,是只允许实例化一次的对象类, | 只允许实例化一次的对象类,有可以节省空间 |