定义
传输对象模式(Transfer Object Pattern)是指客户端到服务器一次性传递具有多个属性的数据,以避免多次调用远程服务器。传输对象是一个具有 getter/setter 方法的简单的实体类,可被序列化。服务器端业务类通常从数据库读取数据,然后填充到实体类,并把它发送到客户端。
组成角色
- 传输对象(Transfer Object):简单的实体类,只有 getter/setter 方法;
- 业务对象(Business Object):为客户端提供业务数据,用于数据处理和构建传输对象;
- 客户端(Client):发送请求或者发送传输对象到业务对象。
角色之间的 UML 关系图如下:
传输对象模式代码实现
传输对象
/**
* 传输对象,只提供传输对象的 getter/setter 方法
*/
class TransferObject {
private int id;
private String name;
public TransferObject(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
业务对象
给系统提供业务数据。
/**
* 业务对象,提供业务数据
*/
class BusinessObject {
// 数据来源的存储容器
List<TransferObject> list;
public BusinessObject() {
// 填充业务数据(伪代码,模拟数据产生)
list = new ArrayList<>();
list.add(new TransferObject(0, "Java"));
list.add(new TransferObject(1, "SQL"));
}
/**
* 获取所有业务数据
*/
public List<TransferObject> getList() {
return list;
}
/**
* 根据下标查询相应的数据
* @param index 下标
* @return 返回单条数据
*/
public TransferObject getDataById(int index) {
return list.get(index);
}
/**
* 修改业务数据
* @param transferObject
*/
public void update(TransferObject transferObject) {
list.get(transferObject.getId()).setName(transferObject.getName());
}
}
客户端调用
public class Client {
public static void main(String[] args) {
// 创建业务对象,获取到数据(伪代码,初始化业务对象时会填充数据)
BusinessObject businessObject = new BusinessObject();
// 循环打印所有业务数据
for (TransferObject t : businessObject.getList()) {
System.out.println("Id=" + t.getId() + " | " + "Name=" + t.getName());
}
// 更新数据
TransferObject transferObject = businessObject.getList().get(0);
System.out.println("原名称:" + transferObject.getName());
transferObject.setName("LaoWang");
businessObject.update(transferObject);
// 打印修改的数据
System.out.println("修改后的名称:" + businessObject.getList().get(0).getName());
}
}
程序执行结果如下:
Id=0 | Name=Java
Id=1 | Name=SQL
原名称:Java
修改后的名称:LaoWang
优缺点
传输对象模式的优点:
- 减少了远程调用次数:通过在单个远程调用中传输更多的数据,应用程序可以减少远程调用次数;
- 提高了性能:远程调用可以使应用程序的运行速度大大降低,减少调用次数是提高性能的最佳方法之一;
- 简化了程序代码:使用传输对象的模式使代码可读性更高,让程序看起来更简单。
传输对象模式的缺点: - 增加了复杂性:由于要兼容多个版本的程序,可能需要创建更多的实体类来适用各个版本的程序,这会让程序变得更加复杂。
应用场景
传输对象模式典型的应用场景如下:
- 希望减少程序中远程调用次数;
- 希望提高程序获取资源的性能;
- 程序需要传输多个数据时。
使用实例
创建物品表
快递的物品表。
/**
* 物品表
*/
class GoodsInfo {
private String mobile;
private String name;
public GoodsInfo() {
}
public GoodsInfo(String mobile, String name) {
this.mobile = mobile;
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
快递业务类
查询所有的快递和新增快递。
/**
* 快递业务类
*/
class Express {
// 所有的快递物品存储容器
private HashMap<String, String> goods;
public Express() {
// 模拟数据
goods = new HashMap<>();
goods.put("18000000001", "Java面试全解析");
goods.put("18000000002", "MySQL面试金典");
}
/**
* 邮寄物品(添加订单)
* @param goodsInfo 邮寄的物品
*/
public void insert(GoodsInfo goodsInfo) {
goods.put(goodsInfo.getMobile(), goodsInfo.getName());
}
/**
* 查询所有的邮件
*/
public List<GoodsInfo> getAllGoods() {
List<GoodsInfo> list = new ArrayList<>();
GoodsInfo goodsInfo;
goods.forEach((k, v) -> {
list.add(new GoodsInfo(k, v));
});
return list;
}
}
客户端调用
public class Lesson29 {
public static void Client(String[] args) {
// 创建快递业务类
Express express = new Express();
// 创建快递物品
GoodsInfo goodsInfo = new GoodsInfo();
goodsInfo.setMobile("18000000008");
goodsInfo.setName("设计模式34讲");
// 添加快递
express.insert(goodsInfo);
// 打印所有快递信息
express.getAllGoods().forEach((goods) -> {
System.out.println("手机号:" + goods.getMobile() + " | 快递物品:" + goods.getName());
});
}
}
程序执行结果如下:
手机号:18000000008 | 快递物品:设计模式34讲
手机号:18000000001 | 快递物品:Java面试全解析
手机号:18000000002 | 快递物品:MySQL面试金典
总结
传输对象模式是客户端每次对业务对象进行相关的业务操作,而客户端和业务对象之间通过传输对象(一个只包含 getter/setter 的实体类)进行信息传递的模式。