gpt4 book ai didi

java - 门面或装饰

转载 作者:搜寻专家 更新时间:2023-10-31 20:33:53 25 4
gpt4 key购买 nike

上下文:

我有一个 REST 服务,比方说 CustomerService现在只有一种方法getCustomer(id, country) .现在的要求是,根据国家/地区,我必须执行不同的业务逻辑,例如访问不同的数据库或一些自定义规则,然后报告我收到了这样的请求。

首先,为了解决不同国家/地区的不同实现,我使用工厂模式,如下所示:

所有基于国家/地区的实现的通用接口(interface)

public Interface CustomerServiceHandler{
Cusomer getCustomer(String id, String country);
}

然后工厂为

public class CustomerServiceHandlerFactory{
public CustomerServiceHandler getHandler(String country){...};
}

使用 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);

}
}

注意:在第二种方法中,我重用了接口(interface) CustomerServiceHandler (在工厂代码中显示)Reporting and Default implementations还有。

那么正确的方法是什么,或者如果存在更合适的方法,替代方法是什么。

问题的第二部分

如果我必须维护两个不同的接口(interface),即一个 CustomerServiceHandler 怎么办?实现不同国家的实现,一个服务于 REST 层。那么设计或替代方案是什么。在这种情况下,我认为立面很合适。

最佳答案

So what is the correct way, or what is the alternative to this

这里的设计非常可靠,并且很好地使用了工厂模式。我提供的是对这项出色工作的建议,但我认为有很多方法可以增强您所拥有的。

我可以看到 CustomerServiceFacade 方法 getCustomer 在哪里破坏了 SRP。它将检索客户与报告方面结合起来。我同意将报告从该方法中移出会更清晰。

那么你的对象看起来像这样:

public CustomerServiceFacade{
public Customer getCustomer(String id, String country){
return factory.getHandler(country).getCustomer(id,country);
}
}

那么我们把报告放在哪里呢?

您可以通过单独的界面移动/管理报告。这将允许灵活地实现不同的报告方法并使测试更容易(即模拟报告部分)。

public interface ReportService {
void report(Customer c, String id, String country);
}

REST 层如何访问报告?

方案一:REST通过多个对象访问各种Customer函数

ReportService 的实现可以通过 CustomerServiceFacade 注入(inject)到 REST Controller 中。

不确定您为 REST 使用的是什么框架,但它可能看起来像这样:

@GET
@Path("/customer/{Id}/{country}")
public Response getCustomer(@PathParam("Id") String id, @PathParam("country") String country){

Response r = null;

// injected implementation of CustomerServiceFacade
Customer c = customerServiceFacade.getCustomer(id, country);
if (c!=null){
// injected implementation of ReportService
reportService.report(c, id, country);
}
else {
// handle errors ...
}

return r;
}

选项 2:REST 通过一个外观/服务访问各种客户功能

您可以让您的服务外观层为提供功能的更大对象集提供简化接口(interface)的功能。这可以通过拥有多个客户服务方法来实现,这些方法使 REST 层能够通过一个对象访问各种功能,但仍然具有让每个方法更紧密地遵守 SRP 的好处。

在这里,我们将 CustomerServiceFacade 注入(inject) REST Controller ,它调用两个方法 1) 获取客户和 2) 处理报告。外观使用上面的 ReportService 接口(interface)的实现。

public CustomerServiceFacade{
public Customer getCustomer(String id, String country){
// call the correct CustomerServiceHandler (based on country)
return factory.getHandler(country).getCustomer(id,country);
}

public void report(Customer c, String id, String country){
// call the reporting service
reportService.report(c, id, country);
}
}

我认为这是对 Facade 模式的合理使用,同时在实际方法中仍然包含 SRP。

如果报告实现因国家/地区而异,与客户不同,您可以使用其他工厂。

   public void report(Customer c, String id, String country){
// call the correct reporting service (based on country)
rptFactory.getInstance(country).report(c,id,country);
}

关于java - 门面或装饰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28733452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com