我有优惠券和优惠平台的以下类层次结构正在开发::
Promotion - abstract
- Coupon
- Sale
- Deal
(优惠券,促销和促销>继承自促销。促销有一个名为type
的字符串属性和一个抽象方法将子类的类型属性初始化为字符串值。例如,优惠券中的type
获取值“优惠券”等...)
对于每个子类,我有一个 DAO 和 Service 类,如CouponDAO
,CouponService
等。
在前端,用户可以通过 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不处理继承情况
答案 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()方法,告诉正确的子类类型,然后使用正确的处理程序进行处理。