设计模式之代理模式
- 代理模式的定义
为其他对象提供一种代理,以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引
用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
- 一个简单的代理例子
// 抽象接口
Interface 外卖() {
public void waimai();
}
//目标 对象类
class 卤肉饭 implements 外卖() {
public void waimai() {
log.i("咖喱饭!");
}
}
// 代理类
calss 订餐平台 implents 外卖() {
卤肉饭 rrf;
public 订餐平台(卤肉饭 rrf) {
this.rrf = rrf;
}
@over
public void waimai() {
骑车到店里拿外买()
wmz.waimai();
骑车给定外卖者送过去();
}
private void 骑车到店里拿外买() {
log.v("我去取外卖了")
}
private void 骑车给定外卖者送过去() {
log.v("我再路上了不要催")
}
}
// 调用
main() {
外卖小哥 a = new 外卖小哥(new 卤肉饭());
a.waimai();
}
-
总结什么情况下使用代理模式
- 目标对象不想被使用者直接使用,就可以用代理模式.在例子中"定餐者"只要在订餐平台叫外卖就可以了,并不用需要担心外卖(目标对象)怎么送的…
- 代理类创建了对象的使用环境,并向客户隐藏了对象与环境之间的交互过程.此种典型的环境问题包括:DB操作、网络I/O、安全控制等,在使用代理类的情况,“客户”将感觉不到DB或网络的存在,想取数据就取到了.
-
动态代理
- 为什么需要动态代理?
如果需要被代理的对象多了,那么你的代理类也就变多, 而使用动态代理,就不需要写那么多的代理类.
- 动态代理例子
静态代理例子如下: // 接口 public interface Subject { void print(); } // 实现 public class RealSubject implements Subject{ @Override public void print() { Log.d(TAG,"RealSubject print"); } } //代理 public class ProxySubject implements Subject { RealSubject realSubject; public ProxySubject(RealSubject realSubject) { this.realSubject = realSubject; } @Override public void print() { // 可以调ProxySubject自己定的方法 xxx realSubject.print(); } } 如果此时我们在增加一个Subject2接口,如下: //接口 public interface Subject2 { void print2(); } 那么采用静态代理的方式,我们此次又要增加一个ProxySubject2, 那如果增加Subject3...SubjectN,对应的ProxySubje3...ProxySubjN, 显而易见代理类增多了很多.所以就有动态代理的出现. 动态代理类如下: public class NormalHandler implements InvocationHandler { private Object target; public NormalHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Log.d(TAG,"enter invoke"); method.invoke(target, args); return null; } } // 实现 public class RealSubject implements Subject,Subject2{ @Override public void print() { Log.d(TAG,"RealSubject print"); } @Override public void print2() { Log.d(TAG,"RealSubject print2"); } } 调用如下: NormalHandler normalHandler = new NormalHandler(new RealSubject()); Subject subject = (Subject)Proxy.newProxyInstance(Subject.class.getClassLoader() ,new Class[]{Subject.class},normalHandler); subject.print(); Subject2 subject2 = (Subject2) Proxy.newProxyInstance(Subject2.class.getClassLoader() ,new Class[]{Subject2.class},normalHandler); subject2.print2();