第三章 --- 关于Javascript 设计模式 之 代理模式

第一、定义: 代理模式是为一个对象提供代用品或者占位符,以便控制对它的访问。
    
    比如说,某男生小明想向他的女神 A 表白,刚好小明认识的一个女生B 和 女神A 是好朋友,那么小明就想让 女生B 帮忙送花给 女神A 。

    这个就是一个代理模式。
第二、Show Code
var Flower = function(){};

var xiaoming = {
	sendFlower: function(target){
		var flower = new Flower();
		target.receiveFlower( flower );
	}
};

var B = {
	receiveFlower: function(flower){
		A.receiveFlower(flower);
	}
};

var A = {
	receiveFlower: function(flower){
		console.log("收到花了" + flower);
	}
} 

xiaoming.sendFlower(B);

到这里我们就实现了简单的 代理模式,那就有同学问了,这个代理模式写出来有什么用呢?

对,不仅没什么用,反而让程序的代码变复杂了。

那我们假设这么一种情况,在女神A 的心情好的时候 小明送花的成功率会提高 60%; 而当女神A 心情不好的时候,小明送花的成功率只有 1%; (毕竟小明送的不是宝马车 =。= )

那么女生B 是刚刚好能够知道女神A 的心情的,那么通过 女生B 确定好送花的时间,那么小明的成功率是不是会成功很多呢,从此走上人生巅峰呢?

好,我们接着往下 完善 上面的代码。

var Flower = function(){};

var xiaoming = {
	sendFlower: function(target){
		var flower = new Flower();
		target.receiveFlower( flower );
	}
};

var B = {
	receiveFlower: function(flower){
		A.listenGoodMood(function(){  //监听女神A 的心情
			A.receiveFlower(flower);
		});	
	}
};

var A = {
	receiveFlower: function(flower){
		console.log("收到花了" + flower);
	},
	listenGoodMood: function( fn ){
		setTimeout(function(){
			fn();
		},10000); //十秒钟后女神的心情变好
	}
} 

xiaoming.sendFlower(B);	

这样,我们就监听到了女神A 的心情变化,再送花给她,那么小明的成功率会高很多啦~

第三、代理模式也是分种类的,这里我们 把 它分为 保护代理 和 虚拟代理
    
    1、保护代理:还是拿上面的例子来说,如果有人继续给 女神A 送各种礼物,但是在 女生B 哪里就已经有了一个 过滤条件,有没房子啊,又没车啊。等等,如果要求达不到,那么这个请求直接就在 B 那里就 过滤掉了。

    2、虚拟代理: 在上面的 案例中 new flower() 在程序的世界里是一种昂贵的 操作,那么,我们可以把  new flower() 这个过程 放到当 女神A 心情好的时候我们再去 new flower(), 这就是代理的另外一种模式,叫做 虚拟代理。
第四:我们来用 虚拟代理的方式 来实现 图片预加载。(我们还是直接上代码)

(图片预加载技术是一种常用的web技术,如果直接给 img 标签设置 src 属性,由于图片过大或者网络不佳,图片的位置往往有一段时间是空白的,我们常见的做法是 先用一张loading 图 来占位,然后异步的方式加载图片,等图片加载好了再把它填充到img 节点里)
var myImage = (function(){
	var imgNode = document.createElement('img');
	document.body.appendChild(imgNode);

	return {
		setSrc: function(src){
			imgNode.src = src;
		}
	}
})();

var proxyImage = (function(){
	var img = new Image;
	img.onload = function(){
		myImage.setSrc(this.src);
	}

	return {
		setSrc: function(src){
			myImage.setSrc("img/donated.jpg");
			img.src = src; 
		}
	}
})();


proxyImage.setSrc("http://g.hiphotos.baidu.com/zhidao/pic/item/63d9f2d3572c11dfff955ae3612762d0f603c2ae.jpg");

效果实现了

最后我们再实现一个 缓存代理模式

var mult = function(){
	var a = 1;
	for (var i = 0; i < arguments.length; i++) {
		a = a*arguments[i]
	};

	return a;
}	

// var result = mult(1,2,3,4);
// console.log(result);

var proxyMult =(function(){
	var cache = {};
	return function(){
		var args = Array.prototype.join.call(arguments,',');
		if(args in cache){
			return cache[args];
		}

		return cache[args] = mult.apply(this,arguments);
	}
})();

var result = proxyMult(1,2,3,4);
var result1 = proxyMult(1,2,3,4);
console.log(result,result1);
posted @ 2016-06-20 12:32  SmallW  阅读(459)  评论(0编辑  收藏  举报