【问题标题】:What is the difference between DTO and Command in DDD?DDD中的DTO和Command有什么区别?
【发布时间】:2020-11-08 11:49:25
【问题描述】:

我是 DDD 域驱动开发 实施的新手。我从网上查看了一些项目的源代码,他们使用 DDD 模式实现了这些源代码。在项目结构中,我找到了 DTO 以及 Commands。我需要了解这两者之间有什么区别?是不是代码重复?

以下是项目中存在的 DTO 和 Command 的两个示例类。

public class BookCargoCommand {
    private String bookingId;
    private int bookingAmount;
    private String originLocation;
    private String destLocation;
    private Date destArrivalDeadline;

    public BookCargoCommand(){}

    public BookCargoCommand(int bookingAmount,
                            String originLocation, String destLocation, Date destArrivalDeadline){

        this.bookingAmount = bookingAmount;
        this.originLocation = originLocation;
        this.destLocation = destLocation;
        this.destArrivalDeadline = destArrivalDeadline;
    }

    public void setBookingId(String bookingId){ this.bookingId = bookingId; }

    public String getBookingId(){return this.bookingId;}
    public void setBookingAmount(int bookingAmount){
        this.bookingAmount = bookingAmount;
    }


    public int getBookingAmount(){
        return this.bookingAmount;
    }


    public String getOriginLocation() {return originLocation; }

    public void setOriginLocation(String originLocation) {this.originLocation = originLocation; }

    public String getDestLocation() { return destLocation; }

    public void setDestLocation(String destLocation) { this.destLocation = destLocation; }

    public Date getDestArrivalDeadline() { return destArrivalDeadline; }

    public void setDestArrivalDeadline(Date destArrivalDeadline) { this.destArrivalDeadline = destArrivalDeadline; }
    }

public class BookCargoResource {

    private int bookingAmount;
    private String originLocation;
    private String destLocation;
    private LocalDate destArrivalDeadline;

    public BookCargoResource(){}

    public BookCargoResource(int bookingAmount,
                             String originLocation, String destLocation, LocalDate destArrivalDeadline){

        this.bookingAmount = bookingAmount;
        this.originLocation = originLocation;
        this.destLocation = destLocation;
        this.destArrivalDeadline = destArrivalDeadline;
    }


    public void setBookingAmount(int bookingAmount){
        this.bookingAmount = bookingAmount;
    }


    public int getBookingAmount(){
        return this.bookingAmount;
    }

    public String getOriginLocation() {return originLocation; }

    public void setOriginLocation(String originLocation) {this.originLocation = originLocation; }

    public String getDestLocation() { return destLocation; }

    public void setDestLocation(String destLocation) { this.destLocation = destLocation; }

    public LocalDate getDestArrivalDeadline() { return destArrivalDeadline; }

    public void setDestArrivalDeadline(LocalDate destArrivalDeadline) { this.destArrivalDeadline = destArrivalDeadline; }

    }

注意:因为我找不到确切的问题,所以我把它放了。如果 StackOverflow 中存在类似问题,请告诉我。

【问题讨论】:

    标签: command domain-driven-design dto


    【解决方案1】:

    DTO(数据传输对象)更像是一个技术概念,指的是一个类,该类仅专用于表示属于一起的数据,并用于将这些数据从一个地方传输到另一个地方。

    在这种情况下,命令在技术上是一个 DTO。但它也代表了在业务领域中具有特殊意义的事物——发生的事物,即要在系统中执行的命令。

    因此,该命令可以被视为与系统接收部分执行此预期操作所需的所有数据一起发生的事情。

    该命令可以包含原始数据字段或更复杂的数据,这些数据也可能是一些 DTO。

    所以关于你关于重复的问题,我将如何为你的命令和货物 DTO 建模:

    public class BookCargoCommand {
    
        private String bookingId;
        private CargoResource cargo;
    
        public BookCargoCommand() {}
    
        public BookCargoCommand(String bookingId, CargoResource cargo) {
            this.bookingId = bookingId;
            this.cargo = cargo;
        }
    
        public String getBookingId() {
            return this.bookingId;
        }
    
        public CargoResource getCargo() {
            return this.cargo;
        }
    }
    

    public class CargoResource {
    
        private int bookingAmount;
        private String originLocation;
        private String destLocation;
        private LocalDate destArrivalDeadline;
    
        public CargoResource(
                int bookingAmount,
                String originLocation,
                String destLocation,
                LocalDate destArrivalDeadline
        ) {
            this.bookingAmount = bookingAmount;
            this.originLocation = originLocation;
            this.destLocation = destLocation;
            this.destArrivalDeadline = destArrivalDeadline;
        }
    
        public int getBookingAmount() {
            return this.bookingAmount;
        }
    
        public String getOriginLocation() {
            return originLocation;
        }
    
        public String getDestLocation() {
            return destLocation;
        }
    
        public LocalDate getDestArrivalDeadline() {
            return destArrivalDeadline;
        }
    }
    

    注意:同样的概念也适用于事件(代表系统中已经发生的事情)。

    附注:在我看来,DTO 是不结合数据行为的类的唯一例外。在其他用例中,我会考虑诸如 anemic 之类的类(另请参阅anemic domain model

    【讨论】:

    • 这个答案涵盖了它。我将任何需要over-the-wire 的东西都视为 DTO,因为它通常是序列化的。因此,它不包含任何行为。如果我确实需要向 DTO 添加一些方法,我倾向于使用扩展方法(在 C# 世界中)。 DTO 在某种程度上是该概念的任何其他表示形式的上位词,例如 command/eventrequest/responsemodel
    猜你喜欢
    • 1970-01-01
    • 2011-06-10
    • 2019-12-20
    • 2014-08-19
    • 2011-06-05
    • 1970-01-01
    • 2010-09-20
    相关资源
    最近更新 更多