1、定义
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。比如,租房的时候,中介就充当代理角色。
2、静态代理角色
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
真实角色:被代理的角色,实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
代理角色:代理真实角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
3、实例分析
我们以租房子为例子来解释什么叫静态代理。
HostRent.java 抽象角色类。
1 public interface HostRent { 2 //租房方法 3 public void rent(); 4 }
Host.java 真实角色(房东)
1 public class Host implements HostRent { 2 3 @Override 4 public void rent() { 5 // TODO Auto-generated method stub 6 System.out.println("房子出租!"); 7 8 } 9 10 }
Proxy.java 代理角色(中介)
1 public class Proxy implements HostRent{ 2 private Host host; 3 @Override 4 public void rent() { 5 // TODO Auto-generated method stub 6 host.rent(); 7 } 8 9 public void setHost(Host host) { 10 this.host = host; 11 } 12 13 public Proxy(Host host) 14 { 15 this.host = host; 16 } 17 18 }
Client.java 客户
1 public class Client { 2 public static void main(String[] args) { 3 Host host = new Host(); 4 Proxy proxy = new Proxy(host); 5 proxy.rent(); 6 7 } 8 }
这里的例子中,中介就代表了一个代理角色。这样的好处就是真实角色处理业务更加纯粹 ,不再关注一些公共的事情。从上面的例子中,可能还看不出有什么优势,我们再列举一个例子。
User.java 抽象角色类
1 public interface User { 2 //添加数据 3 public void add(); 4 // 更新数据 5 public void update(); 6 // 删除数据 7 public void delete(); 8 // 查询数据 9 public void select(); 10 }
UserImpl.java
1 package com.spring.staticProxy; 2 3 public class UserImpl implements User { 4 5 @Override 6 public void add() { 7 System.out.println("添加数据"); 8 } 9 10 @Override 11 public void update() { 12 System.out.println("更新数据"); 13 } 14 15 @Override 16 public void delete() { 17 System.out.println("删除数据"); 18 19 } 20 21 @Override 22 public void select() { 23 System.out.println("查询数据"); 24 } 25 26 }
我们想在UserImpl类里添加日志功能,这时就必须在每个方法里添加日志函数,如下
1 public class UserImpl implements User { 2 3 @Override 4 public void add() { 5 System.out.println("添加数据"); 6 } 7 8 @Override 9 public void update() { 10 log("update"); 11 System.out.println("更新数据"); 12 } 13 14 @Override 15 public void delete() { 16 log("delete"); 17 System.out.println("删除数据"); 18 19 } 20 21 @Override 22 public void select() { 23 log("select"); 24 System.out.println("查询数据"); 25 } 26 27 private void log(String methodName) 28 { 29 System.out.println("执行"+methodName+"方法"); 30 } 31 32 }
这时,UserImpl类变得不纯粹,里面处理了逻辑业务,还有很多公共部分的代码,这时就需要一个代理,代理实现日志功能。整个代理类如下
1 public class Proxy implements User{ 2 3 private UserImpl user; 4 @Override 5 public void add() { 6 log("add"); 7 user.add(); 8 } 9 10 @Override 11 public void update() { 12 log("update"); 13 user.update(); 14 } 15 16 @Override 17 public void delete() { 18 log("delete"); 19 user.delete(); 20 } 21 22 @Override 23 public void select() { 24 log("select"); 25 user.select(); 26 } 27 28 private void log(String methodName) 29 { 30 System.out.println("执行"+methodName+"方法"); 31 } 32 }
整个代理类就实现了日志功能,避免了在真实类里处理了逻辑业务,使整个真实类更加纯粹,里面只有对数据库的操作函数,并且把公共部分给提取出来。这就是静态代理。
在实际使用时,一个真实角色必须对应一个代理角色,但如果大量使用会导致类的急剧膨胀。比如想代理Host类和UserImpl类,则就需要两个代理类。其中动态代理类能够解决这种问题,他只需要一个代理类就能完成。以下是静态代理类的优缺点:
优点:
1、使得真实角色更加纯粹,不再去关注一些公共的业务。
2、公共业务由代理类来完成,实现业务分工。
3、当业务拓展时,只需要修改代理类,变得更加其中和方便
缺点:
1、多了代理类,工作量变大,开发效率变低