重用"设置"跨越不同的方法调用

时间:2014-10-04 11:50:38

标签: web-services oop

这个问题使用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种可能的解决方法。

  1. 为每个方法调用添加必要的参数。优点:简单易懂,在调用方法时很明显,您需要设置&#34;设置&#34;是
  2. 在ServiceInvoker中创建一些这样的setter:
  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;。

    围绕此问题有哪些最佳做法?这种情况是否存在设计模式?

1 个答案:

答案 0 :(得分:1)

这个问题可能最终会被关闭,因为它主要是基于意见的(因为它是),但是将特定请求类型表示为DTO更为清晰。当你把一个类称为“ServiceInvoker”时,我在想Command Pattern。这对您的设计意味着您的Facade的参数应该是不言自明的包,它封装了服务执行其职责所需的所有信息。此设计还应该消除您班级中多种方法的需要。

对于您的服务的来电者,这意味着他们会将不同的参数类型(具有共同的祖先)传递给ServiceInvokerServiceInvoker#invoke中的单个入口点。然后,此方法将采用所有扩展ProductRequest的类。然后ServiceInvoker可以将请求委托给适当的命令处理程序。说明

  1. 创建基类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();
       }
     }
    
  2. 各个服务请求类型应该扩展ProductRequest。根据需要为每种操作类型进行自定义。

  3. 创建将处理特定操作请求的专用ProductRequestHandler类型。让我们尝试专门处理产品参考请求的那个

      public class ProductReferenceReqHandler implements ProductRequestHandler<ProductReferenceRequest>{
    
          @Override
          public ProductResponse handleRequest(ProductReferenceRequest req){
           //implementation grime goes here
          }
    
      }
    
  4. 您应该在地图中堆叠ProductRequestHandler个堆栈,并按请求类型键入。此地图应该是ServiceInvoker

  5. 的成员
  6. 通过访问可能的请求处理程序的地图,您的调用者只需要一个方法: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);
    
            }
    
       }
    

  7. 您所获得的是一个干净,灵活的界面,可以避免Facade中不必要的混乱,并为您的客户提供直观的合约(通过直观命名的DTO)