设计模式演化之代理模式

本文介绍了代理模式的定义,通过日志管理的例子展示了代理模式的演化过程,从简单的工具类到实现共同接口的代理类。代理模式能够实现职责清晰、易于扩展和智能化,但可能带来运行效率下降的问题。适用场景包括需要统一控制多处对象方法的使用,以及需要扩展对象功能但基类无法修改的情况。
摘要由CSDN通过智能技术生成
定义

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

演化

1.我们平时写代码的时候,免不了打印一些日志出来,方便调试。

Log.d("TAG", "Somethings")

不过,这种打印日志的方式,一般只在测试期间使用。当发布正式版本时候,需要关闭日志功能。因此,我们一般会这么写:

if (Constants.debug) {
    Log.d("TAG", "Somethings")
}

然后通过修改 Constans.debug的值来控制日志的打印。

2.假设程序中存在着成千上万处日志输出,那么按照1中的写法,就会存在着一些问题:

  • 每次新增日志输出,都需要额外增加对debug的判断。
  • 当有一天不再使用Log打印日志,而是换成Logger时,代码的修改量非常大。

为了解决这两个问题,我们新建一个工具类来管理一下Log。

public class LogUtil {
    
    public static boolean debug = true;
    
    public static void d(String tag, String content) {   
        Log.d(tag, content);
    }
}

打印日志时,不再直接调用Log的方法,而是通过LogUtil调用。LogUtil跟Log的方法一一对应,这些方法的功能就是去调用Log中对应的方法。此时如果想要通过debug对日志进行控制,只需要将控制的逻辑添加在LogUtil的方法中即可。

public class LogUtil {
    
    public static boolean debug = true;
    
    public static void d(String tag, String content) {  
        if(debug) {
            Log.d(tag, content);
        } 
    }
}

如果想要替换别的日志库Logger,也只需要稍微做下修改

public class LogUtil {
    
    public static boolean debug = true;
    
    public static void d(String tag, String content) {  
        if(debug) {
            Logger.d(tag, content);
        } 
    }
}

这时无论是添加统一的控制逻辑,还是功能替换,都十分方便,只需要改一下LogUtil即可。这就是代理思想的一种简单运用:通过一个间接的类对象去访问实际对象,可以在间接类中附加各种用途。我们称这个间接类为代理类。

3.在2中,存在一个问题。如果代理类与被代理的类之间方法名不同,调用方就很难判断出自己需要的方法究竟是哪个一个。因此需要让代理类与被代理类实现同一个接口,来保证两者拥有相同的特征。
(1) 定义统一的接口

public interface Log {
    void d(String tag, String content);
}

(2) 定义实现类Logger

public class Logger implements Log {
    @Override
    public void d(String tag, String content) {

    }
}

(3) 定义代理类LoggerProxy

public class LoggerProxy implements Log {

    private final Log log;

    public LoggerProxy() {
        log = new Logger();
    }

    @Override
    public void d(String tag, String content) {
        log.d(tag, content);
    }
}

(4) 在代码中使用

Log log = new LoggerProxy();
log.d("test", "content");

这样已经避免了调用者和Logger的直接交互。从代码实现上讲:在Logger中实现打印日志的功能,在LoggerProxy中实现控制日志打印的功能。将一个功能的实现与它的管理分开,解耦。从角色上讲:Logger是提供给调用者的功能,它应该属于服务方。而LoggerProxy控制是否使用日志功能,它属于调用方。因此即使可以通过修改Logger的源码来实现日志的控制逻辑,我们一般也不会这么做。

优点
  • 职责清晰
  • 容易扩展
  • 智能
缺点
  • 增加代理,可能会导致程序运行变慢
  • 设计时需要做额外的工作,但是维护的时候十分简便
使用场景
  • 多处使用某个对象的方法,而这个对象随时可能被改变
  • 多处使用某个对象,并自由扩展其方法,但是偶尔要统一添加一些控制功能,对象的基类又无法扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值