Может ли слишком много абстракции быть плохим?

46

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

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

  1. Микромодули, которые подключены к микросистеме: эти модули легко понять, разработать и обслуживать как единое целое. Этот код в основном представляет код, который фактически выполняет функциональные функции, описанные в требованиях.
  2. Соединительный код; Теперь я верю, что проблема здесь. Этот код имеет тенденцию быть сложным, потому что он иногда очень абстрактен и его трудно понять в начале; это возникает из-за того, что это только чистая абстракция, основа реальности и бизнес-логики выполняется в представленном коде 1; по этой причине не ожидается, что этот код будет изменен после тестирования.

Это хороший подход к программированию? Что, имея изменяющийся код, очень фрагментированный во многих модулях и очень легкий для понимания, и неизменяющий код, очень сложный из абстракции POV? Если весь код будет одинаково сложным (то есть код 1 более сложным и взаимосвязанным, а код 2 более простым), чтобы любой, кто просматривает его, мог понять его за разумное время, но изменение стоит дорого, или решение, представленное выше, хорошо, где «изменение кода» очень легко понять, отладить, изменить, а «связать код» довольно сложно.

Примечание: речь идет не о читабельности кода! Оба кода в 1 и 2 доступны для чтения, но код в 2 поставляется с более сложными абстракциями, в то время как код 1 поставляется с простыми абстракциями.

m3th0dman
источник
3
Комментарии и четкие имена придуманы, чтобы ускорить время, необходимое для понимания сложного кода. Вполне нормально, что ваш низкоуровневый код будет более сложным; на каком-то уровне вы почти наверняка вызываете гораздо более сложный и гораздо более низкий уровень.
DougM
25
«Слишком много» - это плохо по определению.
Джон Парди
@JimmyHoffa: должен держать эти типы на своем месте. И не ревнуй - я не могу писать на Хаскеле весь день. На самом деле это в основном PHP, JavaScript и OCaml.
Джон Перди

Ответы:

78

Самые первые слова TC ++ PL4:

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

(Дэвид Уилер был моим научным руководителем. Цитата без важной последней строки иногда называется «Первый закон информатики».)

Бьярне
источник
6
И как вы узнаете, когда у вас слишком много уровней косвенности? Я бы сказал, что это приходит с опытом, но более опытный программист легко понимает больше косвенности, поэтому не видит проблемы со слишком большим количеством уровней.
m3th0dman
2
@ m3th0dman - у вас есть правильный уровень абстракции, когда в будущем становится легко вносить изменения. Конечно, вы также можете спросить, откуда вы знаете, когда это произойдет, что просто повторяет цикл вопросов по-другому.
2
stackoverflow.com/questions/2668355/…
Сиз Тиммерман,
1
этот вопрос похож на уровень программирования. у вас будут сложные программисты, которые поймут вашу сумасшедшую архитектуру 8-уровневого уровня и найдут ее блестящей, в то время как другие простые, но гладкие кодировщики сочтут ее нелепой и будут спорить о вашем сумасшедшем 8-уровневом уровне многоуровневый проект ... это то, где документация окупается, она не только позволяет документировать ваш код, но и защищать его
Райан,
1
простите мое невежество, но я не понимаю "TC ++ PL4"
LastTribunal
30

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

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

Мейсон Уилер
источник
1
«А это значит, что в какой-то момент каждая абстракция каким-то образом протечет». Верно. Лучшая абстракция - это та, которая протекает реже.
Джорджио
11
В свете ответа Бьярне (и ссылаясь на вики-страницу Дэвида Уилера ), возможно, вы сможете изменить свою цитату? :)
congusbongus
2
@CongXu: Кстати, я пошел на это с другого конца: поиск в Google для "цитат Бьярна Страуструпа" и не нашел ни единого упоминания о Бьярне, который произнес фразу "добавление еще одного слоя косвенности" ... Конечно, не окончательно, но делает очень маловероятно, что он первым произнес это.
Марьян Венема
1
Больше уровней абстракции означает простые абстракции и, следовательно, меньше утечек на абстракцию. Таким образом, в математической формулировке (конечно, без каких-либо доказательств) сумма утечки абстракции может быть постоянной при изменении количества уровней абстракции.
m3th0dman
2
Однажды я наивно воспользовался советом старшего, чтобы добавить абстракцию там, где она не нужна. Он никогда не использовался сверх того, что я хотел сделать в первую очередь.
Сис Тиммерман
15

Да, конечно.

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

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

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

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

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

Возвращаясь к теме.

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

То, что что-то говорит «Micro», обычно указывает на то, что вы перерасходили макет своего объекта и, вероятно, используете Type как синоним того, что должно быть Data . Наличие меньшего количества вещей также означает меньшее количество зависимостей, необходимых для общения между ними.

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

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

Мэтт Д
источник
2
+1 за «Хороший портной, не оставляйте пучки ткани на каждом шве, только если у вас случится отрастить третью руку или забеременеть». К сожалению, мы часто проектируем программное обеспечение таким образом.
Кемода
Наряду с понятностью можно также найти абстракцию полезной при изгибе изогнутой линии в прямую. Это означает, что вы уменьшаете сложность и / или энтропию с помощью абстракции. Возможно, что-то вроде обработчика данных типа Curry, где жир, который вы бреете, все еще полезен в дальнейшем.
Коди
13

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

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

Джордан Лев
источник