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

Как говорит Роберт С. Мартин, автор книги Чистый код: руководство по гибкому программному мастерству:

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

Среди наиболее интересных на данный момент — принцип единой ответственности, принцип открытости-закрытости и принцип инверсии зависимостей.

ТВЕРДЫЕ принципы

Единая ответственность, Открыто-закрыто, Замена Лискова, Разделение интерфейсов, Инверсия зависимостей.

Принцип единой ответственности (SRP)

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

Принцип единственной ответственности (SRP) гласит, что у класса или модуля должна быть одна и только однапричина для изменения. Этот принцип дает нам как определение ответственности, так и ориентир для размера класса. У классов должна быть одна обязанность — одна причина для изменения.

(Чистый код: руководство по гибкому программному обеспечению, глава 10, стр. 138)

Каждый класс и метод должны иметь и должны знать о своей определенной, ограниченной роли. Возложение ответственности на класс Oystercard за маршрут, в котором он находится (например, места, в которых он начинается и заканчивается), стоимость проезда, иистория путешествия — это не просто плохое программирование (или запах кода) это ненужное усложнение и надвигающаяся головная боль для нас и следующего человека, которому придется иметь дело с этой кодовой базой. Вместо этого мы придерживаемся более разрозненного подхода:

  • Класс Oystercard, отвечающий за поддержание баланса при касании пользователем станции и выходе из нее;
  • Класс Station, который отслеживает названия и зоны станций;
  • Класс Journey, который заботится о станциях входа и выхода в путешествии;
  • Класс Journey Log, роль которого заключается в записи истории поездок;
  • Класс Fare, отвечающий за расчет стоимости проезда в зависимости от количества пройденных зон.

Принцип «открыто-закрыто» и инкапсуляция

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

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

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

Инверсия зависимостей и внедрение зависимостей

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

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

(Чистый код: руководство по Agile Software Craftsmanship, глава 11, стр. 157)

Чтобы поддержать принцип инверсии зависимостей, внедрение зависимостей — это метод, который переносит обязанности с создания экземпляров зависимостей на специальные методы, тем самым инвертируя управление.

Преимущества гибкого подхода

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

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