Java版设计模式之【代理模式】

218 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

概述

又叫委托模式,结构型设计模式,能够提供对象的替代品,控制着对于原对象的访问,是一个使用率非常高的模式。

角色

抽象主题:申明了服务的接口,代理类必须遵循该接口。

服务主题:服务类,是被代理的一方,提供了实际业务逻辑的服务接口。

代理主题:代理类,包含了一个指向服务对象的引用成员变量,负责在需要的时候创建或删除服务对象,代理完成其任务,通常情况下会在服务类前后做预处理和善后处理工作。

模板

抽象接口:申明了代理类跟服务类必须实现的功能。

public interface IGamePlayer {
    /**
     * 杀怪
     */
    public void killBoss();
    /**
     * 通关
     */
    public void clearance();
}

服务类:实际的服务处理逻辑

public class GamePlayer implements IGamePlayer{
    private String name;

    public GamePlayer(String name) {
        this.name = name;
    }

    @Override
    public void killBoss() {
        System.out.println(this.name + "三打白骨精!");
    }

    @Override
    public void clearance() {
        System.out.println(this.name + "打死了白骨精!");
    }
}

代理类:对服务类进行代理

public class GamePlayerProxy implements IGamePlayer{
    private IGamePlayer player;

    public GamePlayerProxy(IGamePlayer player) {
        this.player = player;
    }

    /**
     * 记录打怪的时间
     */
    private void log(){
        System.out.println("打怪时间:" + new Date().toString());
    }

    /**
     * 代理方法
     */
    @Override
    public void killBoss() {
        this.log();
        player.killBoss();
    }

    /**
     * 代理方法
     */
    @Override
    public void clearance() {
        player.clearance();
        this.count();
    }

    /**
     * 计算升级所用的时间
     */
    private void count(){
        System.out.println("打死白骨精耗费了三天时间");
    }
}

客户端:客户端的使用案例

public class ProxyPattern {
    public static void main(String[] args) {
        // 服务类实例
        IGamePlayer player = new GamePlayer("孙悟空");
        // 代理类实例
        IGamePlayer proxy = new GamePlayerProxy(player);
        // 方法调用
        proxy.killBoss();
        proxy.clearance();
    }
}

小结

优点

开闭原则:可以在不对服务端或客户端做出修改的情况下创建新的代理

高扩展性:可以在客户端毫无察觉的情况下控制服务对象,只要服务类实现了接口,代理类就完全可以在不做任何修改的情况下代理各种代理类。

智能化:代理类可以在运行时才缺点需要去代理的服务类。

缺点

代码可能会变得复杂,因为需要新建许多类,同时服务响应也有可能会延迟。

适用场景

  • 远程代理:为一个位于不同地址空间的对象提供一个局部代理对象
  • 虚拟代理:创建一些耗费较多资源的对象时,可以先创建代理对象,将真实对象的创建延迟
  • 保护代理:控制对一个对象的访问,可以给不同的用户提供不同的使用权限
  • 缓存代理:为某一个目标操作的结果提供临时的存储空间,以便于多个客户端共享
  • 同步代理:几个用户使用一个对象而不冲突
  • 智能引用:提供一些额外的操作,例如访问记录的流量和次数等