背景:
我有一个REST服务,假设叫做CustomerService
,它目前只有一个方法getCustomer(id, country)
。现在的要求是,根据国家不同,我需要执行不同的业务逻辑,比如访问不同的数据库或者一些自定义规则,并且报告我收到了这样一个请求。
首先,为了解决根据国家不同而产生的不同实现,我使用了工厂模式,如下所示:
所有基于国家的实现的公共接口
public Interface CustomerServiceHandler{
Cusomer getCustomer(String id, String country);
}
然后工厂作为
public class CustomerServiceHandlerFactory{
public CustomerServiceHandler getHandler(String country){...};
}
使用Facade的实现细节
请注意,此Facade从REST类CustomerService调用。
public CustomerServiceFacade{
public Customer getCustomer(String id, String country){
//use factory to get handler and then handler.getCustomer
Customer customer = factory.getHandler(country).getCustomer(id,country);
//report the request
reportingService.report('fetch-customer',....);
return customer;
}
}
根据单一职责原则(SRP),这个门面模式没有实现单一目标。它既获取客户端信息,又报告该请求已经接收。因此,我考虑使用以下装饰器模式进行实现。
使用装饰者模式的实现方法:
//this is called from Rest layer
public ReportingCustomerHandler implements CustomerServiceHandler{
//this delegate is basically the default implementation and has factory too
private CustomerServiceHandler delegate;
private ReportingService reporting;
public Customer getCustomer(String id, String country){
Customer customer = delegate.getCustomer(id, country);
reporting.report(....);
return customer;
}
}
//this is called from ReportingCustomerHandler
public DefaultCustomerServiceHandler implements CustomerServiceHandler{
private CustomerServiceHandlerFactory factory;
public Customer getCustomer(String id, String country){
//get factory object else use itself, even default implementation is provided by factory
CustomerServiceHandler handler = factory.getHandler(country);
return handler.getCustomer(id,country);
}
}
注意:在第二种方法中,我重用了工厂代码中展示的CustomerServiceHandler
接口,同时用于报告和默认实现
。
那么正确的方式是什么,或者如果有更合适的方法,该怎么办。
问题的第二部分
如果我必须维护两个不同的接口,即一个用于实现不同国家的实现,另一个用于服务REST层。那么设计或替代方案是什么?在这种情况下,我认为门面模式很适合。
ReportingCustomerHandler
调用了getCustomer
和report
,这与我们在CustomerServiceFacade
中所遇到的“问题”相似,因此我尽可能地设法避免这种情况。 - Mike Barlotta