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

Излишне упрощенное определение абстракции, вероятно, скажет, что

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

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

Как работает абстракция

Использование абстракции - это двухэтапный процесс: -

  1. Будьте расплывчаты. Во время кодирования абстракция требует, чтобы вы внесли в программу некоторую неопределенность. Этого можно добиться, используя такие конструкции, как базовые классы, параметризованные методы, интерфейсы, дженерики и т. Д. Они позволяют вам писать код, который выполняет минимальную общую функциональность, разделяемую намеченными целями вашей абстракции.
  2. Укрепите свой код: во время выполнения закрепите неопределенность или свои абстракции, передав параметры или конкретные реализации, которые говорят вам, как программа на самом деле работает.

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

Проблема с абстракцией

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

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

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

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

Лучший способ?

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

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

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

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