zoukankan      html  css  js  c++  java
  • 第三章 --- 关于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);
    
  • 相关阅读:
    python入门 类的继承和聚合(五)
    如何快速找到多个字典中的公共键(1.4)
    python输入输出(二)
    python入门 集合(四)
    LOJ 3093: 洛谷 P5323: 「BJOI2019」光线
    LOJ 3049: 洛谷 P5284: 「十二省联考 2019」字符串问题
    【比赛游记】FJOI2019瞎打记
    ICPC World Finals 2019 题解
    LOJ 3043: 洛谷 P5280: 「ZJOI2019」线段树
    LOJ 2483: 洛谷 P4655: 「CEOI2017」Building Bridges
  • 原文地址:https://www.cnblogs.com/erbingbing/p/5600196.html
Copyright © 2011-2022 走看看