Почему плохо связано, но хорошо набрано? - PullRequest
9 голосов
/ 30 октября 2010

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

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

Тем не менее, я чувствую, что сильная типизация поощряется, но слабая связь - это плохо.

РЕДАКТИРОВАТЬ: Я чувствую, что либо моя интерпретация слабой связи неверна, либо другие читают ее неправильно. Сильная связь со мной - это когда класс ссылается на конкретный экземпляр другого класса. Слабая связь - это когда класс ссылается на интерфейс, который может реализовать другой класс.

Мой вопрос: почему бы не назвать конкретный экземпляр / определение класса? Я сравниваю это с определением типа переменной, которая вам нужна. Я читал Dependency Injection, и они, похоже, считают, что слабая связь улучшает дизайн.

Ответы [ 9 ]

15 голосов
/ 30 октября 2010

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

Сильный против слабого набора текста

Строго типизированный язык - это (обычно) хорошая вещь, потому что поведение четко определено. Возьмите эти два примера из Википедии:

Слабый набор :

a = 2
b = '2'

concatenate(a, b) # Returns '22'
add(a, b)         # Returns 4

Вышеприведенное может быть немного запутанным и не очень хорошо определенным, потому что некоторые языки могут использовать числовые значения ASCII (возможно, шестнадцатеричные, может быть восьмеричные и т. Д.) Для сложения или объединения, поэтому есть много места для ошибок. Кроме того, трудно понять, является ли a изначально integer или string (это может быть важно, но язык на самом деле не волнует).

Сильно набран :

a = 2
b = '2'

#concatenate(a, b)     # Type Error
#add(a, b)             # Type Error
concatenate(str(a), b) # Returns '22'
add(a, int(b))         # Returns 4

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

Википедия говорит:

Преимущество слабой печати является то, что это требует меньше усилий на часть программиста, чем, потому что компилятор или интерпретатор неявно выполняет определенные виды преобразований. Тем не менее, один заявленный недостаток что слабо типизированные системы программирования поймать меньше ошибок во время компиляции и некоторые из них могут остаться после тестирование завершено. Два часто используемые языки, которые поддерживают многие виды неявного преобразования C и C ++, и это иногда утверждается что это слабо типизированные языки. Однако другие утверждают, что эти языки накладывают достаточно ограничений на как могут быть операнды разных типов смешанный, что два должны рассматриваться как строго типизированные языки.

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

Слабая и жесткая муфта

Прямо из Википедии :

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

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

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

Надеюсь, я пролил немного света здесь:)

5 голосов
/ 15 мая 2014

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

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

4 голосов
/ 14 мая 2013

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

Вы говорите, что A тесно связана с B , если A должен измениться только потому, что B изменился.

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

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

Кстати, вы правы в том, что типизация и связывание связаны,В частности, более сильная и более статичная типизация имеет тенденцию увеличивать сцепление.Например, в динамических языках иногда можно заменить строку на массив, основываясь на представлении о том, что строку можно рассматривать как массив символов.В Java вы не можете, потому что массивы и строки не связаны.Это означает, что если B использовал для возврата массива, а теперь возвращает строку, он гарантированно сломает своих клиентов (только один простой надуманный пример, но вы можете придумать еще много более сложных и убедительных).Таким образом, более сильная типизация и более статическая типизация являются компромиссами.Хотя более строгая типизация обычно считается хорошей, предпочтение статической и динамической типизации во многом зависит от контекста и личных вкусов: попробуйте организовать дебаты между программистами Python и Java-программистами, если вы хотите удачной борьбы.Можно вернуться к исходному вопросу: почему слабая связь обычно считается хорошей?Из-за непредвиденных изменений.Когда вы пишете систему, вы не можете знать, в каких направлениях она будет развиваться в течение двух месяцев или даже двух часов.Это происходит как из-за того, что требования меняются со временем, так и из-за того, что вы, как правило, не полностью понимаете систему до тех пор, пока после вы ее не написали.Если вся ваша система очень тесно связана (ситуация, которую иногда называют «большой шар грязи»), то любое изменение в каждой части системы в конечном итоге будет распространяться через все остальные части системы (определение «оченьтесная связь").Это делает для очень негибких систем, которые в конечном итоге кристаллизуются в жесткую, неприемлемую каплю.Если у вас было 100% предвидение в тот момент, когда вы начали работать в системе, вам не нужно было бы отделять.

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

2 голосов
/ 30 октября 2010

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

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

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

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

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

РЕДАКТИРОВАТЬ: я чувствую, что либо моя интерпретация слабой связи неверна, либо другие читают ееНеправильный путь.Сильная связь со мной - это когда класс ссылается на конкретный экземпляр другого класса.Слабая связь - это когда класс ссылается на интерфейс, который может реализовать другой класс.

Тогда у меня вопрос: почему бы конкретно не вызвать конкретный экземпляр / определение класса?Я сравниваю это с определением типа переменной, которая вам нужна.Я кое-что читал о внедрении зависимостей, и они, кажется, объясняют это тем, что слабая связь улучшает дизайн.

Я не совсем уверен, в чем здесь ваше замешательство.Скажем, например, что у вас есть приложение, которое интенсивно использует базу данных.У вас есть 100 различных частей вашего приложения, которые должны выполнять запросы к базе данных.Теперь вы можете использовать MySQL ++ в 100 разных местах или создать отдельный интерфейс, который вызывает MySQL ++, и ссылаться на этот интерфейс в 100 разных местах.

Теперь ваш клиент говорит, что он хочет использовать SQL Server вместоMySQL.

Какой сценарий, по вашему мнению, будет легче адаптировать?Переписать код в 100 разных местах или переписать код в 1 месте?

Ладно ... теперь вы говорите, что, возможно, переписать его в 100 разных местах не так уж и плохо.

Итак... теперь ваш клиент говорит, что ему нужно использовать MySQL в некоторых местах, SQL Server в других местах и ​​Oracle в других местах.

Что теперь вы делаете?

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

1 голос
/ 30 октября 2010

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

в сочетании с выводом типа и признаками типа свойства (perl6 и другими) или типомклассы (haskell), строго типизированный код может оставаться компактным и элегантным.

1 голос
/ 30 октября 2010

Тем не менее, я чувствую, что сильная типизация поощряется, но слабая связь плоха.

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

Примечание: не путайте строгую и статическую печать

1 голос
/ 30 октября 2010

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

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

0 голосов
/ 02 сентября 2012

Я думаю, что жесткая / слабая связь (для меня: объявление интерфейса и назначение экземпляра объекта) связана с принципом Лискова .Использование слабой связи дает некоторые преимущества принципа Лискова.

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

0 голосов
/ 10 апреля 2012

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

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

...