Как инициализировать фабрику? - PullRequest
0 голосов
/ 29 октября 2018

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

public class CarFactory
{
    Dictionary<string, Type> cars;

    public ICar CreateInstance(string carName)
    {
        // choose type of class from all classes that implement ICar 
        Type t = GetTypeToCreate(carName); 
        return Activator.CreateInstance(t) as ICar;
    }

    // some more code...
}

Теперь у меня есть служба, которая использует CarFactory. Как правильно инициализировать CarFactory в моем сервисе?

Одним из решений было бы внедрение фабрики, но Factory Pattern - это форма самого IoC , и вводить фабрику кажется странным. По словам Никола Малович :

использование заводов вместе с IoC не имеет большого смысла, потому что Контейнер IoC является в некотором смысле «универсальной абстрактной фабрикой».

Другими словами, по своему опыту, каждый раз, когда я думал о добавлении Завод я закончил с гораздо более простым решением на основе IoC, поэтому я осмелился бы сказать, что «IoC убивает звезду Фабрики»

Вышесказанное имеет для меня абсолютный смысл, хотя я не смог придумать решение заменить мою фабрику на DI.

Итак, мой вопрос (для тех, кто использует фабричный шаблон), как мне его инициализировать?


Чтобы не усложнять вопрос, я использовал упрощенный пример CarFactory в этом вопросе. Я выложил полный пример здесь .

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

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

Но DI-контейнер отвечает за создание экземпляра и всех его зависимостей на основе конфигураций DI. Обычно DI-контейнеры создают экземпляры объектов в точке входа приложения (метод main или request в веб-приложениях).

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

Фабрика - это обычный класс, как и другие классы, и его можно внедрить как зависимость.

В вашем конкретном случае вы знаете имя автомобиля только во время выполнения, поэтому вам понадобится некоторый класс, ответственность за который будет «преобразовывать» имя в экземпляр автомобиля.

0 голосов
/ 31 октября 2018

Как обычно, с такими вопросами, ответ таков: Это зависит ™ . Это зависит от проблемы, которую вы пытаетесь решить. Хотя этот вопрос помечен как инъекция зависимостей и инверсия контроля (в некоторой степени та же идея ), ни один из них не является самоцелью, но только средство для достижения правильной цели.

Обычно целью является разделение поведения . Это приводит к первому вопросу, затем:

Почему CreateInstance возвращает ICar экземпляров?

Я предполагаю, что ICar - это интерфейс. Является ли ICar полиморфным? У вас есть несколько реализаций этого интерфейса?

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

Ради аргумента, однако, давайте предположим, что ICar действительно полиморфен.

Как показано здесь, CarFactory выглядит детерминированным. Трудно сказать, хотя, потому что не вся реализация показана. Если, однако, это относительно прозрачно , то зачем его вообще инициализировать?

Разве это не может быть статической функцией?

public static class CarFactory
{
    public static ICar CreateInstance(string carName)
    {
        // choose type of class from all classes that implement ICar 
        Type t = GetTypeToCreate(carName); 

        return Activator.CreateInstance(t) as ICar;
    }

    // some more code...
}
0 голосов
/ 29 октября 2018

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

Чтобы сделать его еще лучше, вы должны определить интерфейс для вас CarFactory (ICarFactory) и изменить свой сервис в зависимости от этого типа.

В тестах вы можете смоделировать ICarFactory и предоставить специальные реализации для ваших тестовых случаев.

...