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

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

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

В идеале листинг кода должен быть на Java или Groovy, но подойдет и что-то похожее (например, C#).


person Dónal    schedule 02.11.2009    source источник
comment
К сожалению, очень сложно описать преимущества в кратком ответе. Если вы пишете систему, которая содержит много вариантов поведения, а не просто вставку/обновление/удаление, то вы можете извлечь выгоду из инкапсуляции логики в один набор классов (ваших моделей предметной области). Скорее всего, вы не увидите преимуществ, пока у вас не будет достаточно большого решения и логика вашей предметной области не станет достаточно сложной. В этом случае очень удобно инкапсулировать логику вашего домена только в одном месте.   -  person Daniel Lidström    schedule 25.03.2015


Ответы (3)


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

Person.groovy:

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

Членство.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()
}

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

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

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

person Miguel Ping    schedule 17.11.2009

Думаю, такого сравнения еще никто не делал, а если бы и было, то не мало. Проектирование, управляемое предметной областью, пытается решить сложность, а простой пример не содержит сложности.

Возможно, Дизайн на основе домена шаг за шагом даст вам некоторые ответы.

person Marek Tihkan    schedule 02.11.2009

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

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

Изменить:

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

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, таблицу Address и таблицу Company, с кучей отношений между ними. Однако это сильно отличается от того, как программист видит этот объект. Программист видит его как экземпляр объекта Person с 4 параметрами, один из которых — ICollection. Это не очень хорошо согласуется со структурой таблицы базы данных, отсюда и «несоответствие импеданса», или, говоря простым языком, разница в компоновке между реляционной моделью и объектной моделью.

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

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

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

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

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

Хотя это все в теории. На практике вам, вероятно, придется вручную указать «сопоставление» или то, как классы узнают, из какой таблицы/столбца в базе данных получать данные. Это может стать довольно сложным, когда вы пытаетесь сопоставить более сложные типы, такие как словари и другие АТД, а также когда вы пытаетесь извлечь данные из нескольких таблиц в один класс.

person Daniel T.    schedule 02.11.2009
comment
Я не думаю, что это пример богатой модели домена, потому что домен, который вы описываете, не содержит никакого поведения. - person JasonTrue; 17.11.2009
comment
Это не богатый домен. В богатом домене у вас, вероятно, не было бы сеттеров или было бы всего несколько. - person Martin; 11.02.2011
comment
Вы говорите об объектно-реляционном отображении, которое представляет собой совершенно другую концепцию. Ваш класс Person содержит структуру данных, не более того. Вам нужны методы и инкапсуляция (скрытие данных и реализации), чтобы преобразовать его в реальный объект. - person inf3rno; 26.09.2014