Сколько абстракции это слишком много? - PullRequest
66 голосов
/ 19 апреля 2010

В объектно-ориентированной программе: Сколько абстракции - это слишком много? Сколько стоит просто?

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

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

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

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

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

Так, когда это слишком много? В какой момент пустые слои и лишние абстракции «могут нуждаться» становятся излишними? Сколько мало, слишком мало? Где сладкое место?

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

Ответы [ 8 ]

30 голосов
/ 18 марта 2013

Точка абстракции состоит в том, чтобы выделить общие свойства из определенных, как в математической операции:

ab + ac => a(b + c)

Теперь вы делаете то же самое с двумя операциями вместо трех. Этот факторинг упростил наше выражение.

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

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

Чем больше вещей имеют общее свойство. Чем полезнее может быть абстракция:

ab + ac + ad + ae + af

до:

a(b + c + d + e + f)

Это уменьшит 9 операций до 5.

По сути, каждая хорошая абстракция примерно вдвое уменьшает сложность системы.

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

10 => 5 * 2

Вы не можете определить слово «общий», если у вас есть только одна сущность.

Итак, чтобы ответить на ваш вопрос. У вас достаточно абстракций, если они делают вашу систему максимально простой.

(В моих примерах сложение связывает части системы, а умножение определяет абстрактно-конкретные отношения.)

25 голосов
/ 19 апреля 2010

Сколько мало, слишком мало?

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

Так, когда это слишком много?

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

Где сладкое место?

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

21 голосов
/ 19 апреля 2010

Так, когда это слишком много? В какой момент сделать пустые слои и лишнюю "мощь Нужно ли абстракции становиться излишними? Сколько мало, слишком мало? Где сладкое пятно?

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

Вот несколько ссылок, которые могут вдохновить вас на поиски ответов:

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

9 голосов
/ 19 апреля 2010

Теоретически, должно быть вопросом простой математики с использованием только трех (довольно простых) переменных:

  • S = экономия от использования
  • C = стоимость дополнительных абстракций
  • P = вероятность использования

Если S * P> C, то код хороший. Если S * P

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

По крайней мере, некоторые люди сделали вывод из этого. В TDD стандартная мантра гласит: «Тебе это не понадобится» (YAGNI). Проще говоря, все, что непосредственно не способствует коду, отвечающему его текущим требованиям, считается плохой вещью. По сути, они пришли к выводу, что вероятность использования настолько мала, что включение такого дополнительного кода никогда не оправдано.

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

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

6 голосов
/ 19 апреля 2010

Проще говоря, если код сложен для понимания, слишком много абстракции.

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

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

2 голосов
/ 19 апреля 2010

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

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

1 голос
/ 19 апреля 2010

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

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

0 голосов
/ 19 апреля 2010

См. Пункт (6a) из RFC 1925 и знайте, что это действительно так. Единственные проблемы, которые вы не можете исправить, добавляя уровни абстракции, это те, которые вызваны слишком большим количеством слоев абстракции. (В частности, каждая абстракция усложняет понимание всего этого.)

...