继承和REST API控制器 - 处理子类

时间:2018-06-04 20:27:45

标签: java spring rest spring-mvc spring-boot

我有优惠券和优惠平台的以下类层次结构正在开发::

Promotion - abstract
 - Coupon
 - Sale
 - Deal

优惠券促销促销>继承自促销。促销有一个名为type的字符串属性和一个抽象方法将子类的类型属性初始化为字符串值。例如,优惠券中的type获取值“优惠券”等...)

对于每个子类,我有一个 DAO Service 类,如CouponDAOCouponService等。

在前端,用户可以通过 Angular 2 界面创建优惠券促销促销,我决定拥有以下控制器:

PromotionController - abstract
 - CouponController
 - SaleController
 - DealController

CouponController SaleController DealController 继承自 PromotionController

PromotionController将包含所有子类共有的所有常见CRUD函数,在特定控制器中,我将处理针对这些类的特定操作。

A)现在面临的问题是如何实例化来自客户端的正确对象。例如,当用户提交优惠券促销交易时,如何实例化正确的对象。例如,在 PromotionController 中,我有一个像这样的函数::

@RequestMapping(value=CREATE_PROMO, method=RequestMethod.POST)
    public ResponseEntity<?> create(@RequestBody Promotion promotion){
        promotionService.save(promotion);
        return new ResponseEntity<>("", HttpStatus.OK); 
    }

促销是抽象的函数的参数。我应该使用工厂模式和**type**属性来创建正确的对象吗? 例如,如果 type =“Coupon”,那么我创建Coupon对象,如果它是“Sale”,那么我创建Sale对象

B)由于控制器使用Services对象,这意味着我必须在 PromotionController 中声明所有三个服务对象。因为在实例化正确的对象之后,我需要调用其相应的服务来完成这项工作。在上面的方法中,我有promotionService,我认为应该用子类的正确服务替换

C)我正在寻找如何处理REST API来处理现实世界中的子类,就像我上面描述的情况一样

D)我想通过将所有CRUD操作复制到他们的特定控制器来让自己变得容易,但似乎这将是重复的代码。

我认为有更好的方法可以做到。

如果我能找到一个处理这种情况的开源项目,我也试过,但似乎我找到的所有项目都使用一个类而不是继承。他们的REST / API不处理继承情况

3 个答案:

答案 0 :(得分:2)

在我看来,保持端点简单。从REST API的角度来看,创建单个或仅一个控制器并在控制器层之后使用以下模式。从我所看到的情况来看,最好让REST端点远离继承/重用,并在接收和验证请求后应用它。

要从控制器实例化服务/辅助层,请使用工厂方法模式:

https://en.wikipedia.org/wiki/Factory_method_pattern

创建一个PromotionServiceFactory,它根据促销类型返回PromotionService实现。

在控制器中,使用工厂调用相应的促销服务方法。工厂仍然接受类型为Promotion的论据。

@RequestMapping(value=CREATE_COUPON, method=RequestMethod.POST)
    public ResponseEntity<?> create(@RequestBody Promotion promotion){
//helper if adding one more helper layer. The factory invocation is then //transferred to the helper layer
  PromotionService couponService = promotionServiceFactory.get(PROMOTYPES.COUPON);
couponService.save(promotion);
        return new ResponseEntity<>("", HttpStatus.OK); 
    }

从您的问题来看,似乎有不同促销类型的常见CRUD /其他方法。如果某些步骤/子任务对于每个促销都相同而其他步骤/子任务各不相同,则这是服务层中模板模式的良好候选。否则,您可以通过创建抽象促销服务来存储常见的CRUD方法。

https://en.wikipedia.org/wiki/Template_method_pattern

使用常用CRUD方法的主要方法和实现创建抽象促销服务。使用各自不同的方法创建其他促销服务类型的单独实现。

答案 1 :(得分:0)

我认为你可以通过两种方式处理这个问题,具体取决于逻辑。 如果你想保持一切分开,那么为优惠券/交易/销售创建差异端点。这样每个端点都会调用它的控制器等等。

2)如果您认为代码相同,则可以使用抽象工厂模式来实例化正确的服务和DAO对象。

这完全取决于您的业务需求,如果代码逻辑几乎相同,我更倾向于第二种方式。每个继承一个控制器,以便将来如果层次结构增加,则在需要之前不需要创建多个类。

答案 2 :(得分:0)

回答你(A),我想你可以使用requestObject.instanceOf()方法,告诉正确的子类类型,然后使用正确的处理程序进行处理。