【设计模式Android】代理模式

作者: mymdeep | 来源:发表于2017-02-22 12:14 被阅读1509次

    设计模式Android 其他相关文章:
    【设计模式Android】设计模式六大原则

    定义:为其他对象提供一种代理以控制这个对象的访问

    代理模式中的角色

    Subject抽象主题

    抽象主题可以是一个抽象类也可以是一个接口。

    public interface  Subject{
        public void doSomeThing();
    }
    

    RealSubject具体实例

    被代理的角色,是逻辑的具体执行者。

    public class RealSubject implements Subject{
        @Override
        public void doSomeThing() {
            //do some things
        }
    }
    
    

    代理类

    用来代理实际类执行逻辑

    public class Proxy implements Subject{
        private Subject subject = null;
        public Proxy(){
            subject = new RealSubject();
        }
        @Override
        public void doSomeThing() {
            subject.doSomeThing();
        }
    }
    

    举个例子

    在这里我们举这样一个例子。
    比如我们在玩游戏的时候希望找个代练,代替我们升级打怪。这个这个代练就可以认为是一个代理。
    我们可以简单写一下做个对比:

    Subject抽象主题类

    我们在这里定义一下游戏玩家的抽象行为:

    public interface IGame {
         public void attack();
        public void move();
        public void dead();
        public void update();
    }
    

    RealSubject真是主题类

    在这里我们定义下玩家的实际行为:

    public class GamePlayer implements IGame
    {
        private String name;
        public GamePlayer(String name){
            this.name = name;
        }
        @Override
        public void attack() {
            System.out.println(name+"正在"+"攻击");
        }
    
        @Override
        public void move() {
            System.out.println(name+"正在"+"行走");
    
        }
    
        @Override
        public void dead() {
            System.out.println(name+"已经"+"死亡");
    
        }
    
        @Override
        public void update() {
            System.out.println(name+"已经"+"升级");
    
        }
    }
    

    代理类

    现在需要找一个类替我们去执行我们要执行的行为。

    public class GamePlayerProxy implements IGame {
        private IGame player = null;
        public GamePlayerProxy(IGame player){
            this.player = player;
        }
        @Override
        public void attack() {
            player.attack();
        }
    
        @Override
        public void move() {
            player.move();
        }
    
        @Override
        public void dead() {
            player.dead();
        }
    
        @Override
        public void update() {
            player.update();
        }
    }
    

    实例化执行

    我们现在看一下应该如何在程序中调用:

    public class Main {
        public static void main(String[] args) {
                IGame player = new GamePlayer("deep");
                IGame proxy = new GamePlayerProxy(player);
                proxy.move();
                proxy.attack();
                proxy.update();
                proxy.dead();
        }
    }
    

    为什么要用代理模式

    有些开发者看了这篇文章可能会问,我们在写程序中,为什么要用代理模式,我们直接商用上面提到的真是主题类RealSubject不就行了吗?
    可以是可以,但是不符合我们之前提到过的设计原则(【设计模式Android】设计模式六大原则

    隔离原则

    在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用, 其特征是代理类与委托类有同样的接口。

    开闭原则

    代理类不仅仅是一个隔离客户端和委托类的中介。我们还可以借助代理来在增加一些功能,而不需要修改原有代码,严重的复合开闭原则哦。

    优点:

    • 职责清晰,RealSubject只处理实际业务逻辑,不用关心其它。
    • 高扩展性,复合开闭原则,方便进行修改

    拓展

    普通代理

    客户端只访问代理,不访问真实角色。
    就如同上文中举的例子一样。调用者只知道代理而不知道真实角色,我们修改一下上面的例子:

    public class GamePlayerProxy implements IGame {
        private IGame player = null;
        public GamePlayerProxy(String name){
            this.player = new GamePlayer(name);
        }
        @Override
        public void attack() {
            player.attack();
        }
    
        @Override
        public void move() {
            player.move();
        }
    
        @Override
        public void dead() {
            player.dead();
        }
    
        @Override
        public void update() {
            player.update();
        }
    }
    
    

    修改一下调用,可以看出:

    public class Main {
        public static void main(String[] args) {
    
                IGame proxy = new GamePlayerProxy("deep");
                proxy.move();
                proxy.attack();
                proxy.update();
                proxy.dead();
    
        }
    }
    
    

    强制代理

    强制代理比较特殊,它是通过真实角色找到代理角色,我们还是修改一下上面的例子的代理类:

    public class GamePlayer implements IGame
    {
        private String name;
        private IGame proxy = null;
        public GamePlayer(String name){
            this.name = name;
            
        }
    
        public IGame getProxy() {
          this.proxy = new GamePlayerProxy(this);
          return this.proxy;
        }
    
        @Override
        public void attack() {
            if (this.getProxy()!=null){
                System.out.println(name+"正在"+"攻击");  
            }else {
                System.out.println("请指定代理");
            }
           
        }
    
        @Override
        public void move() {
            if (this.getProxy()!=null) {
                System.out.println(name + "正在" + "行走");
            }else {
                System.out.println("请指定代理");
            }
    
        }
    
        @Override
        public void dead() {
            if (this.getProxy()!=null) {
                System.out.println(name + "已经" + "死亡");
            }else {
                System.out.println("请指定代理");
            }
    
        }
    
        @Override
        public void update() {
            if (this.getProxy()!=null) {
                System.out.println(name + "已经" + "升级");
            }else {
                System.out.println("请指定代理");
            }
    
        }
        private boolean isProxy(){
            if (this.proxy == null){
                return false;
            }else {
                return  true;
            }
        }
    }
    

    增加一个私有方法,检查是否有指定的代理。通过这个方式你可以看出,你想绕过代理直接访问真实的类,但是,真实类,还是给你返回代理。我们访问如下:

    public class Main {
        public static void main(String[] args) {
    
            IGame player = new GamePlayer("deep");
            player.move();
            player.attack();
            player.update();
            player.dead();
    
        }
    }
    

    总结

    代理模式跟中介者模式容易搞混,之后的文章我们会再介绍一下中介者模式,并进行一下对比。

    相关文章

      网友评论

        本文标题:【设计模式Android】代理模式

        本文链接:https://www.haomeiwen.com/subject/xbvswttx.html