Подтвердить что ты не робот

Есть ли пример модели с богатой долей?

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

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

В идеале список кодов должен быть в Java или Groovy, но что-то подобное (например, С#) будет делать.

4b9b3361

Ответ 1

Я дам вам простой пример реального производственного кода:

Person.groovy:

  List addToGroup(Group group) {
    Membership.link(this, group)
    return groups()
  }

Membership.groovy:

 static Membership link(person, group) {
    def m = Membership.findByPersonAndGroup(person, group)
    if (!m) {
        m = new Membership()
        person?.addToMemberships(m)
        group?.addToMemberships(m)
        m.save()
    }
    return m
}

Всякий раз, когда я хочу связать человека с группой, я могу просто сделать person.addToGroup(group)

Процедурный код будет выглядеть примерно так: на вашем контроллере:

def m = Membership.findByPersonAndGroup(person, group)
 if (!m) {
        m = new Membership()
        person?.addToMemberships(m)
        group?.addToMemberships(m)
        m.save()
}

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

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

Вы также можете увидеть Мартина Фаулера Транзакция Script vs Domain Model для краткого объяснения этих двух шаблонов, которые я считаю связанными с DDD.

Ответ 3

Я думаю, что никто не проводил такого сравнения, и если бы это было так, то это было бы мало. Domain Driven Design пытается решить сложность, и простой пример не содержит сложности.

Может быть Проект Driven Step by Step даст вам несколько ответов.

Ответ 4

Это точно не отвечает на ваш вопрос, но я вижу противоположность архитектуры, управляемой доменами, как дизайн, управляемый базой данных. В проекте, основанном на базе данных, сначала создается схема базы данных, а затем вы создаете свои классы с полным пониманием того, как выглядит схема. Преимущество состоит в том, что вы лучше понимаете, что происходит "под капотом", и минимизируйте влияние несоответствия импеданса. Однако недостатком является то, что схема базы данных, поскольку она реляционная, а не объектно-ориентированная, не очень хорошо переводит объекты (например, в реляционных базах данных нет понятия коллекции).

В доменном дизайне теоретически вы создаете свои объекты данных так же, как и любой другой класс, и рассматриваете базу данных как просто уровень сохранения. В терминах Layman база данных является только контейнером для хранения, и вам все равно, КАК хранятся объекты, только что они каким-то образом хранятся. Это устраняет несоответствие импеданса, и вам остается меньше беспокоиться. На практике, однако, вы все равно должны знать, как хранятся объекты, и могут возникнуть проблемы с производительностью, когда используемая вами ORM пытается выплеснуть сложный SQL-запрос.

Edit:

Вот пример того, какой дизайн, основанный на доменах, должен быть в принципе. Скажем, у вас есть класс Person, например (на С#):

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
    public ICollection<Person> Relatives { get; set; }
    public Company Employer { get; set; }
}

Теперь, в реляционной базе данных, это, вероятно, переведет на 3 таблицы, таблицу Person, таблицу адресов и таблицу Company, с кучей отношений между ними. Однако это значительно отличается от того, как программист видит этот объект. Программист видит его как экземпляр объекта Person с 4 параметрами, один из которых - ICollection. Это не очень хорошо сочетается с структурой таблицы базы данных, следовательно, "несоответствие импеданса" или в терминах Laymen, разница в макете между реляционной моделью и объектной моделью.

В доменном дизайне я должен это сделать:

Person person = new Person();
// set each property to something
Database.Save(person);

Теперь объект person сохраняется. Я могу получить его так:

Person databasePerson = Database.Get<Person>(idOfPerson);

И он вернет мой объект Person, как и прежде, чем я его сохранил. Таким образом, я не беспокоюсь о том, как файл данных сохраняет его или беспокоится о несоответствии импеданса. Я просто сохраняю его и извлекаю его по мере необходимости.

Это все в теории. На практике вам, вероятно, придется вручную указать "сопоставление" или как классы узнают, какую таблицу/столбец в базе данных получить данные. Он может стать довольно сложным, когда вы пытаетесь сопоставить более сложные типы, такие как словари и другие ADT, а также когда вы пытаетесь извлечь данные из нескольких таблиц в один класс.