Свободная связь без вариантов использования анти-паттерном?

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/8565

Вопрос

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

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

Считаете ли вы сосредоточенность на свободной связи без каких-либо вариантов использования свободной связи (например, избегание дублирования кода или планирование изменений, которые, вероятно, произойдут в обозримом будущем), чтобы быть анти-паттерном? Может ли свободная связь подпадает под зонт Ягни?

Это было полезно?

Решение

В некотором роде.

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

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

Другие советы

Это практика программирования Икс хорошо или плохо? Ясно, что ответ всегда "это зависит."

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

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

Если вы «разработаете» свое решение, чтобы его можно было бесконечно расширить и измениться, то вы на самом деле усложняете его.

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

(В настоящее время я работаю в довольно маленькой кодовой базе, которая очень сложна делает простую работу, и частью того, что делает ее настолько сложным, является отсутствие понимания терминов «связывание» и «сплоченность» со стороны оригинала Разработчики.)

Я думаю, что ты здесь понимаешь, - это концепция сплоченность. Анкет У этого кода есть хорошая цель? Могу ли я усвоить эту цель и понять «общую картину» того, что происходит?

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

С гибкой точки зрения, я мог бы предположить, что такая свободная связь будет анти-паттерном. Без сплоченности или даже использования для этого вы не можете написать разумные модульные тесты и не можете проверить цель кода. Теперь гибкий код может привести к свободной связи, например, когда используется разработка, управляемая тестированием. Но если были созданы правильные тесты, в правильном порядке, то, вероятно, есть и хорошая сплоченность, и свободная связь. И вы говорите только о случаях, когда явно нет сплоченности.

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

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

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

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

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

Простой ответ - свободная связь хороша, когда это сделано правильно.

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

Простые правила дизайна: 1. Не создайте знания нескольких элементов в одну точку (как указывается повсюду, зависит от зависимости), если вы не создаете интерфейс фасада. 2. Одна функция - одна цель (эта цель может быть многогранна, например, в фасаде) 3. Один модуль - один четкий набор взаимосвязанных функций - одна четкая цель 4. Если вы не можете просто проверить его, то у него нет Простая цель

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

Печальная вещь о разработке программного обеспечения в наши дни состоит в том, что 90% людей разрабатывают новые системы и не имеют возможности понимать старые системы и никогда не находятся вокруг, когда система достигла такого плохого состояния здоровья из -за постоянного рефакторинга битов и предметов.

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

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

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

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

Поэтому мне нравится предпочесть стабильность и полную развязку, чтобы я мог, по крайней мере, с уверенностью сказать: «Эта небольшая изолированная библиотека, которая использовалась годами и обеспеченной тщательным тестированием, почти не имеет вероятности требовать изменений, независимо от того, что происходит в хаотическом внешнем мире . " Это дает мне небольшой кусок здравомыслия, независимо от того, какие изменения дизайна требуются снаружи.

Связь и стабильность, пример ECS

Я также люблю системы компонентов сущностей, и они вводят много тесной связи, потому что система зависимости от компонентов-все это доступ и напрямую манипулирует необработанными данными, например, так:

enter image description here

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

Тем временем может быть свободно связанная альтернатива:

enter image description here

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

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

Я обнаружил, что на практике вышеупомянутый тип «плоской» системы ECS гораздо проще рассуждать, чем даже самые слабое связанные системы со сложной паутиной свободной зависимости и, что наиболее важно для меня, я нахожу так мало причин Чтобы версия ECS когда -либо нуждалась в изменении любых существующих компонентов, поскольку компоненты зависели, не несут никакой ответственности, кроме как предоставить соответствующие данные, необходимые для функционирования систем. Сравните сложность проектирования чистого IMotion Интерфейс и конкретный объект движения реализуют этот интерфейс, который обеспечивает сложную функциональность, пытаясь поддерживать инварианты над частными данными и компонентом движения, который должен предоставить только необработанные данные для решения проблемы и не беспокоиться о функциональности.

Функциональность намного сложнее получить правильно, чем данные, поэтому я думаю, что часто предпочтительнее направлять поток зависимостей к данным. В конце концов, сколько библиотеки Vector/Matrix там? Сколько из них используют одно и то же представление данных и только тонко различаются в функциональности? Бесчисленное количество, и все же у нас все еще есть так много, несмотря на идентичные представления данных, потому что мы хотим тонких различий в функциональности. Сколько библиотек изображений там? Сколько из них представляют пиксели по -другому и уникальным образом? Вряд ли и снова и снова показывают, что функциональность гораздо более нестабильна и подвержена изменению проектирования, чем данные во многих сценариях. Конечно, в какой -то момент нам нужна функциональность, но вы можете разработать системы, где основная часть зависимостей движется в направлении данных, а не к абстракциям или функциональности в целом. Таково будет определять приоритет стабильности выше связи.

Наиболее стабильные функции, которые я когда -либо писал (то, что я использовал и повторно использую с конца 80 -х годов, не меняя их вообще), - все те, которые полагались на необработанные данные, например, функция геометрии, которая только что приняла массив Поплавки и целые числа, а не те, которые зависят от комплекса Mesh объект или IMesh умножение интерфейса или вектор/матрицы, которое только зависело от float[] или же double[], не тот, который зависел от FancyMatrixObjectWhichWillRequireDesignChangesNextYearAndDeprecateWhatWeUse.

Лицензировано под: CC-BY-SA с атрибуция
scroll top