工厂模式
工厂模式常用于创建对象,工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。
简单的工厂模式可以理解为解决多个相似的问题;这也是她的优点,比如如下代码:
/**
* 工厂模式
*/
function CreatePerson(name,age,sex) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.sayName = function(){
return this.name;
}
return obj;
}
var p1 = new CreatePerson("longen",'28','男');
var p2 = new CreatePerson("tugenhua",'27','女');
优点:能解决多个相似的问题。
缺点:不能确定对象的类型。
单例模式
什么是单体模式?单体模式是一个用来划分命名空间并将一批属性和方法组织在一起的对象,如果它可以被实例化,那么它只能被实例化一次。
单体模式的优点是:
1,可以用来划分命名空间,减少全局变量的数量。
2,使用单体模式可以使代码组织的更为一致,使代码容易阅读和维护。
3,可以被实例化,且实例化一次。
/**
* 在执行当前 Single 只获得唯一一个对象
*/
var Singleton = function(name){
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function(){
return this.name;
}
// 获取实例对象
function getInstance(name) {
if(!this.instance) {
this.instance = new Singleton(name);
}
return this.instance;
}
// 测试单体模式的实例
var a = getInstance("aa");
var b = getInstance("bb");
什么时候使用单例模式:例如想要实例化一个div,每次对它进行显示和隐藏,但是又不想每次重新创建,就可用单例模式。可减少重绘和重流。
模块模式
模块模式的思路是为单体模式添加私有变量和私有方法能够减少全局变量的使用;如下就是一个模块模式的代码结构:
var singleMode = (function(){
// 创建私有变量
var privateNum = 112;
// 创建私有函数
function privateFunc(){
// 实现自己的业务逻辑代码
}
// 返回一个对象包含公有方法和属性
return {
publicMethod1: publicMethod1,
publicMethod2: publicMethod1
};
})();
模块模式使用了一个返回对象的匿名函数。在这个匿名函数内部,先定义了私有变量和函数,供内部函数使用,然后将一个对象字面量作为函数的值返回,返回的对象字面量中只包含可以公开的属性和方法。这样的话,可以提供外部使用该方法;由于该返回对象中的公有方法是在匿名函数内部定义的,因此它可以访问内部的私有变量和函数。
我们什么时候使用模块模式?
如果我们必须创建一个对象并以某些数据进行初始化,同时还要公开一些能够访问这些私有数据的方法,那么我们这个时候就可以使用模块模式了。
代理模式
代理是一个对象,它可以用来控制对本体对象的访问,它与本体对象实现了同样的接口,代理对象会把所有的调用方法传递给本体对象的;代理模式最基本的形式是对访问进行控制,而本体对象则负责执行所分派的那个对象的函数或者类,简单的来讲本地对象注重的去执行页面上的代码,代理则控制本地对象何时被实例化,何时被使用;我们在上面的单体模式中使用过一些代理模式,就是使用代理模式实现单体模式的实例化,其他的事情就交给本体对象去处理;
代理的优点:
- 代理对象可以代替本体被实例化,并使其可以被远程访问;
- 它还可以把本体实例化推迟到真正需要的时候;对于实例化比较费时的本体对象,或者因为尺寸比较大以至于不用时不适于保存在内存中的本体,我们可以推迟实例化该对象;
我们先来理解代理对象代替本体对象被实例化的列子;比如现在京东ceo想送给奶茶妹一个礼物,但是呢假如该ceo不好意思送,或者由于工作忙没有时间送,那么这个时候他就想委托他的经纪人去做这件事,于是我们可以使用代理模式来编写如下代码:
// 先申明一个奶茶妹对象
var TeaAndMilkGirl = function(name) {
this.name = name;
};
// 这是京东ceo先生
var Ceo = function(girl) {
this.girl = girl;
// 送结婚礼物 给奶茶妹
this.sendMarriageRing = function(ring) {
console.log("Hi " + this.girl.name + ", ceo送你一个礼物:" + ring);
}
};
// 京东ceo的经纪人是代理,来代替送
var ProxyObj = function(girl){
this.girl = girl;
// 经纪人代理送礼物给奶茶妹
this.sendGift = function(gift) {
// 代理模式负责本体对象实例化
(new Ceo(this.girl)).sendMarriageRing(gift);
}
};
// 初始化
var proxy = new ProxyObj(new TeaAndMilkGirl("奶茶妹"));
proxy.sendGift("结婚戒"); // Hi 奶茶妹, ceo送你一个礼物:结婚戒
什么时候使用代理模式:使用虚拟代理实现图片的预加载
发布-订阅模式/观察者模式
支持简单的广播通信,当对象状态发生改变时,会自动通知已经订阅过的对象。
/**
* 发布订阅模式
*/
var EventCenter = (function(){
var events = {};
/*
{
my_event: [{handler: function(data){xxx}}, {handler: function(data){yyy}}]
}
*/
// 绑定事件 添加回调
function on(evt, handler){
events[evt] = events[evt] || [];
events[evt].push({
handler:handler
})
}
function fire(evt, arg){
if(!events[evt]){
return
}
for(var i=0; i < events[evt].length; i++){
events[evt][i].handler(arg);
}
}
function off(evt){
delete events[evt];
}
return {
on:on,
fire:fire,
off:off
}
}());
var number = 1;
EventCenter.on('click', function(data){
console.log('click 事件' + data + number++ +'次');
});
EventCenter.off('click'); // 只绑定一次
EventCenter.on('click', function(data){
console.log('click 事件' + data + number++ +'次');
});
EventCenter.fire('click', '绑定');
什么时候使用发布-订阅模式:
对于第一点,我们日常工作中也经常使用到,比如我们的ajax请求,请求有成功(success)和失败(error)的回调函数,我们可以订阅ajax的success和error事件。我们并不关心对象在异步运行的状态,我们只关心success的时候或者error的时候我们要做点我们自己的事情就可以了
参考:
1.https://www.jianshu.com/p/d8c1c426d028
2.https://www.cnblogs.com/tugenhua0707/p/5198407.html
2095

被折叠的 条评论
为什么被折叠?



