Подтвердить что ты не робот

Исходные бананы со свободным сцеплением и зависимостью

С последними дополнениями к нашей инфраструктуре инъекций зависимостей (аннотации в spring) предельные затраты на создание компонентов, управляемых DI, по-видимому, достигли некоторого критического нового порога. Хотя ранее были накладные расходы, связанные с spring (тонны XML и дополнительные ссылки), инъекция зависимостей, похоже, начала движение туда, куда идет множество шаблонов; они идут под капотом и "исчезают".

Следствием этого является то, что концептуальные служебные данные, связанные с большим числом, становятся приемлемыми. Можно утверждать, что мы могли бы создать систему, в которой большинство классов один единственный публичный метод и построить всю систему, просто объединив эти штуки, как сумасшедшие. В нашем случае дается несколько вещей; пользовательский интерфейс вашего приложения имеет некоторые функциональные требования, которые формируют самые верхние службы. А задние системы управляют нижней частью. Но между этими двумя, все для захватов.

Наше постоянное обсуждение действительно почему мы группируем вещи в классы и какими должны быть принципы? Несколько вещей уверены; рисунок фасада мертв и похоронен. Любая услуга, содержащая несколько несвязанных функций, также имеет тенденцию делиться. "Несвязанная функция" интерпретируется в гораздо более строгом смысле, чем когда-либо ранее.

В нашей команде есть два преобладающих поезда: здесь зависят ограничения группировки; любая функциональность в одном классе предпочтительно должна быть клиентом всех введенных зависимостей. Мы являемся проектом DDD, а другая часть считает, что домен ограничивает группировку (CustomerService или более мелкозернистый CustomerProductService, CustomerOrderService). Нормализованное использование вложенных зависимостей несущественно.

Итак, в слабосвязанной Вселенной DI, почему мы группируем логику в классы?

edit: duffymo указывает, что это может перейти к функциональному стилю программирования; который поднимает вопрос о государстве. У нас довольно много объектов "State", которые представляют (небольшие) части соответствующего состояния приложения. Мы вводим их в любую службу, которая имеет законную потребность в этом состоянии. (Причина, по которой мы используем объекты "State" вместо обычных объектов домена, заключается в том, что spring построить их в неопределенное время. Я рассматриваю это как небольшое обходное решение или альтернативное решение, позволяющее spring управлять фактическим созданием объектов домена. могут быть лучшими решениями здесь).

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

4b9b3361

Ответ 1

Превосходные принципы хорошего OO Design не останавливаются на свободной связи, но также высокая степень сцепления, которая игнорируется в большинстве обсуждений.

Высокая сплоченность

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

Сплошность уменьшается, если:

* The functionality embedded in a class, accessed through its methods,
  have little in common.
* Methods carry out many varied activities, often using coarsely-grained or 
  unrelated sets of data.

Недостатки низкой когезии (или "слабой когезии" ):

* Increased difficulty in understanding modules.
* Increased difficulty in maintaining a system, because logical changes in 
  the domain affect multiple modules, and because changes in one module 
  require changes in related modules.
* Increased difficulty in reusing a module because most applications
  won’t need the random set of operations provided by a module.

Одна вещь, которая теряется, когда люди сходят с ума с помощью контейнеров IoC, - это потеря целостности и прослеживаемость того, что и как что-то делает что-то, превращается в кошмар, чтобы потом разобраться в собственном по дороге, потому что все отношения затушевываются связкой файлов конфигурации XML (Spring Я смотрю на вас) и слабо названных классов реализации.

Ответ 2

  • Почему мы группируем вещи в классы и какими должны быть принципы?

Вы подчеркиваете, "Группировка", или "Классы?"

Если вы спрашиваете, почему мы группируем вещи, то я бы сказал, что Secondelt's "Поддержание работоспособности", хотя я бы перефразировал его как "Уменьшить потенциальную стоимость эффектов пульсаций".

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

Существует теорема, показывающая, что при заданной цепочке компонент a - b - c - d - e, такой, что a зависит от b и т.д., вероятность того, что изменение e затем изменит c-компонент, не может быть больше чем вероятность того, что изменение e изменит d. И в реальных программных системах вероятность того, что изменение e будет влиять на c, обычно меньше вероятности того, что изменение e повлияет на d.

Конечно, вы можете сказать, что это очевидно. Но мы можем сделать это еще более очевидным. В этом примере d имеет прямую зависимость от e, а c имеет косвенную (через d) зависимость от e. Таким образом, можно сказать, что статистически система, сформированная преимущественно из прямых зависимостей, будет страдать от большего эффекта пульсации, чем система, сформированная преимущественно из косвенных зависимостей.

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

Теперь вернемся к потенциальной связи. Можно показать, что в контексте абсолютной инкапсуляции (например, Java или С#, где рекурсивная инкапсуляция широко не используется) все компоненты потенциально связаны друг с другом посредством прямой зависимости или косвенной зависимости от одного промежуточного компонента. По статистике, система, которая минимизирует прямую потенциальную связь между ее компонентами, минимизирует потенциальную стоимость эффекта пульсации из-за любого обновления.

И как мы достигаем этого различия между прямым и косвенным потенциальным сцеплением (как будто мы еще не выпустили кошку из сумки)? С инкапсуляцией.

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

Для этого обязательно требуется какой-то контейнер группировки, в котором может быть скрыта скрытая информация.

Вот почему мы "группируем" вещи.

Что касается того, почему мы используем классы для группировки вещей:

A) Классы предоставляют механизм инкапсуляции, поддерживающий язык.

B) Мы не просто используем классы: мы также используем пространства имен/пакеты для инкапсуляции.

Привет,

Под ред.

Ответ 3

Я могу думать о двух причинах.

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

Состояние и идентификатор: объекты не только содержат логику, но и поддерживают состояние. Логика, являющаяся частью интерфейса работы с состоянием конкретного объекта, должна быть определена на этом объекте. Объекты также поддерживают идентификацию, объект, который моделирует один объект в проблемной области, должен быть одним объектом в вашем программном обеспечении.

Как side- node: аргумент состояния и идентификации в основном применим к объектам домена. В большинстве решений я использовал контейнер IoC в основном для сервисов вокруг них. Мои объекты домена обычно создаются и уничтожаются как часть потока программы, и я обычно использую для этого отдельные объекты factory. Затем фабрики могут быть введены и обработаны контейнером IoC. У меня был некоторый успех, создавая фабрики как обертки вокруг контейнера IoC. Таким образом, контейнер также обрабатывает время жизни объектов домена.

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

Ответ 4

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

Факторы затрат

  • Накладные расходы DI. Спиннинг всех основных и связанных подходов для одного метода является дорогостоящим. Группировка в класс позволяет нам частично компенсировать это.
  • Навыки - DI новичок для многих (сам ОСОБЕННО), поэтому понимание того, как сделать это лучше или выйти из старых/привычных дизайнов, является жестким.
  • Приложения с коричневым полем, которые у них уже есть, проще/дешевле/быстрее жить с ними и беспокоиться об этом в будущих приложениях с зеленым полем.

Надеюсь, моя новичка (да, я наполнен написанными словами) с DI не сделала меня совершенно неправильным с этим.