代理模式

一、概述

一般问题:在某些情况下,一个对象不适合或者不能直接引用另一个对象,比如对象创 建开销很大,或者某些操作需要安全控制,或者需要进程外的访问,或者直接访问会给使用者或者系统结构带来很多麻烦。

核心方案:为其他对象提供一种代理以控制对这个对象的访问。

设计意图:既然是代理,那么首先应该有两个对象:实现类和代理类。实现类是我们真正希望访问的,是功能的最终提供者,业务的最终完成者;代理类是介于访问者和实现类之间的中间层,代理类拥有实现类的实例,访问者通过访问代理类间接访问实现类。那么还有一个问题需要解决:代理类如何知道知道实现类能提供什么功能?一个最笨的方法就是为代理类添加实现类的同名方法,但是这样太难维护和扩展了。于是,我们需要一个规范接口,来定义代理类究竟代理实现类的哪些方法。然后让代理类和实现类同时实现该接口,以强制二者拥有代理功能的同名方法。换句话说,代理类中拥有的方法,必然对应实现类中的实现方法。

代理模式的最终设计结构如下:


二、应用场景

以向中介租房为例,设计一个代理模式:

IHouse接口定义如下:

public interface IHouse { 
  String getAddress(); 
  double getPrice(); 
}

 

HouseImpl实现类:

public class HouseImpl implements IHouse{ 
  private String address; 
  private double price; 
  
  public HouseImpl(String address, double price){ 
    this.address = address; 
    this.price = price; 
  } 
  
  @Override
  public String getAddress() { 
    return this.address;
  } 
  
  @Override
  public double getPrice() { 
    return this.price;
  } 
} 

ProxyHouse代理类:

public class ProxyHouse implements IHouse{ 
  private IHouse houseImpl;     //被代理类
  public ProxyHouse(IHouseImpl houseImpl){ 
    this.houseImpl = houseImpl; 
  } 
  @Override
  public String getAddress() { 
    return houseImpl.getAddress();   //由实际被代理类执行
  } 
  
  @Override
  public double signPrice() { 
    if(houseImpl.getPrice() < 0){  //此处代表对接口做简单限制
          return 0;
    }
    return houseImpl.getPrice();
  } 
}

 

分析上面代码:

  1. HouseImpl和ProxyHouse都继承自IHouse抽象类,且重写了其声明的抽象方法。
  2. ProxyHouse是HouseImpl的代理类,其属性mHouseImpl即HouseImpl实例,在实现方法中直接调用mHouseImpl同名方法。
  3. HouseImpl是真正的实现者,是接口方法的具体执行者。

之所以这样设计,是方便对HouseImpl的方法做限制。


三、总结

优点:

  1. 职责清晰——代理类专注于提供代理方法,代码整洁,便于调用;
  2. 高扩展性——代理类可同时代理多个实现类,只要实现同一接口,拥有同名方法,而不必关心具体的实现。

缺点:

  1. 由于增加了代理层,可能使请求速度变慢;
  2. 由于添加了代理逻辑,增加了额外工作,可能使代码复杂化。

总结:

代理模式也叫委托模式,是一种结构型设计模式,当我们需要对某对象进行保护,或者对其访问进行控制,或者其他原因不便于直接访问时,应当考虑使用代理模式。尽管增加了额外的工作,但会让整体架构更加清晰、安全,易于维护和扩展。

posted @ 2014-01-18 14:27  西贝雪  阅读(125)  评论(0)    收藏  举报