设计模式—代理模式

来源:互联网 发布:先学c还是先学java 编辑:程序博客网 时间:2024/05/16 01:51

代理模式:为其他对象提供一种代理以控制对这个对象的访问。
日常生活中,我们也有着很多的代理,如明星与经纪人,经纪人就是明星的代理;还有比如追女孩,碍于不了解,你去找一个比你熟知这个女孩的人去追她;这也是一种代理;
代理和本体需呀实现同一接口,这样做的好处就是在任何使用本体的地方都可以替换成使用代理,另外用户可以放心的请求代理,因为用户只关心是否能够得到想要实现的结果。
我们来模拟一下利用中间人(也就是中间人)追女孩的过程:

public class Girl{    private string _name;    public string Name     {        get { return this._name; }        set { this._name = value; }    }}// 送礼物接口public interface IGiveGift{    void GiveFlower();}// 本体类public class Pursult : IGiveGift{    private Girl _girl;    public Pursult(Girl girl)     {        this._girl = girl;    }    public void GiveFlower()     {        Console.WriteLine("{0},送你花", this._girl.Name);    }}// 代理类public class Proxy : IGiveGift{    Pursult boy;    public Proxy(Girl girl)     {        boy = new Pursult(girl);    }    public void GiveFlower()     {        boy.GiveFlower();    }}// 客户端调用Girl mm = new Girl();mm.Name = "peiyi";IGiveGift zp = new Proxy(mm);zp.GiveFlower();

这就是一个代理模式,下面我们来看一下代理的意义:
1.利用虚拟代理来做惰性加载,假设我们在执行需要调用一个很大的js文件,如果不利用代理的话,我们只能在页面加载时,对这个js文件进行加载,这样肯定会拖慢我们加载的速度,如果利用代理的话,我们可以先虚拟出来一个对象,作为代理,在需要执行相应的操作时,在去加载我们的js文件,将我们虚拟出来的代理对象覆盖。
如下面例子,模拟按下F2,查看控制台输出

var miniConsole = function () {    var cache = [];    var handler = function (ev) {        if (ev.keyCode === 113) {            var script = document.createElement("script");            script.onload = function () {                for (var i = 0, fn; fn = cache[i++];) {                    fn();                }            };            script.src = "test.js";            document.getElementsByTagName("head")[0].appendChild(script);            document.body.removeEventListener("keydown", handler);        }    };    document.body.addEventListener("keydown", handler, false);    return {        log: function () {            var args = arguments;            cache.push(function () {                return miniConsole.log.apply(miniConsole, args);            })        }    };}();miniConsole.log(11111);// test.js内代码var miniConsole = {    log: function () {        console.log(Array.prototype.join.call(arguments));    }       };

2.实现单一职责,利用代理减少本体职责,使类需要改变的原因减少,例如我们实现一个图片的预加载功能:

var myImage = function () {    var imgNode = document.createElement("img"),        img = new Image();    document.body.appendChild(imgNode);    img.onload = function () {        imgNode.src = img.src;    }    return {        setSrc: function (src) {            imgNode.src = "C:\\Users\\John\\Desktop\\js练习、 (1)\\msg-icon.png";            img.src = src;        }    };}();        myImage.setSrc("http://www.lsgogroup.com/Public/Blog/images/test4.jpg");

你可能会这么去写代码,但是当我们的网速达到足够快,不许要进行预加载时,我们这是就要去修改我们的myImage,所以我们可以换一种思路,那就是使用我们的代理模式,因为代理和本体相分离,我们让本体来做添加图片src的工作,而代理是用来做预先加载另外一张图片的工作,这样,假如我们不使用预加载了,我只需要调用本体,根本需要对其做任何更改。

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("C:\\Users\\John\\Desktop\\js练习、 (1)\\msg-icon.png");            img.src = src;        }    };}();proxyImage.setSrc("http://www.lsgogroup.com/Public/Blog/images/test4.jpg");
0 0