Value Object模式

1 理论知识    

    在J2EE软件开发中,通常会对系统模块进行分层。展示层主要负责数据的展示,定义数据库的UI组织模式;业务逻辑层负责具体的业务逻辑处理;持久层通常指数据库以及相关操作。在一个大型系统中,这些层次很有可能被分离,并部署在不同的服务器上。而在两个层次之间,可能通过远程过程调用RMI等方式进行通信。如图2.15所示,展示层组件作为RMI的客户端,通过中间的业务逻辑层取得一个订单(Order)的信息。假设一个订单由客户名、商品名和数量构成,那么一次交互过程可能由图2.15所描述的这样,RMI的客户端会与服务端进行3次交互,依次取得这些信息。

Value Object模式_第1张图片

    基于以上模式的通信方式是一种可行的解决方案,但是它存在两个严重的问题:

  (1)对于获取一个订单对象而言,这个操作模式略显繁琐,且不具备较好的可维护性。

  (2)前后累计进行了3次客户端与服务器的通信,性能成本较高。

  为了解决这两个问题,就可以使用Value Object模式。Value Object模式提倡将一个对象的各个属性进行封装,将封装后的对象在网络中传递,从而使系统拥有更好的交互模型,并且减少网络通信数据,从而提高系统性能。使用Value Object模式对以上结构进行改良,定义对象Order,由Order对象维护客户名、商品名和数量等信息,而Order对象也就是Value Object,它必须是一个可串行化的对象。将Value Object模式应用到本例中,便可以得到如图2.16所示的结构。


    在基于Value Object模式的结构中,为了获得一份订单信息,只需要进行一次网络通信,缩短了数据存取的响应时间,减少了网络数据流量。

 注意:使用Value Object模式可以有效减少网络交互次数,提高远程调用方法的性能,也能使系统接口具有更好的可维护性。


2 代码实现

(1)RMI服务端接口,即业务逻辑层:(必须继承Remote接口)
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IOrderManager extends Remote{
	Order getOrder(int id) throws RemoteException;
	String getProductName(int id) throws RemoteException;
	double getPrice(int id) throws RemoteException;
	String getBrand(int id) throws RemoteException;
}

(2)RMI服务器端接口的实现:(必须继承类UnicastRemoteObject)
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class OrderManager extends UnicastRemoteObject implements IOrderManager {

	private static final long serialVersionUID = 1L;

	protected OrderManager() throws RemoteException {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public Order getOrder(int id) throws RemoteException {
		// TODO Auto-generated method stub
		Order order=new Order();
		order.setPrice(112.3);
		order.setProductName("AIR-MAX");
		return order;
	}

	@Override
	public String getProductName(int id) throws RemoteException {
		// TODO Auto-generated method stub
		return "AIR-MAX";
	}

	@Override
	public double getPrice(int id) throws RemoteException {
		// TODO Auto-generated method stub
		return 112.3;
	}

	@Override
	public String getBrand(int id) throws RemoteException {
		// TODO Auto-generated method stub
		return "NIKE";
	}

}
(3)Value Object:(RMI传输的对象)
import java.io.Serializable;

public class Order implements Serializable {

	private static final long serialVersionUID = -3485578276309961802L;
	
	private int id;
	private String productName;
	private double price;
	private String brand;
	
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
	public String getProductName() {
		return productName;
	}
	public void setProductName(String productName) {
		this.productName = productName;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
}
(4)业务逻辑层注册,并开启RMI服务器:
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class OrderServer {
	public static void main(String[] args) {
		try {
			LocateRegistry.createRegistry(1099);       //注册RMI端口
			IOrderManager manager=new OrderManager();  //RMI远程业务对象
			Naming.rebind("OrderManager", manager);    //绑定RMI对象
			System.out.println("orderManager is ready");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
(5)客户端代码:
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class OrderClient {
	public static void main(String[] args) {
		try {
			IOrderManager manager=(IOrderManager)Naming.lookup("OrderManager");
			
			long begin=System.currentTimeMillis();
			for(int i=0;i<1000;i++){
				manager.getOrder(i);
			}
			System.out.println("耗时:"+(System.currentTimeMillis()-begin));
			
			
			begin=System.currentTimeMillis();
			for(int i=0;i<1000;i++){
				manager.getPrice(i);
				manager.getProductName(i);
				manager.getBrand(i);
			}
			System.out.println("耗时:"+(System.currentTimeMillis()-begin));
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

运行结果:

耗时:110
耗时:140
注意:运行顺序,先运行Server端,注册RMI端口,绑定RMI对象,开启服务器;然后,运行client端。

    由运行结果可以看出,对传输的数据进行有效的封装,可以明显提升RMI的性能。

3 参考文献
<1> Java程序性能优化. .葛一鸣等著

你可能感兴趣的:(设计模式,value,Object模式)