Как стать автором
Обновить
0
Skillbox
Образовательная платформа Skillbox

10 принципов объектно-ориентированного программирования, о которых должен знать каждый разработчик

Время на прочтение5 мин
Количество просмотров53K
Автор оригинала: Javin Paul


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

Напоминаем: для всех читателей «»Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».

Skillbox рекомендует: Образовательный онлайн-курс «Java-разработчик».

DRY (Don’t Repeat Yourself)


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

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

Это нужно для того, чтобы упростить код и сделать его поддержку проще, что является основной задачей ООП. Злоупотреблять объединением тоже не стоит, поскольку один и тот же код не пройдет проверку как с OrderId, так и с SSN.

Инкапсуляция изменений


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

Если вы пишете на Java, то по умолчанию присваивайте private методам и переменным.

Принцип открытости/закрытости


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

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

Вот пример кода, который нарушает этот принцип.



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

Кстати, открытость-закрытость — один из принципов SOLID.

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


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



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

Принцип инверсии зависимостей (DIP)




Выше приведен пример кода, где AppManager зависит от EventLogWriter, который, в свою очередь, тесно связан с AppManager. Если нужен иной способ показать уведомление, будь это пуш, SMS или email, нужно изменить класс AppManager.

Проблема может быть решена при помощи DIP. Так, вместо AppManager мы запрашиваем EventLogWriter, который будет введен при помощи фреймворка.

DIP дает возможность без проблем заменять отдельные модули другими, изменяя модуль зависимости. Это дает возможность изменять один модуль, не влияя на остальные.

Композиция вместо наследования


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

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

Даже “Effective Java” Джошуа Блох (Joshua Bloch) советует отдавать предпочтение композиции, а не наследованию.

Принцип подстановки Барбары Лисков (LSP)


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

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

Вот участок кода, который противоречит LSP.



Метод area(Rectangle r) просчитывает площадь Rectangle. Программа упадет после выполнения Square, поскольку Square здесь не является Rectangle. Согласно принципу LSP, функции, которые используют ссылки на базовые классы, должны иметь возможность использовать и объекты производных классов без дополнительных инструкций.

Этот принцип, который является специфичным определением подтипа, был предложен Барбарой Лисков в 1987 году на конференции в основном докладе под названием «Абстракция данных и иерархия» — отсюда и его название.

Принцип разделения интерфейса (ISP)


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

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

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

Достоинством принципа ISP в Java является то, что сначала нужно реализовать все методы, и только потом они могут быть использованы классами. Поэтому принцип дает возможность снизить количество методов.



Программирование для интерфейса, а не реализации


Здесь все понятно из названия. Применение этого принципа ведет к созданию гибкого кода, который сможет работать с любой новой реализацией интерфейса.

Следует использовать тип интерфейса для переменных, возвращаемых типов или же типа аргумента метода. Пример — использование SuperClass, а не SubClass.

То есть:

List numbers= getNumbers();

А не:

ArrayList numbers = getNumbers();

Вот практическая реализация того, о чем говорится выше.



Принцип делегирования


Распространенный пример — методы equals() и hashCode() в Java. Когда требуется сравнить два объекта, то это действие делегируется соответствующему классу вместо клиентского.

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



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

Skillbox рекомендует:

Теги:
Хабы:
Всего голосов 57: ↑36 и ↓21+15
Комментарии26

Публикации

Информация

Сайт
skillbox.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия

Истории