这个问题使用Java示例,但它处理适用于任何OOP的问题。我想公开一些web服务,以便其他应用程序可以使用它们。我创建了一个jar / library文件,它处理所有连接内容以及string / xml到pojo之间的转换。我创造了一个" facade"每个可调用web服务有1个方法的类。例如。在伪代码中:
class ServiceInvoker
{
//constructor
...
//methods
public List<Product> getProducts()
public ProductReference getProductReferences(int productId)
...
}
问题是,大多数Web服务都需要一堆参数。例如,无论何时您处理产品,您都会获得完整的详细信息,或者您只能获得最基本的信息。仅适用于最近/旧信息。只获得少量产品更高效,但有时您确实需要更多信息,因此存在以最佳方式满足所有用例的参数。我发现了3种可能的解决方法。
public void setInfoMode(Infomode mode) { this.infoMode = mode; }
InfoMode将是这样的枚举类:InfoMode.DETAILED,InfoMode.BASIC。这种方案的优点是开发人员只需设置模式&#34;一次&#34;然后所有未来的服务调用都将使用该模式。这可以在多个方法中保存一大堆参数,特别是因为某些服务可以共享设置,并且很可能多次调用相同的服务。这种方案的主要缺点是清晰度:当调用服务&#34; getProducts&#34;时,响应可能会根据早期的设置模式而有很大差异。如果开发人员必须进行这样的预处理,那么早先说的优势将会丢失:
if (serviceInvoker.getInfoMode != InfoMode.DETAILED)
{
serviceInvoker.setInfoMode(InfoMode.DETAILED);
}
因为这比简单地将模式作为参数传递更复杂。
第三个选项是将1和2组合在一起。有一个没有参数的方法,它使用前面设置的模式,但也提供了一个带有参数的方法,这些方法会暂时覆盖该方法调用的设置模式。这种方案的缺点是&#34;倍增&#34;所有方法。突然间,我的祈求者课程变得庞大,它开始闻起来像反模式&#34;巨大的神级&#34;。
围绕此问题有哪些最佳做法?这种情况是否存在设计模式?
答案 0 :(得分:1)
这个问题可能最终会被关闭,因为它主要是基于意见的(因为它是),但是将特定请求类型表示为DTO更为清晰。当你把一个类称为“ServiceInvoker”时,我在想Command Pattern。这对您的设计意味着您的Facade的参数应该是不言自明的包,它封装了服务执行其职责所需的所有信息。此设计还应该消除您班级中多种方法的需要。
对于您的服务的来电者,这意味着他们会将不同的参数类型(具有共同的祖先)传递给ServiceInvoker
,ServiceInvoker#invoke
中的单个入口点。然后,此方法将采用所有扩展ProductRequest
的类。然后ServiceInvoker
可以将请求委托给适当的命令处理程序。说明
创建基类ProductRequest
。此基类应包含对所有操作类型都通用的信息
public abstract class ProductRequest{
private InfoMode infoMode;
private String requestType;
//getters and setters
//trying to avoid violating Javabean convention here
private void setRequestName(){
this.requestType = this.getClassName().toString();
}
}
各个服务请求类型应该扩展ProductRequest
。根据需要为每种操作类型进行自定义。
创建将处理特定操作请求的专用ProductRequestHandler
类型。让我们尝试专门处理产品参考请求的那个
public class ProductReferenceReqHandler implements ProductRequestHandler<ProductReferenceRequest>{
@Override
public ProductResponse handleRequest(ProductReferenceRequest req){
//implementation grime goes here
}
}
您应该在地图中堆叠ProductRequestHandler
个堆栈,并按请求类型键入。此地图应该是ServiceInvoker
通过访问可能的请求处理程序的地图,您的调用者只需要一个方法:invoke
public class ServiceInvoker{
private Map<String,ProductRequestHandler> handlers;
//work out some logic to instantiate and populate the map with the available handlers
public ProductResponse invoke(ProductRequest req){
ProductRequestHandler handler = handlers.get(req.getRequestType());
ProductResponse resp = handler.handleRequest(req);
}
}
您所获得的是一个干净,灵活的界面,可以避免Facade中不必要的混乱,并为您的客户提供直观的合约(通过直观命名的DTO)