Смешно ли называть этот класс "фабрикой"? - PullRequest
5 голосов
/ 16 ноября 2009

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

Я создал несколько классов, которые на самом деле инкапсулируют создание объектов, но по другой причине: объекты трудно создать. На данный момент я называю эти классы "фабриками", но я обеспокоен тем, что это может быть неправильным и может привести в замешательство других программистов, которые могут посмотреть на мой код. Мои "фабричные" классы не решают, какой конкретный класс создавать, они гарантируют, что ряд объектов будет создан в правильном порядке и что правильные классы будут переданы в правильные конструкторы, когда я вызову new().

Например, для проекта MVVM, над которым я работаю, я написал класс, чтобы гарантировать, что мой SetupView будет создан правильно. Это выглядит примерно так:

public class SetupViewFactory
{
    public SetupView CreateView(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities)
    {
        var setupViewModel = new SetupViewModel(databaseModel, settingsModel, viewUtilities);
        var setupView = new SetupView();
        setupView.DataContext = setupViewModel;
        return setupView;
    }
}

Смешно ли называть это «фабрикой»? Он не выбирает среди нескольких возможных конкретных классов, и его возвращаемый тип не является интерфейсом или абстрактным типом, но он инкапсулирует создание объекта.

Если это не "фабрика", что это?


Редактировать

Некоторые люди предположили, что это на самом деле Образец Строителя.

Определение шаблона Builder из dofactory выглядит следующим образом:

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

Это тоже немного натянуто. Что меня беспокоит, так это «разные представления». Моя цель не состоит в том, чтобы абстрагировать процесс построения View (не то, что это не достойная цель). Я просто пытаюсь поместить логику для создания определенного представления в одном месте, чтобы, если какой-либо из компонентов или процесс создания этого представления изменился, мне нужно было только изменить этот один класс. Кажется, что шаблон конструктора действительно говорит: «Давайте создадим общий процесс создания представлений, тогда вы сможете следовать тому же базовому процессу для любого создаваемого представления». Хорошо, но это не то, что я здесь делаю.


Редактировать 2

Я только что нашел интересный пример в статье в Википедии об инъекции зависимостей .

В разделе «Вводимые вручную зависимости» он содержит следующий класс:

public class CarFactory {

    public static Car buildCar() {
        return new Car(new SimpleEngine());
    }

}

Это почти точно использование, которое у меня есть (и, нет, я не писал вики-статью:)).

Интересно, что этот комментарий следует за этим кодом:

В приведенном выше коде завод берет на себя ответственность за сборку автомобиля и впрыскивает двигатель в автомобиль. Это освобождает автомобиль от знания того, как создать двигатель, хотя теперь CarFactory должен знать о конструкции двигателя. Можно создать EngineFactory, но это просто создает зависимости между фабриками. Таким образом, проблема остается, но по крайней мере была перенесена на фабрики или строителя объектов. [мой акцент]

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

Ответы [ 9 ]

4 голосов
/ 17 ноября 2009

Для меня это не сильно отличается от конструктора для экземпляра SetupView. Возможно, слишком много контекста кода было исключено из вашего примера, но я не понимаю, почему то, что у вас есть, не может быть просто записано как конструктор, а аргументы переданы в качестве аргументов конструктору.

Если судить строго по паттернам GoF, я думаю, что он не соответствует заводской отметке по двум причинам:

  1. нет семейства связанных / зависимых объектов
  2. конкретный класс действительно указан

Что касается Builder, я думаю, что в аспекте различий продуктов он отсутствует.

Когда я преподаю курсы «Шаблоны проектирования», я говорю студентам не только о намерении шаблона при попытке определить «наилучшее соответствие», но и о применимости и структуре / участниках. Намерение может помочь вам исключить вещи, но применимость и структура / участники помогут вам в этом.

Если вы можете определить, какая часть вашего проекта выполняет различные роли участников в (Абстрактной) Фабрике или Строителе, то вы нашли хороший пример для использования этой номенклатуры.

4 голосов
/ 16 ноября 2009

Мне кажется, что у вас есть больше шаблонов Builder , чем шаблон Factory .

1 голос
/ 17 ноября 2009

Почему бы не два класса с простыми конструкторами?

 public class SetupViewModel {
      public SetupViewModel(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities) {
          this.DatabaseModel = databaseModel;
          this.SettingsModel = settingsModel;
          this.ViewUtilities = viewUtilities;
      }
 }

и

 public class SetupView {         
      public SetupView(SetupViewModel model) {              
          this.DataContext = model;
      }
 }

Таким образом, оба класса четко указывают, что им нужно построить.

1 голос
/ 16 ноября 2009

Это кажется мне немного странным. Это не абстрактная фабрика, но она не совсем подходит и для шаблона Builder. Что было бы для меня наиболее разумным, так это то, что вместо SetupViewFactory с методом CreateView я бы переместил этот метод в класс SetupView и сделал бы его статичным. Таким образом, вы бы ...

public class SetupView
{
    public static SetupView CreateView(DatabaseModel databaseModel, SettingsModel settingsModel, ViewUtilities viewUtilities)
    {
        var setupViewModel = new SetupViewModel(databaseModel, settingsModel, viewUtilities);
        var setupView = new SetupView();
        setupView.DataContext = setupViewModel;
        return setupView;
    }
}

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

В ответ на комментарий ОП:

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

public class SetupView
{
    public static SetupView CreateView(SetupViewModel model)
    {
        var setupView = new SetupView(); { DataContext = model };
        return setupView;
    }
}
1 голос
/ 16 ноября 2009

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

1 голос
/ 16 ноября 2009

Я думаю, это «Фабрика». Когда я смотрю на объявление класса, я рад видеть, что это «Фабрика», и более того, это «Фабрика» объектов SetupView. Так что я знаю, что эта Фабрика даст мне конкретные и правильно построенные экземпляры SetupView.

1 голос
/ 16 ноября 2009

GoF назовите это " Builder "

0 голосов
/ 17 ноября 2009

Я бы предпочел согласиться с Джейсоном выше. Для меня это больше похоже на шаблон Builder, но если бы вы превратили SetupView в интерфейс, это было бы больше похоже на шаблон Factory. Ключ к шаблону Factory - позволить шаблону Factory выполнять всю работу по определению того, что возвращать из вызова функции. Поэтому я бы подумал, что вам придется переключаться между различными опциями, учитывая входные параметры.

0 голосов
/ 16 ноября 2009

Вы можете назвать это «Волшебником».

...