javascript设计模式
一个模式就是一个可重用的方案,可应用于在软件设计中的常见问题。模式的另一种解释就是一个我们如何解决问题的模板 - 那些可以在许多不同的情况里使用的模板。
设计模式的好处:
①模式是行之有效的解决方法:他们提供固定的解决方法来解决在软件开发中出现的问题,这些都是久经考验的反应了开发者的经验和见解的使用模式来定义的技术。
②模式可以很容易地重用:一个模式通常反映了一个可以适应自己需要的开箱即用的解决方案。这个特性让它们很健壮。
③模式善于表达:当我们看到一个提供某种解决方案的模式时,一般有一组结构和词汇可以非常优雅地帮助表达相当大的解决方案。
创建型模式
一、单例模式
单例模式限制一个类只能有一个实例化对象。经典的实现方式是,创建一个类,这个类包含一个方法,这个方法在没有对象存在的情况下,将会创建一个新的实例对象。如果对象存在,这个方法只是返回这个对象的引用。
实例:
function SetBOSS(name) {
this.BOSS = name;
}
SetBOSS.prototype.getName = function() {
console.log(this.BOSS);
};
var SingletonSetBOSS = (function() {
var BOSS = null;
return function(name) {
if (!BOSS) {//如果没有对象,则创建一个新的实例对象
BOSS = new SetBOSS(name);
}
//若if语句执行,返回该语句中创建的对象
//如果if语句不执行,则对象存在,返回这个对象的引用
return BOSS;
}
})();
SingletonSetBOSS('a').getName(); //输出:a
SingletonSetBOSS('b').getName(); //输出:a
SingletonSetBOSS('c').getName(); //输出:a
总结:如果对象已经创建,返回对象的引用
二、工厂模式
工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象,用工厂方法代替new操作的一种模式。
实例:
class Creator {
create(name) {
return new Phone(name)
}
}
class Phone {
constructor(name) {
this.name = name
}
}
var creator = new Creator()
var Apple = creator.create('Apple')
console.log(Apple.name) // Apple
var Android = creator.create('Android')
console.log(Android.name) // Android
总结:实现了构造函数和创建者分离,对new操作进行了封装
三、原型模式
原型模型是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
实例:
var vehiclePrototype = {
init: function ( carModel ) {
this.model = carModel;
},
getModel: function () {
console.log(this.model);
}
};
function vehicle( model ) {
function F() {};
F.prototype = vehiclePrototype;
var f = new F();
f.init( model );
return f;
}
var car = vehicle( "Ford" );
car.getModel();
结构性模式
一、适配器模式
适配器模式主要解决两个软件实体间的接口不兼容的问题,对不兼容的部分进行适配。
实例:
class ChangHongTV {
show() {
console.log('长虹电视')
}
}
class HaierTV {
display() {
console.log('海尔电视')
}
}
// 定义适配器类, 对HaierTV类进行封装
class HaierTVAdapter {
show() {
var HaierTV = new HaierTV()
return HaierTV.display()
}
}
function render(TV) {
if (TV.show instanceof Function) {
TV.show()
}
}
render(new ChangHongTV()) // 长虹电视
render(new HaierTVAdapter()) // 海尔电视
适配器模式在本实例中,主要体现在 HaierTV类中的display方法不兼容,通过HaierTVAdapter类的封装,提供show方法接口。
总结:适配器模式主要解决两个接口之间不匹配的问题,不会改变原有的接口,而是由一个对象对另一个对象的包装。
二、代理模式
代理模式是为一个对象提供代用品或占位符,以便控制对它的访问。
实例:
//代理对象
var proxyImage = (function(){
var img = new Image();
img.onload = function(){
//代理对象img加载真实图片src完成后将src传递给本体对象显示
myImage.setSrc(this.src)
}
return {
setProxySrc: function(src){
//代理对象控制本体对象使用加载图片src
myImage.setSrc('loding.gif')
//代理对象的img对象获取将要传递给本体对象的真实图片src
img.src = src
}
}
})()
//通过代理对象来对本体对象进行访问
proxyImage.setProxySrc('https://xxx.xxx.com/xxx.jpg')
本实例为代理模式中的虚拟代理,通过代理对象获取实际显示图片地址并进行加载,同时先让本体对象显示预加载图片,待代理对象将实际图片地址加载完毕后传递给本体对象进行显示即可。