Вы, вероятно, узнали о лучших методах программирования, таких как принципы SOLID.

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

Что нам не нравится

Есть две вещи, которые нам не нравятся, потому что мы ленивы:

  1. Обновление вещей в нескольких местах — поэтому мы используем централизованные точки управления.
  2. Думая о слишком многих вещах одновременно, мы используем абстракции.

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

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

Но сначала давайте рассмотрим эти два понятия, чтобы мы знали, что они означают.

Централизованные точки управления

Какой фрагмент кода будет легче обновить, если процент наценки изменится?

Пример 1

Пример 2

Очевидно, пример 2, потому что вам просто нужно обновить markUp constant.

Обратите также внимание на то, насколько легче понять код, поскольку 1.25 заменено осмысленным именем (markUp)?

1.25 был абстрагирован от понятия "разметка".

Абстракции

Какой фрагмент кода легче читать и понимать, пример 1 или 2?

Пример 1

Пример 2

Очевидно пример 2, но почему?

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

Microsoft абстрагировала код, необходимый для вычисления среднего значения, в метод расширения LINQ.

Гораздо проще читать Average(), чем пытаться понять, что делают 6 строк кода.

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

Понятия

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

Инкапсуляция

Инкапсуляция — это хранение связанных вещей в едином блоке. В С# вы можете использовать класс или структуру.

Пример без инкапсуляции

Централизованные точки управления:

Если вы хотите добавить «возраст», в первом примере вам нужно:

  1. Добавьте возраст в качестве переменной.
  2. Обновите вызов до StoreUserDetailsInDb(), чтобы включить дополнительный аргумент.
  3. Обновите вызов до EmailUserDetailsToUser(), чтобы включить дополнительный аргумент.
  4. Обновите сигнатуру метода для StoreUserDetailsInDb(), чтобы включить дополнительный параметр.
  5. Обновите сигнатуру метода для EmailUserDetailsToUser(), чтобы включить дополнительный параметр.

Абстракции:

Здесь нам нужно подумать о 4 разных частях данных.

Пример с инкапсуляцией

В этом примере четыре отдельных фрагмента информации были инкапсулированы в один блок с именем Person.

Централизованные точки управления:

Добавить «возраст» во второй пример проще, нужно только:

  1. Добавьте Age в качестве свойства в класс Person.
  2. Инициализируйте свойство Age в инициализации объекта person.

Абстракции:

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

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

Наследование

Здесь объект «наследует» члены родительского класса.

Пример без наследования

Централизованные точки управления:

Если вы хотите добавить Address, поскольку это то, что есть у Teacher и Student, вам нужно добавить его к этим двум классам.

Абстракции:

Нам нужно подумать о двух понятиях, Teacher и Student.

Пример с наследованием

Централизованные точки управления:

Если вы хотите добавить Address, вам нужно добавить его только в класс Person.

Абстракции:

Нам нужно подумать только об одном концепте, Person.

Полиморфизм

Здесь объект может вести себя как другой объект.

Пример без полиморфизма

Централизованные точки управления:

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

Абстракции:

GetFullName() связано с Teacher и Student, это два отдельных понятия.

Пример с полиморфизмом

Здесь объекты student и teacher ведут себя так, как будто они являются объектами Person.

Централизованные точки управления:

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

Абстракции:

GetFullName() связан только с Person.

Скрытие данных

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

Пример без сокрытия данных

Централизованные точки управления:

Если вы хотите добавить еще один метод для представления другого процесса, когда водитель ведет машину, вам нужно будет добавить этот метод в класс Driver, а также добавить вызовы для объектов driver1 и driver2.

Абстракции:

Нам нужно думать о 3 процессах, когда водитель ведет машину.

Пример с сокрытием данных

Централизованные точки управления:

Три процесса теперь private, т.е. недоступен за пределами класса Driver. Вместо этого они инкапсулированы и поэтому спрятаны внутри метода Drive().

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

Абстракции:

Нам нужно думать только о понятии «Драйв», а не о трех разных понятиях.

Еще один пример сокрытия данных

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

Пример без сокрытия данных

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

Пример с сокрытием данных

Поскольку для отправки электронной почты требуется только строка электронной почты, это все, что нам нужно передать методу. Мы спрятали Employee и Manager из метода SendEmail().

Пример в базах данных

С реляционными базами данных, когда вы хотите иметь централизованные точки управления, вы превращаете таблицу в 3-ю нормальную форму (3NF).

Представьте, что у вас есть эта таблица:

Если «Research» и «Sydney» нужно обновить до «Res» и «Syd», это нужно будет сделать в двух строках.

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

Если вы привыкли к языкам программирования, вы можете думать об этом так, будто «d1» и «d2» в таблице «Сотрудники» — это переменные, которые ссылаются на «Исследования/Сидней» и «Маркетинг/Мельбурн» в таблице «Отдел».

Другие концепции

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

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