代理模式

代理模式在客户对象调用服务提供者对象上方法的前后,执行诸如日志(logging)和计数(counting)一系列附加功能时很有用。代理模式建议把这些附加功能封装在一个单独的对象,这个对象就是指计数代理对象,而不是把这些附加的功能实现放到服务提供者的内部。

 

良好的对象设计的一个特征就是对象要专注于提供特定的功能。换句话说,理想的对象不应该做各种不相干的事情。把诸如日志(logging)和计数(counting)等类似的功能封装为一个单独的对象,而让服务提供者对象仅提供它自己的特定功能。也就是说,只允许服务提供者对象执行定义良好、特定的任务。

 

代理被设计成可以被客户访问的与服务提供者具有相同接口的对象。客户对象不是直接访问服务提供者,而是调用计数代理对象上的方法,计数代理执行必要的纪录日志(logging)和计数(counting)功能后,再把方法调用传递给服务提供着对象。如  图1

 
代理模式
 


<CountingProxy的命名不太恰当,因为它代理的不仅仅是记数的功能,还有日志能其他功能。

 


下面的例子说明了如何在应用程序中利用计数代理。例子:

让我们设计一个Order类,类层次如图2,


代理模式
 

OrderIF接口声明了getAllOrders读取数据库中所有订单的简单方法。

public interface OrderIF {
public Vector getAllOrders();
}

 
作为getAllOrders方法实现的一部分,Order类实用了FileUtil工具类从order.txt文件中读取订单项。

public class Order implements OrderIF {
 public Vector getAllOrders() {
  FileUtil fileUtil = new FileUtil();
  Vector v = fileUtil.fileToVector("orders.txt");
  return v;
 }
}

 

让我们假定在调用getAllOrders()时,需要把取数据文件所花费的时间和记录条数要记录到log日志文件中(记录日志是常规功能)。


这个附加的功能可以设计一个单独的OrderProxy类来实现,它与真实对象Order一样实现OrderIF接口。这样保证了OrderProxy对象提供给客户与真实对象Order一样的接口。类层次如图3:


代理模式
 

 

 

public class OrderProxy implements OrderIF {
 private int counter = 0;
 public Vector getAllOrders() {
  Order order = new Order();
  counter++; //<得不到定单的条数!!!!>
  long t1 = System.currentTimeMillis ();
  Vector v = order.getAllOrders();
  long t2 = System.currentTimeMillis();
  long timeDiff = t2 - t1;
  String msg = "Iteration=" + counter + "::Time=" + timeDiff + "ms"; <数据的条数和所用时间>

  //log the message
  FileUtil fileUtil = new FileUtil();
  fileUtil.writeToFile("log.txt”,msg, true, true); <记录到一个日志文件>
  return v;
 }
}

 
   客户对象MainApp就象调用真实对象Order一样调用OrderProxy对象上的getAllOrders()方法,OrderProxy对象传递这个调用给真实对象Order,计算读取所有订单所花费的时间并使用FileUtil帮助类将其纪录的log日志文件中。在这个过程中, OrderProxy扮演者计数代理的角色。

public class MainApp {
 public static void main(String[] args) {
  OrderIF order = new OrderProxy();
  Vector v = order.getAllOrders();
  v = order.getAllOrders();
  v = order.getAllOrders();
    v = order.getAllOrders();
 }
}

 

<简评:
本例中这种调用方式:

OrderIF order = new OrderProxy();
Vector v = order.getAllOrders();

 

优点:
1. 更加符合“开-闭原则”。增加新功能,不修改原来的类,而是通过添加新的类实现功能的增强。
2. 减少了客户端的工作量,接口够简洁。

缺点:在描述类关系上不够清晰,不够OO。
如果Order类在OrderProxy类中作为一个类变量出现,这样就能清晰的反映OrderProxy和Order类之间是引用的关系,更OO一些。但这时,却增加了client端的工作量:要先生成Order类的一个对象,然后赋值给OrderProxy类中的Order类变量。

你可能感兴趣的:(java,设计模式,工作,OO)