Достоинства DI, обзор Реализации фабричной фабрики

Я пишу совершенно новую систему и стараюсь оставаться верным принципам SOLID, в частности, Interfacing and Dependency Injection. Мы внимательно следим за стеком Microsoft, поэтому мы используем C # и контейнер Unity. Я в относительно незрелом магазине, насколько понятны концепции SOLID, поэтому я стараюсь держать все как можно проще для всех, включая меня.

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

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

http://blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator / http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/

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

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

_container.RegisterType<IChartFactory, ChartFactory>();
_container.RegisterType<IDocumentFactory, DocumentFactory>();
_container.RegisterType<IReportFactory, ReportFactory>();
_reportFactory = _container.Resolve<IReportFactory>();
_report = _reportFactory.CreateReport1(runTimeData);

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

public class DocumentFactory : IDocumentFactory
{  
    public IDocument Create(string filePath)
    {
        return new Document(filePath);
    }
}

public interface IReportFactory
{
    IReport CreateReport1(object runTimeData);
    IReport CreateReport2(object runTimeData);
}

public class ReportFactory : IReportFactory
{
    IDocumentFactory _documentFactory;
    IChartFactory _chartFactory;

    public ReportFactory(IDocumentFactory documentFactory, IChartFactory chartFactory)
    {
        _documentFactory = documentFactory;
        _chartFactory = chartFactory;
    }

    public IReport CreateReport1(object runTimeData)
    {
        return new ConcreteReport1(runTimeData, _documentFactory, _chartFactory);
    }

    public IReport CreateReport2(object runTimeData)
    {
        return new ConcreteReport2(runTimeData, _documentFactory, _chartFactory);
    }
}

Мне легко понять и объяснить. Если изменения зависимостей, реализация нескольких строк кода для фабрики кажется небольшой ценой, а не изменением каждого места в системе, где тип обновляется.

Взаимозависимы полные зависимости, и все эти интерфейсы и фабрики чувствуют себя излишними. Меня беспокоит толкание. Я не уверен, что достоинства оправдывают шаблон, и я не уверен, что я делаю это правильно. Любые мысли приветствуются!

3 голоса | спросил grinder22 10 MarpmThu, 10 Mar 2016 20:53:14 +03002016-03-10T20:53:14+03:0008 2016, 20:53:14

1 ответ


1

Добро пожаловать в мир развлечений IoC. Недавно я прошел через это. Это может быть массовое изменение и несколько разочаровывающее.

Несколько элементов обратной связи:

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

  2. Если разработчики в вашей команде не используются для IoC, они могут получить немного расстроенный код отладки, так как они больше не могут использовать «Перейти к определению», чтобы отслеживать, куда идет вызов (он просто покажет их интерфейс, а не реализация). Чтобы сделать это немного менее болезненным, я рекомендую поместить ваш Конструкторы ничего не должны делать (кроме принятия DI). Это связано с тем, что метод ctor, как известно, трудно изолировать по отдельности. Если вам необходимо передать параметры в конструкторе, просто сохраните их в переменных-членах и отложите их на все, используя ленивая инициализация .

    1. Не забывайте, что для фабрик вы не хотите создавать новый каждый раз. С Unity я считаю, что вы использовали бы RegisterInstance или Lifetime manager , чтобы определить, будет ли InitContainers будет возвращать новый экземпляр каждый раз или тот же экземпляр для процесса /потока /запроса.
ответил John Wu 11 FebruaryEurope/MoscowbSat, 11 Feb 2017 03:39:22 +0300000000amSat, 11 Feb 2017 03:39:22 +030017 2017, 03:39:22

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132