向 DTO 对象添加行为

Adding behaviour to DTO object

这是一个让我很困惑的设计题。

如您所知,对象由属性和行为组成。在网络编程中,我已经将几个协议对象实现为 DTO。这些就像:

abstract AbstractRequest{

   public abstract AbstractResponse apply();
...
}

MathLessonRequest extends AbstractRequest{

    public AbstractResponse apply(){
          ..do something based on request
    }
...
}

HistoryLessonRequest extends AbstractRequest{
    public AbstractResponse apply(){
          ..do something based on request
    }
}

我想做的是,在我的控制器中我只想做这样的事情:

@RestController
class SchoolRequestController{

    @RequestMapping(value="/",method = RequestMethod.POST, produces = "application/json")
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public AbstractResponse query(AbstractRequest request){

          return request.apply();
    }

}

所以,如您所见,我想赋予 Request 类 执行他们所要求的所有任务的责任。

我的问题是,这是一个好的设计吗?赋予 DTO 对象执行其目的的责任是否正确?或者 DTO 对象只用于数据传输?

PS:这个设计有一个问题,apply 方法需要一些其他对象的外部引用,如服务、dao 等。那么将这种依赖关系注入到这个实例中的优雅方法是什么?

通常 DTO 没有逻辑(或者非常简单的转换逻辑,例如从出生日期返回一个人的年龄)。

您可以使用那里的模式...当然,只是这些对象不是真正的 DTO,而是更丰富的对象(这通常很好)。您没有为 class 名称添加 'DTO' 后缀,所以我会说您做得很好,因为 Request 对象可能有一些行为。

编辑

我明白你想做什么了。可以使用依赖注入 + AOP,但我认为还有其他模式可能具有更明显的区别并且更少的黑魔法。

根据您想要使用的方法,您的 Request 是您的应用程序(您领域的核心)的入口点,代表您想要 运行 的用例。

我通常使用的方法是基于 Domain-Driven 设计 (DDD) 和六边形架构,使 DTO 可能与传输技术有某种绑定(例如 xml/json注释)。我使用了一层 Application Services 作为域逻辑的外观。 Application Service 只负责编排,不负责业务逻辑。

作为编排的一部分,Application Service 需要获取对具有业务逻辑的对象的引用。在 DDD 中,这些对象通常是 Aggregates.

我想我会写更多关于这个的内容,但是已经有很多非常好的资源解释了如何设计好的应用程序,而且那里的解释比我在这里所做的要好得多:)。

如果您对此感兴趣,并且不介意多花一点时间(也许几块钱)。我强烈建议你得到一份Growing Object-Oriented Software and Implementing Domain-Driven Design。这两本书都很好,很容易阅读,幸运的是所有的例子都在 Java.