2

Мой вопрос очень прост: как получить личные данные моего класса в хранилище для сохранения?DDD - Управление связью между доменом и репозиторием

Независимо от архитектурного стиля, который мы принимаем, все согласны с тем, что бизнес-объекты не должны знать «как», чтобы спасти себя, то есть им не следует внедрять базу данных или другие данные о сохранении. Однако мне кажется, что бизнес-объекты являются единственными, кто знает «что» им нужно сохранить. Репозиторий знает, как извлечь из базы данных, но если он должен знать, как перевести бизнес-объект в термины базы данных, тогда он должен знать , что для перевода.

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

Предполагая, что мои занятия здесь на самом деле им конкретных хозяйствующих субъектов, что было бы неправильно с делать что-то вроде

interface Exporter 
{ 
    public void Export(String id, String value1, String value2); 
} 

interface Repository 
{ 
    public Entity FindById(String id); 
} 

class Entity 
{ 
    private String id; 
    private String value1; 
    private String value2; 
    private String derivedvalue; 

    public Entity() {} 

    public Entity(String id, String value1, String value2) 
    { 
     this.id = id; 
     this.value1 = value1; 
     this.value2 = value2; 
     this.derivedvalue = /* derived from id, value1, and value2 */; 
    } 

    public void DoBusiness() 
    { 
     // ... 
    } 

    public void Export(Exporter exporter) 
    { 
     Exporter.Export(this.id, this.value1, this.value2); 
    } 
} 

и использовать его как

FlatFileRepositoryAndExporter flatfile = new FlatFileRepositoryAndExporter(...); 
Entity entity = flatfile.FindById(...); 

// Do business logic 
entity.DoBusiness(); 

entity.Export(flatfile); 

Я понимаю, что есть рамки, которые могут помочь но, в конце концов, все они полагаются на какое-то отражение. Я хочу знать, без размышлений, как я могу статически составлять мои объекты, чтобы выставлять свои данные при сохранении инкапсуляции. Единственный ответ, который я могу придумать, - это шаблон посетителя.

+0

Это прекрасно. Я сделал что-то подобное, когда я вставляю зависимости в сущности, чтобы делать разные вещи (например, настойчивость), и он очень хорошо работает для меня. –

+0

Шаблоны посетителей в порядке, но это добавляет некоторый шум для объекта домена. Вы правы, говоря, что все фреймворки и постоянные клиенты используют отражения для сохранения и извлечения объектов. Самым простым был бы сериализатор xml или json, который работал бы без какого-либо сопоставления. То же самое справедливо для баз данных NoSQL. Добавление логики сохранения в ваш домен заставит вас начать ее тестировать, что на самом деле не является частью теста домена.Если вы хотите сериализовать какой-либо файл, вы всегда можете реализовать свой репозиторий в качестве общего списка и использовать некоторую сериализацию, чтобы сохранить его в файловой системе. –

ответ

1

Я, как правило, согласен с @MikeSW в том, что создание внешних инструментов персистентности, способных собирать состояние объекта домена, с помощью незначительных корректировок области (или отражения в виде ORM), часто проще, чем позволить объекту домена сам полностью контролировать то, что сохраняется.

Существует третий способ, который заключается в том, чтобы сущность излучала события, описывающие, что произошло, вместо того, чтобы подвергать его состоянию - это Event Sourcing. Тогда любой, кто хочет, может слушать этих людей и сохранять изменения в любой форме, которые они хотят получить.

1

Не слишком усложняйте свою жизнь. То, что вы пытаетесь сделать, - это в основном сувенир, который работает, но он имеет высокую (как и в очень скучной) стоимость обслуживания. Я обычно json сериализую вещи независимо от того, где я их фактически храню, и я настроил json.net для сериализации защищенных свойств. Таким образом, в основном, я защищал свойства или просто защищал сеттеры, и он работает очень хорошо.

Хотя это не пуристское решение, компромисс очень низок, внутренние элементы объекта не подвергаются воздействию его пользователя. И вы можете иметь такие вещи, как

private List<string>_data=new List<string>(); 
public IEnumerable<string> Data 
{ 
    get { return _data;} 
    protected set { _data=value.ToList(); } 

} 

Этот подход достаточно прост, очень прост в обслуживании и агностик настойчивости.

Btw, экспортер, учитывая его цель, должен иметь дело только с общественными членами, и объект не должен знать об этом.

Смежные вопросы