继承和REST API控制器-处理子类 [英] Inheritance and REST API Controllers - Dealing with Subclasses

查看:47
本文介绍了继承和REST API控制器-处理子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Coupon and Deals平台开发以下类层次结构:

I have the following class hierarchy for Coupon and Deals platform am developing::

Promotion - abstract
 - Coupon
 - Sale
 - Deal

(优惠券销售交易)是从促销继承的.促销具有名为 type 的字符串属性和将子类的type属性初始化为字符串值的抽象方法,例如,优惠券中的 type 获得值"Coupon" 等...)

(Coupon, Sale and Deal inherit from Promotion. Promotion has a string attribute called type and an abstract method that initializes the the type attributes of the subclasses to a string value. For instance the type in coupon gets the value "Coupon" etc...)

对于每个子类,我都有一个 DAO Service 类,例如 CouponDAO CouponService 等.

For each subclass, I have a DAO and Service classes like CouponDAO, CouponService, etc.

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

In the front-end users can create Coupon or Sale or a Deal through Angular 2 interface so I decided to have the following controllers:

PromotionController - abstract
 - CouponController
 - SaleController
 - DealController

( CouponController SaleController DealController PromotionController 继承)

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

The PromotionController will contain all the common CRUD functions common to all subclasses and in the specific controllers I will handle specific operations meant for those classes.

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

A) The issue am facing now is how to instantiate the correct object coming from the client side. For instance when a user submit a Coupon or a Sale or a Deal how do I instantiate the right object. For instance in the PromotionController I have a function like this::

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

促销(抽象)是该函数的参数.是否应该使用工厂模式和 ** type ** 属性创建正确的对象?例如,如果 type ="Coupon" ,那么我创建了优惠券对象,如果它是"Sale" ,那么我创建了Sale对象

Promotion which is abstract is the argument of the function. Should I use the factory pattern and the **type** attribute to create the right object? For instance if the type="Coupon" then I create Coupon object, if it is "Sale" then I create the Sale object

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

B) Since the controller uses the Services objects it means that I have to declare all the three services objects in the PromotionController. Because after instantiating the right object, I need to call its corresponding service to do the job. In the method above I have promotionService which I think should be replaced with the right service of subclass

C)我正在寻找如何像上面描述的那样处理现实世界中处理子类的REST API

C) I am looking for how to handle REST APIs that deals with subclasses in the real world like the situation I have described above

D)我正在考虑通过将所有CRUD操作复制到它们的特定控制器来简化操作,但这似乎是重复的代码.

D) I was thinking of making it easy for myself by copying all the CRUD operations to their specific controllers but it seems that will be repetitive code.

我认为有更好的方法可以完成.

I think there is a better way that can be done.

我还尝试过是否可以找到一个处理这种情况的开源项目,但是似乎我发现的所有项目都使用一个类而不是继承.他们的REST/API无法处理继承情况

I have also tried if I can find an open source project that deals with this situations but it seems all the projects I found use one class and not inheritance. Their REST/APIs don't handle inheritance situations

推荐答案

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

In my view, keep your endpoints simple. From a REST API standpoint, create individual or only one controller and use the following patterns after the controller layer. From what I have seen, it is always better to keep REST endpoints away from inheritance/reuse and apply it later after receiving and validating the requests.

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

To instantiate service/helper layer from controllers, use factory method pattern:

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

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

Create a PromotionServiceFactory which returns the PromotionService implementation depending upon the promotion type.

在控制器中,使用工厂调用相应的促销服务方法.工厂仍然接受促销"类型的参数.

In controller, invoke corresponding method of promotion service using the factory. The factories still accept arguments of type 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方法.

From your questions, it seems like that there are common CRUD/other methods for different promotion types. This is a good candidate of the template pattern in the service layer if some of the steps/sub-tasks are same for every promotion and the others vary. Otherwise, you could just store the common CRUD methods by creating an abstract promotion service.

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

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

Create an abstract promotion service with the primary method and implementations of common CRUD methods. Create individual implementations of other promotion service types with respective varying methods.

这篇关于继承和REST API控制器-处理子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆