Web services 再利用;“设置”;跨不同的方法调用

Web services 再利用;“设置”;跨不同的方法调用,web-services,oop,Web Services,Oop,这个问题使用Java示例,但它处理的问题适用于任何OOP。我想公开一些Web服务,以便其他应用程序可以使用它们。我创建了一个jar/library文件,它处理所有连接内容以及string/xml到pojo之间的转换。我创建了一个“facade”类,它为每个可调用的Web服务都有一个方法。例如,在伪代码中: class ServiceInvoker { //constructor ... //methods public List<Product> getP

这个问题使用Java示例,但它处理的问题适用于任何OOP。我想公开一些Web服务,以便其他应用程序可以使用它们。我创建了一个jar/library文件,它处理所有连接内容以及string/xml到pojo之间的转换。我创建了一个“facade”类,它为每个可调用的Web服务都有一个方法。例如,在伪代码中:

class ServiceInvoker 
{
   //constructor
   ...

   //methods
   public List<Product> getProducts()
   public ProductReference getProductReferences(int productId)
   ...
}
因为这比简单地将模式作为参数传递要复杂得多

第三种选择是将1和2结合起来。有一个不带参数的方法,该方法使用前面设置的模式,但也提供一个带有does takes参数的方法,这些参数将临时覆盖该方法调用的设置模式。该方案的缺点是所有方法都“加倍”。突然,我的调用器类变得巨大,它开始闻起来像反模式的“巨大的上帝类”


围绕这个问题有哪些最佳实践?这种情况下是否存在设计模式?

这个问题可能会以主要基于意见的方式结束(因为它是基于意见的),但只将特定的请求类型表示为DTO更为简洁。当您调用类a“ServiceInvoker”时,我考虑的是命令模式。这对您的设计意味着,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
          }
    
      }
    


  • 您得到的是一个干净、灵活的界面,它避免了外观上不必要的混乱,并为您的客户提供了一个直观的契约(通过直观命名的DTO)

    优秀的设计模式!不过有一个建议:我没有依赖于“处理程序”的映射,而是强制每个请求类都有一个方法getHandler()(我通过在baseRequest类中生成一个抽象方法来实现这一点,每个其他请求都会继承该方法),该方法返回适当的处理程序。这个处理程序实际上是请求类的一个静态final属性,所以它不会导致处理程序对象的虚假实例化。@user1884155-这有点反模式。请求类应该只是请求数据。请求类不应该知道它们的执行上下文或要调用的处理程序。通过将处理程序信息烘焙到请求中,您也会失去处理程序映射所提供的灵活性。拥有处理程序的映射意味着您可以随意添加或删除处理程序,甚至可以重新指定一些处理程序来处理不同的请求类型。我不明白为什么不允许请求具有“suggestedHandler”方法。serviceInvoker没有义务实际使用该处理程序,它可以使用它想要的任何处理程序(如果上下文证明它是正确的),并且请求不知道“被调用”是什么意思。request类唯一要说的是“嘿,如果有人想要一个可以处理我的处理程序,为什么不试试这个默认的呢?”。这是基本的多态性,绝对不是反模式。用request->handler数据填充硬编码的hashmap确实闻起来像是一种反模式(可维护性?@user1884155)-如果您这样说(因为它只是为了提供信息),那么它可能是可以接受的。带有命令commandHandler映射的hashmap绝对不是反模式;这是服务定位器模式的内容。您确实有这样一个观点:通过硬编码的方式,它可能会很笨拙,当处理程序在外部配置时,它看起来会更好,或者更好,使用类似spring的DI框架。从“纯净”的角度来看,DTO应该完全不知道它的执行环境。我明白你的意思了。我将尝试实现它,并检查服务定位器模式的优点是否大于缺点(如wikipedia文章中明确描述的)。谢谢
      public class ProductReferenceReqHandler implements ProductRequestHandler<ProductReferenceRequest>{
    
          @Override
          public ProductResponse handleRequest(ProductReferenceRequest req){
           //implementation grime goes here
          }
    
      }
    
       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);
    
            }
    
       }