• js代理模式


    代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对象。替身对象对请求做出一些处理之后,再把请求转交给本体对象。

    代理模式类图:

    在上面类图中,代理模式所涉及的角色有三个:

    抽象主题角色(Person):声明了真实主题和代理主题的公共接口,这样一来在使用真实主题的任何地方都可以使用代理主题。

    代理主题角色(Friend):代 理主题角色内部含有对真实主题的引用,从而可以操作真实主题对象;代理主题角色负责在需要的时候创建真实主题对象;代理角色通常在将客户端调用传递到真实 主题之前或之后,都要执行一些其他的操作,而不是单纯地将调用传递给真实主题对象。例如这里的PreBuyProduct和PostBuyProduct 方法就是代理主题角色所执行的其他操作。

    真实主题角色(RealBuyPerson):定义了代理角色所代表的真是对象。

    附:在实际开发过程中,我们在客户端添加服务引用的时候,在客户程序中会添加一些额外的类,在客户端生成的类扮演着代理主题角色,我们客户端也是直接调用这些代理角色来访问远程服务提供的操作。这个是远程代理的一个典型例子。

    先看一下C#的代理模式:

    namespace 代理模式
    {
        class Program
        {
            static void Main(string[] args)
            {
                SchoolGirl jiaojiao = new SchoolGirl();
                jiaojiao.Name = "李娇娇";
    
                Proxy daili = new Proxy(jiaojiao);
    
                daili.GiveDolls();
                daili.GiveFlowers();
                daili.GiveChocolate();
    
    
                Console.Read();
            }
        }
    
        //送礼物
        interface GiveGift
        {
            void GiveDolls();
            void GiveFlowers();
            void GiveChocolate();
        }
    
        class Proxy : GiveGift
        {
            Pursuit gg;
            public Proxy(SchoolGirl mm)
            {
                gg = new Pursuit(mm);
            }
    
    
            public void GiveDolls()
            {
                gg.GiveDolls();
            }
    
            public void GiveFlowers()
            {
                gg.GiveFlowers();
            }
    
            public void GiveChocolate()
            {
                gg.GiveChocolate();
            }
        }
    
        class Pursuit : GiveGift
        {
            SchoolGirl mm;
            public Pursuit(SchoolGirl mm)
            {
                this.mm = mm;
            }
            public void GiveDolls()
            {
                Console.WriteLine(mm.Name + " 送你洋娃娃");
            }
    
            public void GiveFlowers()
            {
                Console.WriteLine(mm.Name + " 送你鲜花");
            }
    
            public void GiveChocolate()
            {
                Console.WriteLine(mm.Name + " 送你巧克力");
            }
        }
    
        class SchoolGirl
        {
            private string name;
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
        }
    }

    js模拟高级语言的代理模式:

    var SchoolGirl = function(name){
            this.name = name;
        };
        
        var Pursuit = function(mm){
            this.mm = mm;
        };
        Pursuit.prototype.giveDolls = function(){
            alert(this.mm.name + '送你洋娃娃');
        };
        Pursuit.prototype.giveFlowers = function(){
            alert(this.mm.name + '送你鲜花');
        };
        Pursuit.prototype.giveChocolate = function(){
            alert(this.mm.name + '送你巧克力');
        };
    
        var Proxy = function(mm){
            this.gg = new Pursuit(mm);
        };
        Proxy.prototype.giveDolls = function(){
            this.gg.giveDolls();
        };
        Proxy.prototype.giveFlowers = function(){
            this.gg.giveFlowers();
        };
        Proxy.prototype.giveChocolate = function(){
            this.gg.giveChocolate();
        };
    
    
        //调用:
        var jiaojiao = new SchoolGirl();
        jiaojiao.name = "李娇娇";
    
        var daili = new Proxy(jiaojiao);
    
        daili.giveDolls();
        daili.giveFlowers();
        daili.giveChocolate();

    js语言特性的代理模式:

    var Flower = function(){};
    
        var Pursuit = {
            sendFlower:function(target){
                var flower = new Flower();
                target.receiveFlower(flower);
            }
        };
    
        var Proxy = {
            sendFlower:function(target){
                Pursuit.sendFlower(target);
            }
        };
    
        var SchoolGirl = {
            receiveFlower:function(flower){
                console.log('收到花' + flower);
            }
        };
    
        //调用:
        Proxy.sendFlower(SchoolGirl);

    js虚拟代理实现图片预加载:

    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('file:// /C:Users/svenzeng/Desktop/loading.gif');
                    img.src = src;
                }
            }
        })();
    
        //调用:
        proxyImage.setSrc('http://imgcache.qq.com/music/photo/k/000GGDys0yAonk.jpg');

    js缓存代理实现计算器:

    //计算乘积
        var mult = function(){
            var a = 1;
            for(var i=0,l=arguments.length; i<l; i++){
                a = a * arguments[i];
            }
            return a;
        };
    
        //计算加和
        var plus = function(){
            var a = 0;
            for(var i=0,l=arguments.length; i<l; i++){
                a = a + arguments[i];
            }
            return a;
        };
        
        //创建缓存代理工厂
        var createProxyFactory = function(fn){
            var cache = {};
            return function(){
                var args = [].join.call(arguments,',');
                if(args in cache){
                    return cache[args];
                }
                return cache[args] = fn.apply(this,arguments);
            }
        };
    
    
        //调用:
        var proxyMult = createProxyFactory(mult),
            proxyPlus = createProxyFactory(plus);
    
        alert(proxyMult(1,2,3,4)); //24
        alert(proxyMult(1,2,3,4)); //24
        alert(proxyPlus(1,2,3,4)); //10
        alert(proxyPlus(1,2,3,4)); //10

    总结:代理模式包括许多小分类,在js开发中最常用的是虚拟代理和缓存代理。虽然代理模式非常有用,但我们在编写业务的时候,往往不需要去预先猜测是否需要使用代理模式。当真正发现不方便直接访问某个对象的时候,再编写代理也不迟。

  • 相关阅读:
    Win10创意者更新秋季版激活秘籍
    将刷了Android的Lumia恢复为WP系统
    给Lumia 520/521/525/526/720刷Android系统
    DNS解析
    遍历对象目录
    PE注入
    利用NtCreateThreadEx注入
    利用CreateRemoteThread注入
    APC注入
    SetWindowHookEx()注入
  • 原文地址:https://www.cnblogs.com/gongshunkai/p/6593886.html
Copyright © 2020-2023  润新知