向 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.
这是一个让我很困惑的设计题。
如您所知,对象由属性和行为组成。在网络编程中,我已经将几个协议对象实现为 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.