DDD - заводской метод и внедрение зависимостей - PullRequest
0 голосов
/ 25 апреля 2009

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

У меня есть объект Value Value, который должен получить доступ к хранилищу, чтобы получить дополнительные данные для завершения класса. Проблема (или проблема дизайна) заключается в том, что новые экземпляры валюты могут создаваться только с помощью фабричного метода.

public class Currency
{
  internal Currency() {}

  public string Name { get; set; }

  public static Currency CreateCurrencyFromAlphaCode(string alphaCode)
  {
    Currency cur = new Currency();
    //Needs repository to set name etc
    return cur;
  }

  public static Currency CreateCurrencyFromCountryCode(string countryCode)
  {
    Currency cur = new Currency();
    //Needs repository to set name etc
    return cur;
  }

  public static Currency CreateCurrencyFromCountryName(string countryName)
  {
    Currency cur = new Currency();
    //Needs repository to set name etc
    return cur;
  }

}

Я думал, что если мне понадобится вставить репозиторий в конструктор, то это сделает метод фабрики бессмысленным?

public class Currency
{
  public Currency(IRepoistory repository)
  {

  }
}

Как мне спроектировать этот класс, учитывая зависимость от репозитория - я должен сделать параметр для каждого из фабричных методов для принятия репозитория?

Ответы [ 4 ]

3 голосов
/ 26 апреля 2009

Я ответил на это в списке DDD , где вы тоже об этом спрашивали, но я повторю свои опасения и здесь.

Я думаю, что вы путаете роли Фабрики и Хранилища.

Ваши методы, названные, например, CreateCurrencyFromAlphaCode, на самом деле выглядят так, как будто они должны быть, например, FindCurrencyByAlphaCode, и они должны существовать в репозитории, а не на фабрике. Фабрика используется для создания объектов, которые не уже существуют в вашем слое постоянства (или для создания экземпляров объектов из данных, которые вы уже получили из вашего слоя постоянства).

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

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

3 голосов
/ 25 апреля 2009

Почему бы вам не переместить здание валюты за пределы класса валюты? Мне не нравится название, но вы можете попробовать что-то вроде CurrencyBuilder. Это может выглядеть так:

public class CurrencyBuilder {
  private IRepository repository;

  public CurrencyBuilder() : this(new DefaultRepository()) {
  }

  public CurrencyBuilder(IRepository repository) {
    this.repository = repository;
  }

  public Currency FromCountryCode(string countryCode) {
    string currencyName = repository.GetCurrencyNameByCode(countryCode);
    if (currencyName == null)
      throw new CurrencyCodeException(countryCode + " not found");

    Currency c = new Currency();
    c.Name = currencyName;

    return c;
  }
}

Используя эту настройку, когда вы вызываете 'new CurrencyBuilder ()', он будет использовать ваш экземпляр репозитория по умолчанию. Однако для тестирования вы можете передать фиктивный репозиторий в конструктор.

Надеюсь, что это поможет, и придерживайтесь этого. Для чего бы это ни стоило, это не хороший пример, где DI очень поможет. Так что, если вы чувствуете себя неудовлетворенным после выполнения этой задачи, не сдавайтесь сразу. Когда вам станет удобнее, его полезность станет более очевидной.

1 голос
/ 25 апреля 2009

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

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

Во-вторых, ваш валютный объект принимает на себя две обязанности. Во-первых, это валюта (очевидно), а во-вторых, она отвечает за создание валют.

Чтобы устранить эти проблемы, можете ли вы разделить фабричные методы из класса валюты на «более высокий» уровень вашего приложения? Если это так, вы можете обнаружить, что все становится легче, поскольку вы можете без проблем внедрить зависимости хранилища в фабрику. Это может означать рефакторинг кода вашего доменного уровня, чтобы вы передавали туда «готовые» валюты, а не коды валют, коды стран и т. Д., Но я думаю, что это само по себе неплохо. Предполагается, что уровень домена должен заботиться о «валюте», а не о «коде валюты».

0 голосов
/ 25 апреля 2009

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

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

...