Как бороться с чрезмерным внедрением конструктора в .NET - PullRequest
12 голосов
/ 05 января 2011

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

Сегодня я открыл один из классов в моем реальном приложении и обнаружил, что у него есть 13 зависимостей, введенных конструктором !!! Фактически каждый разработчик добавил зависимость, в которой он нуждался, в методе, который он писал.

Одна точка моего понимания DI состоит в том, что когда мы вводим зависимость конструктором, это означает, что это обязательная зависимость и должна использоваться во всех методах класса. Если нам нужна определенная зависимость только в одном методе данного класса, что это значит для вас?

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

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

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

Ответы [ 5 ]

25 голосов
/ 05 января 2011

Вы правы: если вам нужно внедрить 13 зависимостей в класс, это довольно верный признак того, что вы нарушаете Принцип единой ответственности . Переключение на внедрение свойств не поможет , так как это не уменьшит число зависимостей - это будет означать, что эти зависимости являются необязательными, а не обязательными.Существует два способа решения проблемы такого типа:

  • Рефакторинг для Facade Services .По сути это неразрушающий рефакторинг , поскольку он поддерживает функциональность контроллера.Однако это меняет ответственность на координацию / организацию взаимодействия между службами вместо управления подробностями реализации.
  • Разделение класса на независимоеклассы.Если каждая из служб была представлена ​​разными разработчиками для поддержки подмножества методов, это признак низкой когезии .В этом случае было бы лучше разделить класс на несколько независимых классов.

Специально для ASP.NET MVC вы можете не захотеть разделять контроллер, поскольку он изменит вашу схему URL.Это достаточно справедливо, но рассмотрим, что это означает: это означает, что единственная ответственность Контроллера должна заключаться в сопоставлении URL-адресов с кодом приложения .Другими словами, это все, что должен сделать Контроллер, и из этого следует, что правильным решением является рефакторинг для Facade Services .

10 голосов
/ 05 января 2011

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

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

4 голосов
/ 05 января 2011

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

0 голосов
/ 28 ноября 2017

Просто так работает DI.Это факт.Так что прими это.Это полностью законно в сервисе как Сервис PDF, Посмотрите на этот код:

public PdfService(ILocalizationService localizationService, 
        ILanguageService languageService,
        IWorkContext workContext,
        IOrderService orderService,
        IPaymentService paymentService,
        IDateTimeHelper dateTimeHelper,
        IPriceFormatter priceFormatter,
        ICurrencyService currencyService, 
        IMeasureService measureService,
        IPictureService pictureService,
        IProductService productService, 
        IProductAttributeParser productAttributeParser,
        IStoreService storeService,
        IStoreContext storeContext,
        ISettingService settingContext,
        IAddressAttributeFormatter addressAttributeFormatter,
        CatalogSettings catalogSettings, 
        CurrencySettings currencySettings,
        MeasureSettings measureSettings,
        PdfSettings pdfSettings,
        TaxSettings taxSettings,
        AddressSettings addressSettings)
0 голосов
/ 01 декабря 2013

Если у вашего класса 13 зависимостей, у вас точно есть проблема. Очевидно, ваш класс выполняет слишком много обязанностей. Марк Симанн обсуждал эту проблему в своей книге «Внедрение зависимостей в .NET», параграф 6.4. Если ваш класс начинает иметь 3 параметра в конструкторе, вы должны задуматься. Мой класс все еще выполняет одну обязанность? Если в вашем конструкторе появилось 4 или более параметров, проведите рефакторинг вашего класса, начав использовать фасад или композиционный шаблон.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...