定义
业务代表模式(Business Delegate Pattern)主要是为了实现表现层和业务层的解耦,使用业务代表模式可以支持各种场景,在这些场景中,客户端可以根据需要自行选择不同的业务代表,每个业务代表负责的服务各有不同或者说服务类型不同,业务查询服务一般是负责公共的业务查询,提供给业务代表使用。
业务代表模式是一种经典的 J2EE 设计模式,是业务解耦的一种手段。举个例子:生活中比较常见的去银行办理业务时,每种业务都会有不同的业务顾问(业务代表),客户办理业务时可以选择具体的业务顾问,每个业务顾问又负责不同的业务范畴,业务顾问进行业务办理时需要先进行业务询问或查询,也就说根据客户业务范畴选择可以进行服务的服务窗口,完事后就交由服务窗口负责客户具体服务了。
组成角色
业务代表模式包含如下角色:
- 客户端(Client):表现层,可以是 JSP、Servlet 或者 Java 代码。上面的例子中指的就是去银行办理业务的客户;
- 业务代表(Business Delegate):和客户端打交道的实体类,提供了对业务服务方法的访问。对应的是业务顾问;
- 查询服务(Look Up Service):用来查询具体业务范畴或对象的具体业务实现,对应上文的就是业务顾问要根据查询服务查询对客户进行服务的具体窗口(服务实现);
- 业务服务(Business Service):具体的业务服务实现类,对应的就是具体的服务窗口。
业务代表模式的通用 UML 类图如下:
业务代表模式代码实现
业务代表模式的通用代码如下:
业务服务
/**
* 业务服务抽象接口
* @author Administrator
*
*/
public interface BusinessService {
// 提供的服务
void doTask();
}
业务服务的具体实现类
服务实现类 1:
/**
* 业务服务具体实现类
* @author Administrator
*
*/
public class BusinessServiceImpl1 implements BusinessService{
public void doTask() {
System.out.println("Processing task by invoking BusinessServiceImpl1");
}
}
服务实现类 2:
/**
* 业务服务的具体实现类
* @author Administrator
*
*/
public class BusinessServiceImpl2 implements BusinessService{
public void doTask() {
System.out.println("Processing task by invoking BusinessServiceImpl2");
}
}
业务查询服务
/**
* 业务查询服务
* @author Administrator
*
*/
public class BusinessLookUp {
/**
* 根据具体的业务类型,查询具体的业务类型的办理人(服务)
* @param serviceType
* @return
*/
public BusinessService getBusinessService(String serviceType) {
if ("type1".equalsIgnoreCase(serviceType)) {
return new BusinessServiceImpl1();
} else {
return new BusinessServiceImpl2();
}
}
}
业务代表
/**
* 业务代表
* @author Administrator
*
*/
public class BusinessDelegate {
// 业务查询
private BusinessLookUp lookUpService = new BusinessLookUp();
// 业务服务
private BusinessService businessService;
// 服务类型
private String serviceType;
public void setServiceType(String serviceType) {
this.serviceType = serviceType;
}
/**
* 业务代表的服务方法
*/
public void doTask() {
// 查找具体的服务窗口
businessService = lookUpService.getBusinessService(serviceType);
// 委托窗口进行业务处理
businessService.doTask();
}
}
客户端
/**
* 客户端-表现层
* @author Administrator
*
*/
public class Client {
// 业务代表
private BusinessDelegate businessDelegate;
public Client(BusinessDelegate businessDelegate) {
this.businessDelegate = businessDelegate;
}
// 客户端的业务
public void doTask() {
// 委托业务代表处理
businessDelegate.doTask();
}
}
测试验证
/**
* 业务代表模式测试类
* @author Administrator
*
*/
public class BusinessDelagateDemo {
public static void main(String[] args) {
// 生成一个服务范畴类型为type1的业务代表
BusinessDelegate businessDelegate = new BusinessDelegate();
businessDelegate.setServiceType("type1");
// 指定客户的业务代表为businessDelegate
Client client = new Client(businessDelegate);
// 客户办理业务
client.doTask();
// 生成一个服务范畴类型为type2的业务代表
businessDelegate.setServiceType("type2");
client.doTask();
}
}
输出结果如下:
Processing task by invoking BusinessServiceImpl1
Processing task by invoking BusinessServiceImpl2
优缺点
业务代表模式的优点:
- 表现层和业务层分离,利于应用解耦;
- 客户端可以根据需要自主选择业务代表,符合面向对象的特点。
应用场景
业务代表模式典型应用场景如下: - 业务的表现层和业务层解耦:传统的 MVC 架构中,为了实现 JSP、Servlet 等与业务层解耦,可以提高系统的开发效率以及模块的复用性。
使用实例
下面我们以本节开始时讲解的银行业务办理场景进行 Demo 讲解,具体代码设计如下:
抽象业务服务
/**
* 抽象业务服务
*/
interface BusinessService {
// 要进行的业务-开户
void doCreateCount();
// 要进行的业务-存钱
void doSaveMoney();
}
服务窗口 - 张
/**
* 服务窗口-张
*/
class BusinessConsultantZh implements BusinessService {
@Override
public void doCreateCount() {
System.out.println("服务窗口-张:开户成功");
}
@Override
public void doSaveMoney() {
System.out.println("服务窗口-张:存钱成功");
}
}
服务窗口 - 李
/**
* 服务窗口-李
*/
class BusinessConsultantLi implements BusinessService {
@Override
public void doCreateCount() {
System.out.println("服务窗口-李:开户成功");
}
@Override
public void doSaveMoney() {
System.out.println("服务窗口-李:存钱成功");
}
}
业务查询服务
/**
* 业务查询服务
*/
class BusinessLookUp {
/**
* 根据具体的业务类型,查询具体的业务类型的办理人(服务)
* @param serviceType
* @return
*/
public BusinessService getBusinessService(String serviceType) {
// 开户业务暂由 BusinessConsultantZh 窗口办理
if ("doCreateCount".equalsIgnoreCase(serviceType)) {
return new BusinessConsultantZh();
} else {
// 存钱业务暂由 BusinessConsultantLi 窗口办理
return new BusinessConsultantLi();
}
}
}
业务顾问
/**
* 业务顾问或者大堂业务专员
*/
class BusinessDelegate {
// 业务查询
private BusinessLookUp lookUpService = new BusinessLookUp();
// 业务服务
private BusinessService businessService;
// 服务类型
private String serviceType;
public void setServiceType(String serviceType) {
this.serviceType = serviceType;
}
/**
* 业务顾问的服务方法
*/
public void doTask() {
// 查找具体的服务窗口
businessService = lookUpService.getBusinessService(serviceType);
// 委托窗口进行业务处理
if (serviceType.equalsIgnoreCase("doCreateCount")) {
businessService.doCreateCount();
} else {
businessService.doSaveMoney();
}
}
}
客户
/**
* 普通客户
*/
class NormalCustomer {
// 要提供服务的业务代表
private BusinessDelegate businessDelegate;
public NormalCustomer(BusinessDelegate businessDelegate) {
this.businessDelegate = businessDelegate;
}
// 客户端的业务
public void doTask() {
// 委托业务代表处理
businessDelegate.doTask();
}
}
测试类
// 生成一个服务范畴类型为开户的业务代表
BusinessDelegate businessDelegate = new BusinessDelegate();
businessDelegate.setServiceType("doCreateCount");
// 指定客户的业务代表为businessDelegate
NormalCustomer client = new NormalCustomer(businessDelegate);
// 客户办理业务
client.doTask();
// 生成一个服务范畴类型为存钱的业务代表
businessDelegate.setServiceType("doSaveMoney");
client.doTask();
输出结果如下:
服务窗口 - 张:开户成功
服务窗口 - 李:存钱成功
总结
业务代表模式比较简单,在做 MVC 开发的时候就能体会到表现层和业务层分离的好处,这里要和建造者模式区分下,建造者模式强调的是构建与表现相分离,强调的是内部构建,而业务代表模式强调的是表现层。