В настоящее время я изучаю шаблоны проектирования.
Я думаю, что большинство людей согласится с тем, что эти шаблоны являются отличными инструментами, но их следует использовать с умеренностью, а не как ответ на все вопросы. Их чрезмерное использование слишком усложнит приложение с небольшой выгодой. Шаблоны следует использовать только там, где они могут быть лучшим решением или помочь в создании хорошего решения (вы согласны?).
Имея это в виду:
Книга, которую я читаю (Head First Design Patterns), часто подчеркивает важность слабой связи . Эта слабая связь достигается благодаря следующим принципам, таким как «программа для интерфейса, а не реализация» и «инкапсуляция того, что меняется».
По сути, большинство шаблонов, которые я изучил до сих пор, существуют в основном для того, чтобы конструкции были слабо связаны и, следовательно, были более гибкими.
Я понимаю важность и преимущества слабой связи.
Но мой вопрос заключается в том, сколько усилий нужно на самом деле инвестировать в создание слабо связанных, гибких конструкций?
Те, кто выступает против шаблонов проектирования, говорят, что затраты на использование этих шаблонов часто перевешивают выгоды. Вы тратите много времени на создание слабосвязанного проекта с использованием некоторого шаблона, где на самом деле - слабая связь, «программирование на интерфейс, а не реализация» и все эти принципы - на самом деле не так важны.
Что я хотел бы знать, так это то, сколько усилий я действительно должен приложить для создания дополнительных уровней абстракции и дизайна, только чтобы мое приложение следовало принципам ОО, таким как слабая связь, программирование интерфейса и т. Д. Стоит ли это действительно Это? Сколько усилий я должен приложить к этому?
источник
Ответы:
Фатальный ответ: чем больше ты это делаешь, тем меньше усилий.
По сути, создание слабосвязанного кода на самом деле не очень сложно. С другой стороны, тренировать свой ум думать в терминах слабой связи. И, ну, я верю, что оно того стоит.
Предположим, вы берете работу, в которой используется итеративный подход к разработке программного обеспечения, как это было рекомендовано большинством всех в течение последних 20 лет. Вы создаете что-то, что прекрасно работает в итерации 1. В итерации 2 вы строите поверх нее, добавляя некоторые новые функции и немного сгибая одну или две вещи, когда они не вписываются в вашу концепцию итерации 1 о том, как все должно работать , Теперь идет итерация 3, и вы узнаете, что требования требуют переосмысления вашей базовой архитектуры. Как вы разрываете свой код на части и перестраиваете его, не возвращаясь к исходной точке?
Это случилось. Много. Это либо приводит к тому, что проекты запускаются с опозданием, либо к тому, что все слишком напуганы, чтобы делать то, что необходимо сделать на последующих итерациях. В лучшем случае вы получите Большой Грязевой Шар. Такие вещи, как слабая связь и принцип единой ответственности, в значительной степени смягчают эти проблемы. Вот почему твердые принципы рекламируются - они действительно помогают.
И вы обнаружите, что после того, как у вас есть несколько слабо связанных конструкций под вашим поясом, он начинает появляться естественно. Шаблоны - это то, что люди нашли для себя подходящим, поэтому они документировали их. Это полезные инструменты, которые также приходят со временем.
источник
Необходимое количество усилий не всегда скажет вам достаточно; Я думаю, что лучшей мерой будет соотношение усилий к отдаче. Но выяснить, какой может быть отдача, не всегда просто и безошибочно.
Следует помнить о шаблонах, повышающих гибкость, в том, что их вставка требует определенных усилий, и если вы не можете точно понять, зачем они вам нужны, у вас могут возникнуть сложности в коде, но никогда их не использовать. Если гибкость никогда не изгибается, она может и не быть там.
Есть одна вещь, которую вы должны делать всегда (или как можно ближе к ней): превращение отдельных компонентов вашего программного обеспечения (объектов для ООП, функций для функционального или процедурного программирования) в черные ящики. Черный ящик - это то, чьи внутренности (реализация) мы не знаем или не заботимся.
Если мы не знаем или не заботимся о том, как это работает, то мы не будем пытаться использовать что-либо, кроме интерфейса, поэтому, если реализация меняется без изменения интерфейса, это имеет значение только внутри черного ящика - ничего за его пределами могут быть затронуты. Это также облегчает размышления о программе, потому что вам не нужно держать каждую деталь всей программы в своей голове. Чем больше деталей вы можете законно забыть, тем больше места в вашей голове для деталей, которые имеют значение.
Я думаю, что вы неправильно поняли возражения против шаблонов проектирования; Я не фанат их, но мне очень нравится принцип слабой связи и программирования интерфейса. Мое самое сильное возражение против них заключается в том, что они представлены как готовое решение, которое не поощряет понимание принципов, лежащих в их основе, а скорее способствует запоминанию деталей. Я не собираюсь рекомендовать вам не изучать их, но когда вы это делаете, помните, что понимание принципов, лежащих в их основе, важнее, чем специфика какой-либо конкретной модели.
Одно из возражений против шаблонов проектирования заключается в том, что они «очевидны» или «я использовал их до того, как услышал о них, но только не под этим именем». Причина, по которой люди могут выдвигать эти возражения, или создатели шаблонов проектирования, в первую очередь, могут придумать их, заключается в том, что они поняли принципы, лежащие в их основе.
Использование черных ящиков организует ваш код разумным способом, и они обычно не стоят дорого (если вообще что-то); используйте их повсюду. Использование шаблона проектирования или какой-либо другой техники, которая добавляет уровень абстракции или усложняет вещи, имеет свою стоимость; никогда не используйте их только потому, что они красивые, аккуратные или умные; используйте их, когда они подходят к проблеме, и стоимость того стоит, чтобы получить выгоду.
источник
Ваш вопрос, кажется, приравнивает слабую связь с шаблонами проектирования, но они действительно отдельные, но связанные вещи.
Слабая связь - фундаментальная проблема в программировании. Как только мы перешли от машинного кода к символическим языкам, программы стали слабо связаны с их выполнением. И т.п.
Сам по себе OO - это модель для создания слабосвязанных компонентов. Инкапсуляция делает внутреннюю часть объектов слабо связанной с другими объектами. Функциональное программирование может быть даже более того, потому что выполнение функции слабо связано с выполнением других функций в крайнем случае.
Почти по определению, любой дизайн, который вы делаете, предполагает слабую связь. Существуют способы, позволяющие непреднамеренно связывать вещи, но я видел лишь несколько случаев, когда кто-то на самом деле проектировал систему для более тесной связи.
(Время от времени я работаю с кем-то, кто хочет помешать будущим разработчикам делать выбор дизайна, встраивая статические ссылки на конкретные артефакты платформы, форсируя их использование - нарочно. Но это действительно исключение. Большинство проектов вращается вокруг того, чтобы разбить вещи на модульность и повторно использовать во многих контекстах.)
источник
Я вижу шаблоны проектирования строго как детали реализации. Если вы документируете свои общедоступные API и программируете эту документацию, в общем случае не имеет значения (или не сильно повлияет на вас), где у вас есть шаблоны проектирования. То есть, вы не говорите: «У меня есть шаблон моста, и я добавлю посетителя поверх него». Вместо этого это «этот класс будет иметь разные реализации в разных операционных системах, поэтому он будет реализован с использованием шаблона моста». Затем, когда вы используете его, вам безразлично, что он реализован в виде моста - потому что вы смотрите на публичный API, а не на шаблон моста.
Слабая связь может быть достигнута, следуя простому набору правил. Если вы уважаете их, ваш код будет (более) слабо связан, как вы пишете (т.е. любые усилия уже являются частью процесса разработки).
Среди правил (не исчерпывающий список):
Эти правила соблюдаются по-разному, в зависимости от языка, методологии разработки, используемой вашей командой (например, TDD), временных ограничений бюджета и так далее.
Например, в Java рекомендуется определить ваш интерфейс как
interface
и написать на нем клиентский код (а затем создать экземпляр интерфейса с помощью класса реализации).В C ++, с другой стороны, у вас нет интерфейсов, поэтому вы можете написать интерфейс только как абстрактный базовый класс; Поскольку в C ++ вы используете наследование только тогда, когда к нему предъявляются строгие требования (и поэтому избегаете ненужных виртуальных функций), вы, вероятно, не будете определять интерфейс отдельно, только заголовок класса).
Я думаю, что они делают это неправильно. Если вы пишете слабосвязанный (и СУХОЙ) код, интеграция в него шаблонов проектирования требует минимальных дополнительных усилий. В противном случае вам придется адаптировать свой код для реализации шаблона проектирования.
Если вам нужно внести множество изменений для реализации шаблона проектирования, ваша проблема не в шаблоне проектирования, а в том, что ваша кодовая база является монолитной и тесно связанной. Это плохая / неоптимальная проблема проектирования, а не проблема шаблонов проектирования.
Ваши вопросы приводят (неустановленное) предположение, что единственным преимуществом слабой связи является возможность легко реализовывать шаблоны проектирования. Не то.
Среди преимуществ слабой связи:
... и несколько других, которые не приходят мне в голову прямо сейчас.
источник