Entity и Value object на основе одного класса

250
08 июля 2017, 07:17

Скажите, пожалуйста, в рамках подхода DDD, является ли корректным рассматривать один и тот же класс как Entity и как Value object.

Например, есть объект Book с набором свойств. Книга принадлежит владельцу. Я не хочу каждый раз при изменении информации о книге пересоздавать объект Book в Owner.

В классе Owner содержится приватное поле _userBook типа IBook, представляющее собой Entity. Свойство UserBook (Value object) используется для получения информации о книге владельца. Оно возвращает IBookValue.

В одном случае мне необходимо изменить параметр сущности, в другом случае просто получить информацию о книге без возможности ее изменения.

Насколько корректен данный подход?

public class Program {
    public static void Main() {
        BookDTO book = new BookDTO() {
            Name = "Ведьмак",
            Price = 1500
        };
        Owner user = new Owner(book);
        book.Price = 2000;
        user.UpdateBookInfo(book);
    }
}
// Библиотека
public class Owner : IOwner {
    private IBook _userBook;
    public Owner(IBookValue bookInfo) {
        _book = new Book(bookInfo);
    }
    public IBookValue UserBook{ 
        get { return _userBook; }
    }
    public void UpdateBookInfo(IBookValue bookInfo) {
        _userBook.Update(bookInfo);
    }
}
// Книга
public class Book : IBook {
    public Book(IBookValue bookInfo) {
        Update(bookInfo);
    }
    public string Name { get; private set; }
    public double Price { get; private set; }
    public void Update(IBookValue bookInfo) {
        Name = bookInfo.Name;
        Price = bookInfo.Price;
    }
}
// Информационно-транспортный объект для сериализации, вывода информации о книге и т. д.
public class BookDTO : IBookValue {
    public string Name { get; set; }
    public double Price { get; set; }   
}
// Информация о книге
public interface IBookValue {
    string Name { get; }
    double Price { get; }
}
// Сущность книги
public interface IBook : IBookValue {
    void Update(IBookValue bookInfo);
}

// Информация о владельце книги  
public interface IOwnerValue {
    IBookValue UserBook{ get; }
}
// Владелец книги  
public interface IOwner : IOwnerValue {
    void UpdateBookInfo(IBookValue bookInfo);
}
// Информационно-транспортный объект для сериализации, вывода информации о владельце и т. д.
public class OwnerDTO : IOwnerValue {
    public IBookValue Book { get; set; }    
}
Answer 1

Рассматривать один и тот же объект как Entity и Value object некорректно из-за принципиальных различий. Entity имеет идентичность и жизненный цикл, тогда как Value object это только характеристика Entity.

Нет ничего плохого в измении характерискик Entity, цены в вашем случае. И для этого совершенно не нужно создавать новую сущность. Если вы хотите получить представление объекта для целей транспортировки, то добавьте соответствующий метод ToDto() в книгу, который вернет необходимый набор характеристик.

Кстати, не стоит создавать интерфейсы для доменных объектов, как минимум, пока вам не понадобится от них полиморфное поведение.

READ ALSO
Иконка из DirectoryEntry по типу объекта

Иконка из DirectoryEntry по типу объекта

Реально ли получить иконку из ресурсов Windows по типу объекта из DirectoryEntry?

257
Как в Unity3d использовать возможности C# 5/6/7?

Как в Unity3d использовать возможности C# 5/6/7?

Захотел я идти в ногу со временем, посмотрел новые фишки и плюшки C#6/7, воодушевилсяТам так всё вкусно и круто, что грех не пользоваться

417
Обработка исключения Format Exception

Обработка исключения Format Exception

Как корректно обработать исключение Format Exception на проверку введенных значений в TextBox?

244