Value Object模式是将远程调用的传递数据封装在一个串行化的对象中进行传输,而业务代理模式则是将一组由远程方法调用构成的业务流程,封装在一个战士层的代理类中。比如当用户修改订单,需要进行一下三个操作:检验用户,获取旧的订单信息,更新订单。
以上结构存在两个问题:当展示层存在大量并发线程时,这些县城都会直接进行远程方法调用,进而增加网络负担;由于缺乏对订单修改操作流程的有效封装,如果将来修改流程发生变化则展示层组件需要进行修改。
为解决上述问题,在展示层中加入业务代理对象,业务代理对象负责和远程服务器通信,完成订单修改操作。而业务代理对象只需要暴露简单的更新方法即可。
这种结构体现了业务代理模式的核心思想。由于业务代理对象被所有的展示层请求线程和多个客户端共享,故系统会有较好的可维护性。如果业务流程发生变化,只需要简单的修改业务代理对象暴露的方法即可。除此之外,通过业务代理对象,可以更容易的在多个线程或者客户端请求之间共享数据,从而有效的利用缓存,减少远程调用次数,提高系统性能。
业务代理模式将一些业务流程封装在前台系统,为系统性能优化提供了基础平台,在业务代理中,不仅可以复用业务流程,还可以视情况为展示层组件提供缓存等功能,从而减少远程方法调用次数,降低系统压力。
在服务端接口中添加以下两个方法:
boolean checkUser(int uid) throws RemoteException;
boolean updateOrder(Order order) throws RemoteException;
业务代理类:
package com.performance.optimization.design.valueobject;
import java.rmi.RemoteException;
/**
* 业务代理模式
* @author qiaolin
*
*/
public class BusinessDelegate {
private IOrderManager orderManager;
public BusinessDelegate(IOrderManager orderManager){
this.orderManager = orderManager;
}
public boolean checkUserFromCache(int uid){
return true;
}
public boolean checkUser(int uid) throws RemoteException{
if(!checkUserFromCache(uid)){//当前对象被多个客户端共享时可从缓存中校验
return orderManager.checkUser(1);
}
return true;
}
public Order getOrderFromCache(int oid){//从cache中获取订单
return null;
}
public Order getOrder(int oid) throws RemoteException{
Order order = getOrderFromCache(oid) ;
if(order == null){
return orderManager.getOrder(oid);
}
return order;
}
public boolean updateOrder(Order order) throws RemoteException{
if(checkUser(order.getOrderId())){
orderManager.updateOrder(order);
}
return true;
}
}
测试方法:
@Test
public void testBusinessDelegate(){
try {
IOrderManager orderManager = (IOrderManager) Naming.lookup("OrderManager");
BusinessDelegate delegate = new BusinessDelegate(orderManager);
Order order = new Order();
order.setClientName("张三");
order.setNumber(1);
order.setOrderId(1);
order.setProductName("剃须刀");
delegate.updateOrder(order);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
测试方法:
OrderManager is ready.
更新订单操作
Order [orderId=1, clientName=张三, number=1, productName=剃须刀]