Основные концепции объектно ориентированного программирования
Основные понятия в объектно-ориентированном программировании ИЛИ
моя шпаргалка по ООП
С целью освежения базовых знаний по ООП, я решила перечитать потрясающую книгу «Объектно-ориентированный анализ и проектирование с примерами приложений», Гради Буч
Я обожаю эту книгу, потому что она написана простым языком со знанием дела и такой любовью к программированию, что вы ее с упоением прочтете в метро. Вы будете с нетерпением ждать того момента, когда вы сможете усесться с книжечкой в поезде и взахлеб читать и пропускать свои станции.
А теперь для ленивых и для себя любимой я составила краткий конспект-шпаргалку по этой книги.
ШПАРГАЛКА ПО ООП
Объектно-ориентированное программирование или ООП — это способ создания программных компонентов, базирующихся на объектах.
Основные принципы ООП
- абстрагирование
- инкапсуляция
- модульность
- иерархия
Абстрагирование — это процесс выделения наиболее существенных характеристик некоторого объекта, отличающих его от всех других видов объектов, важных с точки зрения дальнейшего рассмотрения и анализа, и игнорирование менее важных или незначительных деталей.
Объекты и классы — основные абстракции предметной области.
Инкапсуляция — это процесс отделения друг от друга элементов объекта, определяющих его устройство и поведение; инкапсуляция служит для того, чтобы изолировать контрактные обязательства абстракции от их реализации.
Модульность — это свойство системы, связанное с возможностью ее декомпозиции на ряд внутренне сильно сцепленных, но слабо связанных между собой подсистем (частей).
Модульность снижает сложность системы, позволяя выполнять независимую разработку ее отдельных частей.
Иерархия — это упорядочение абстракций, расположение их по уровням.
Типизация — способ защититься от использования объектов одного класса вместо другого, или, по крайней мере, управлять таким использованием.
Тип — точная характеристика некоторой совокупности однородных объектов, включающая структуру и поведение.
При строгой типизации (например, в языке Оберон) запрещается использование объектов неверного типа, требуется явное преобразование к нужному типу. При менее строгой типизации такого рода запреты ослаблены. В частности, допускается полиморфизм — многозначность имен. Одно из проявлений полиморфизма, использование объект подтипа (наследника) в роли объекта супертипа (предка).
Параллелизм — это свойство, отличающее активные объекты от пассивных.
Параллелизм — наличие в системе нескольких потоков управления одновременно. Объект может быть активен, т. е. может порождать отдельный поток управления. Различные объекты могут быть активны одновременно.
Сохраняемость (устойчивость) — способность объекта существовать во времени, переживая породивший его процесс, и (или) в пространстве, перемещаясь из своего первоначального адресного пространства.
Устойчивость — способность объекта сохранять свое существование во времени и/или пространстве (адресном, в частности при перемещении между узлами вычислительной системы). В частности, устойчивость объектов может быть обеспечена за счет их хранения в базе данных.
Основные понятия объектно-ориентированного подхода или элементы объектной модели
“ Объект в ООП — это сущность, способная сохранять свое состояние (информацию) и обеспечивающая набор операций (поведение) для проверки и изменения этого состояния. ”
Объект — осязаемая сущность (tangible entity) — предмет или явление (процесс), имеющие четко выраженные границы, индивидуальность и поведение.
Любой объект обладает состоянием, поведением и индивидуальностью.
Состояние объекта определяется значениями его свойств (атрибутов) и связями с другими объектами, оно может меняться со временем.
Поведение определяет действия объекта и его реакцию на запросы от других объектов. Поведение представляется с помощью набора сообщений, воспринимаемых объектом (операций, которые может выполнять объект).
Индивидуальность — это свойства объекта, отличающие его от всех других объектов.
Структура и поведение схожих объектов определяют общий для них класс.
Объект в JavaScript создаётся с помощью функции Object.create. Эта функция из родителя и опционального набора свойств создаёт новую сущность. Пока что мы не будем беспокоиться о параметрах.
Прототип — это объект-образец, по образу и подобию которого создаются другие объекты. Объекты-копии могут сохранять связь с родительским объектом, автоматически наследуя изменения в прототипе; эта особенность определяется в рамках конкретного языка.
Класс — это множество объектов, связанных общностью свойств, поведения, связей и семантики. Любой объект является экземпляром класса. Определение классов и объектов — одна из самых сложных задач объектно-ориентированного проектирования.
Класс (class) — это группа данных и методов(функций) для работы с этими данными. Это шаблон. Объекты с одинаковыми свойствами, то есть с одинаковыми наборами переменных состояния и методов, образуют класс.
Конструктор класса — специальный блок инструкций, вызываемый при создании объекта.
var s = new String();
Деструктор — специальный метод класса, служащий для деинициализации объекта (например освобождения памяти).
Атрибут — поименованное свойство класса, определяющее диапазон допустимых значений, которые могут принимать экземпляры данного свойства. Атрибуты могут быть скрыты от других классов, это определяет видимость атрибута: рublic (общий, открытый); private (закрытый, секретный); protected (защищенный).
Требуемое поведение системы реализуется через взаимодействие объектов. Взаимодействие объектов обеспечивается механизмом пересылки сообщений. Определенное воздействие одного объекта на другой с целью вызвать соответствующую реакцию называется операцией или посылкой сообщения. Сообщение может быть послано только вдоль соединения между объектами. В терминах программирования соединение между объектами существует, если один объект имеет ссылку на другой.
Дескриптор — это атрибут объекта со связанным поведением (англ. binding behavior), т.е. такой, чьё поведение при доступе переопределяется методами протокола дескриптора.
Операция — это услуга, которую можно запросить у любого объекта данного класса. Операции реализуют поведение экземпляров класса. Описание операции включает четыре части: имя; список параметров; тип возвращаемого значения; видимость.
Реализация операции называется методом.
Метод — это функция или процедура, принадлежащая какому-то классу или объекту.
Различают простые методы и статические методы (методы класса):
- простые методы имеют доступ к данным объекта (конкретного экземпляра данного класса),
- статические методы не имеют доступа к данным объекта и для их использования не нужно создавать экземпляры (данного класса).
Методы предоставляют интерфейс, при помощи которого осуществляется доступ к данным объекта некоторого класса, тем самым, обеспечивая инкапсуляцию данных.
В зависимости от того, какой уровень доступа предоставляет тот или иной метод, выделяют:
- открытый (public) интерфейс — общий интерфейс для всех пользователей данного класса;
- защищённый (protected) интерфейс — внутренний интерфейс для всех наследников данного класса;
- закрытый (private) интерфейс — интерфейс, доступный только изнутри данного класса.
Такое разделение интерфейсов позволяет сохранять неизменным открытый интерфейс, но изменять внутреннюю реализацию.
Полиморфизм — способность скрывать множество различных реализаций под единственным общим именем или интерфейсом.
Понятие полиморфизма может быть интерпретировано, как способность объекта принадлежать более чем одному типу.
Интерфейс — это совокупность операций, определяющих набор услуг класса или компонента. Интерфейс не определяет внутреннюю структуру, все его операции открыты.
Компонент — это относительно независимая и замещаемая часть системы, выполняющая четко определенную функцию в контексте заданной архитектуры.
Компонент представляет собой физическую реализацию проектной абстракции и может быть: компонентом исходного кода (cpp-шник); компонентом времени выполнения (dll, ActiveX и т. п.); исполняемый компонентом (exe-шник). Компонент обеспечивает физическую реализацию набора интерфейсов. Компонентная разработка (component-based development) представляет собой создание программных систем, состоящих из компонентов (не путать с объектно-ориентированным программированием (ООП).
Компонентная разработка — технология, позволяющая объединять объектные компоненты в систему.
Пакет — это общий механизм для организации элементов в группы. Это элемент модели, который может включать другие элементы. Каждый элемент модели может входить только в один пакет.
-средством организации модели в процессе разработки, повышения ее управляемости и читаемости;
-единицей управления конфигурацией.
Подсистема — это комбинация пакета (может включать другие элементы модели) и класса (обладает поведением). Подсистема реализует один или более интерфейсов, определяющих ее поведение. Она используется для представления компонента в процессе проектирования.
Основные концепции объектно-ориентированного программирования;
Объектно-ориентированные языки программирования
Реализация программного обеспечения связана с использованием одного из языков программирования. Наиболее удобными для реализации программных систем, разработанных в рамках объектно-ориентированного подхода, являются объектно-ориентированные языки программирования, хотя возможна реализация и на обычных (не объектно-ориентированных) языках (например, на языке C и на языке Fortran).
Объектно-ориентированные языки программирования пользуются в последнее время большой популярностью среди программистов, так как они позволяют использовать преимущества объектно-ориентированного подхода не только на этапах проектирования и конструирования программных систем, но и на этапах их реализации, тестирования и сопровождения.
Первый объектно-ориентированный язык программирования Simula 67 был разработан в конце 60-х годов в Норвегии. Авторы этого языка очень точно угадали перспективы развития программирования: их язык намного опередил свое время. Однако современники (программисты 60-х годов) оказались не готовы воспринять ценности языка Simula 67, и он не выдержал конкуренции с другими языками программирования (прежде всего, с языком Fortran). Прохладному отношению к языку Simula 67 способствовало и то обстоятельство, что он был реализован как интерпретируемый (а не компилируемый) язык, что было совершенно неприемлемым в 60-е годы, так как интерпретация связана со снижением эффективности (скорости выполнения) программ.
Но достоинства языка Simula 67 были замечены некоторыми программистами, и в 70-е годы было разработано большое число экспериментальных объектно-ориентированных языков программирования: например, языки CLU, Alphard, Concurrent Pascal и др. Эти языки так и остались экспериментальными, но в результате их исследования были разработаны современные объектно-ориентированные языки программирования: C++, Smalltalk, Eiffel и др.
Наиболее распространенным объектно-ориентированным языком программирования безусловно является C++. Разработка новых объектно-ориентированных языков программирования продолжается. С 1995 года широко распространен новый объектно-ориентированный язык программирования Java, ориентированный на сети компьютеров и, прежде всего, на Internet.
Основными понятиями объектно-ориентированного программирования (ООП) являются объект и класс. Понятие «объект» может быть определено следующим образом.
Объект — это нечто, обладающее состоянием, поведением и идентичностью.
Некоторые примеры объектов были приведены выше. В качестве еще одного примера может быть приведен интерфейсный объект, например кнопка. Кнопка однозначно выделяется из всего прочего интерфейса — т.е обладает идентичностью. Ее состояние — надпись на кнопке, цвет, размер, форма и т.п. Ее поведение — способность быть нажатой — отобразить этот процесс на экране и предать сообщение об этом событии тому объекту, который должен на него реагировать.
Идентичность — это такое свойство объекта, которое отличает его от всех других объектов.
Состояние объекта характеризуется перечнем (обычно статическим) всех свойств данного объекта и текущими (обычно динамическими) значениями каждого из этих свойств.
Поведение — это то, как объект действует и реагирует; поведение выражается в терминах изменения состояния объекта и передачи сообщений. Структура и поведение схожих объектов определяет для них общий класс. Например класс графических интерфейсных элементов — кнопок, переключателей, окон ввода данных, и т.п. Другой пример — если бы мы занялись моделированием экосистемы, то могли бы выделить классы растений, насекомых, рыб, млекопитающих и т.д. Может быть дано следующее определение понятия «класс». Класс — это некое множество объектов, имеющих общую структуру и общее поведение.
Термины «экземпляр класса» и «объект» взаимозаменяемы. Классы вступают между собой в некоторое отношение, называемое иерархией наследования. Наследование — это такое отношение между классами, когда один класс повторяет структуру и поведение другого класса (одиночное наследование) или других классов (множественное наследование).
Для примера рассмотрим программу моделирующую работу цеха. На верхнем уровне иерархии наследования могут быть выделены такие классы, как работник, станок, помещение. Различные категории работников в свою очередь образуют классы, которые наследуют структуру и поведение класса работник (например все работники должны приходить на работу в одно время), но и добавляют что-то свое (выполняют разные категории работ). То же самое относится к станкам и помещениям — станки разного типа и помещения разного назначения.
Предлагается следующее определение термина «объектно-ориентированное программирование»:
Объектно-ориентированное программирование— это методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является объектом определенного класса, а классы образуют иерархию наследования.
В данном определении можно выделить три части:
1) ООП использует в качестве базовых элементов объекты, а не алгоритмы,
2) каждый объект является экземпляром какого-либо определенного класса
3) классы организованы иерархически.
Программа будет объектно-ориентированной только при соблюдении всех трех указанных условий.
Для разработки объектно-ориентированных программ используются объектно-ориентированные языки программирования. Объектно-ориентированный язык программирования может быть определен как язык, имеющий средства хорошей поддержки объектно-ориентированного стиля программирования, т.е. при разработке программ на этом языке удобно пользоваться таким стилем программирования. Если написание программ в стиле ООП требует специальных усилий или оно невозможно совсем, то этот язык не является объектно-ориентированным.
Язык программирования является объектно-ориентированным тогда и только тогда, когда выполняются следующие условия:
— поддерживаются объекты, т.е. абстракции данных, имеющие интерфейс в виде именованных операций и собственные данные, с ограничением доступа к ним;
— объекты относятся к соответствующим типам (классам);
— типы (классы) могут наследовать атрибуты супертипов (суперклассов).
Согласно этому определению такие языки как С++ и Object Pascal являются объектно-ориентированными.
Дальнейшее изложение ООП ведется на примере языка Object Pascal, реализованном в Borland Delphi. В некоторых случаях для сравнения рассматривается реализация объектно-ориентированного подхода в языке С++.
Ключевые программные приемы, применяемые в системах управления. Выбрасывание исключений и их обработка, вложенные исключения, Создание пользовательского класса исключений. Макросы отладки. Основные классы MFC. CObject, коллекции, CString, CWnd, механизм «документ — отображение».
Основы объектно-ориентированного программирования
Применение ООП к разработке программных проектов
Несмотря на то, что язык Java является объектно-ориентированным, до сих пор при разработке программ мы по существу пользовались парадигмой директивного программирования — целью было создание кода, воздействующего должным образом на данные. Этот подход хорош при решении небольших задач, но порождает множество трудноразрешимых проблем при попытке создания больших программных систем.
Одной из альтернатив директивному программированию является объектно-ориентированное программирование, которое действительно помогает справиться с нелинейно растущей сложностью программ при увеличении их объема. Не следует, однако, делать вывод , что использование парадигмы объектно-ориентированного программирования гарантирует успешное решение всех проблем.
Для того чтобы стать профессионалом в программировании, необходимы талант, способность к творчеству, интеллект , знания, логика, умение строить и использовать абстракции и, самое главное, опыт .
В этом параграфе мы продолжим знакомство с базисными концепциями объектно-ориентированного программирования, начатое еще в первой главе книги. Сначала будут обсуждены общие для различных языков программирования понятия ООП , а затем — их реализация в языке Java .
Следует знать, что курс объектно-ориентированного программирования читается студентам-старшекурсникам в течение целого семестра, и поэтому материал, изложенный ниже, представляет собой лишь самое начальное введение в мир ООП . Значительно более полное изложение многих вопросов, связанных с объектно-ориентированными дизайном, проектированием и программированием, содержится в книге [2], а в третьей главе книги [13] можно найти очень ясное описание всех объектно-ориентированных аспектов языка Java .
Основные концепции ООП
Объектно-ориентированное программирование или ООП (object-oriented programming) — методология программирования , основанная на представлении программы в виде совокупности объектов , каждый из которых является реализацией определенного типа , использующая механизм пересылки сообщений и классы , организованные в иерархию наследования .
Центральный элемент ООП — абстракция . Данные с помощью абстракции преобразуются в объекты, а последовательность обработки этих данных превращается в набор сообщений, передаваемых между этими объектами. Каждый из объектов имеет свое собственное уникальное поведение. С объектами можно обращаться как с конкретными сущностями, которые реагируют на сообщения, приказывающие им выполнить какие-то действия.
ООП характеризуется следующими принципами ( по Алану Кею):
- все является объектом ;
- вычисления осуществляются путем взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие; объекты взаимодействуют, посылая и получая сообщения ; сообщение — это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия;
- каждый объект имеет независимую память, которая состоит из других объектов ;
- каждый объект является представителем класса , который выражает общие свойства объектов данного типа ;
- в классе задается функциональность (поведение объекта); тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия;
- классы организованы в единую древовидную структуру с общим корнем, называемую иерархией наследования ; память и поведение, связанное с экземплярами определенного класса, автоматически доступны любому классу, расположенному ниже в иерархическом дереве.
Определение 10.1. Абстрагирование (abstraction) — метод решения задачи, при котором объекты разного рода объединяются общим понятием (концепцией), а затем сгруппированные сущности рассматриваются как элементы единой категории.
Абстрагирование позволяет отделить логический смысл фрагмента программы от проблемы его реализации, разделив внешнее описание ( интерфейс ) объекта и его внутреннюю организацию (реализацию).
Определение 10.2. Инкапсуляция (encapsulation) — техника, при которой несущественная с точки зрения интерфейса объекта информация прячется внутри него.
Определение 10.3. Наследование (inheritance) — свойство объектов, посредством которого экземпляры класса получают доступ к данным и методам классов-предков без их повторного определения.
Наследование позволяет различным типам данных совместно использовать один и тот же код, приводя к уменьшению его размера и повышению функциональности.
Определение 10.4. Полиморфизм (polymorphism) — свойство, позволяющее использовать один и тот же интерфейс для различных действий; полиморфной переменной, например, может соответствовать несколько различных методов.
Полиморфизм перекраивает общий код, реализующий некоторый интерфейс , так, чтобы удовлетворить конкретным особенностям отдельных типов данных.
Определение 10.5. Класс (class) — множество объектов, связанных общностью структуры и поведения; абстрактное описание данных и поведения (методов) для совокупности похожих объектов, представители которой называются экземплярами класса.
Определение 10.6. Объект (object) — конкретная реализация класса, обладающая характеристиками состояния, поведения и индивидуальности, синоним экземпляра.
Как это уже отмечалось в самом начале курса, Java — лишь один из объектно-ориентированных языков. Другим активно используемым профессиональными программистами языком ООП , с который мы познакомимся в следующем семестре, является C++. В дальнейшем нам предстоит знакомство с такими представителями этого семейства, как Smalltalk, Delphi Pascal и CLOS .
Следует иметь в виду, что в разных объектно-ориентированных языках для обозначения одних и тех же концепций ООП используются слегка отличающиеся друг от друга термины (см. словарик ООП в конце лекции).
лабы по информатике, егэ
лабораторные работы и задачи по программированию и информатике, егэ по информатике
Объектно-ориентированное программирование (как расшифровывается ООП) – это, прежде всего, парадигма программирования.
Парадигма программирования определяет то, как программист видит выполнение программы.
Так, для парадигмы ООП характерно, что программист рассматривает программу в виде набора взаимодействующих объектов, в то время как, например, в функциональном программировании программа представляется в виде последовательности вычисления функций. Процедурное программирование или, как его еще правильно называют, классическое операциональное, подразумевает написание алгоритма для решения задачи; при этом ожидаемые свойства конечного результата не описываются и не указываются. Структурное программирование в основном придерживается тех же принципов, что и процедурное, лишь немного дополняя их полезными приемами.
Парадигмы непроцедурного программирования, к которым можно отнести объектно-ориентированную парадигму, имеют совершенно другие идеи.
Определение Гради Буча гласит: “Объектно-ориентированное программирование – это методология программирования, которая основана на представлении программы в виде совокупности объектов, каждый из которых является реализацией определенного класса (типа особого вида), а классы образуют иерархию на принципах наследуемости”.
Структурное и объектно-ориентированное программирование строятся на таком научном методе как декомпозиция — метод, который использует структуру задачи и позволяет разбить решение общей большой задачи на решение последовательности меньших задач. Декомпозиция ООП происходит не по алгоритмам, а по объектам, использующимся при решении задачи. Данная декомпозиция уменьшает размер программных систем благодаря повторному использованию общих механизмов. Известно, что системы визуального программирования или системы, построенные на принципах объектно-ориентированного программирования, являются более гибкими и легче эволюционируют со временем.
История развития ООП берет свое начало в конце 60-х годов. Первым объектно-ориентированным языком был язык программирования Simula, созданный в компьютерном центре в Норвегии. Язык предназначался для моделирования ситуаций реального мира. Особенностью Simula было то, что программа, написанная на языке, была организована по объектам программирования. Объекты имели инструкции, называемые методами, и данные, которые назывались переменными; методы и данные определяли поведение объекта. В процессе моделирования объект вел себя согласно своему стандартному поведению и, в случае необходимости, изменял данные для отражения влияния назначенного ему действия.
Сегодня существует достаточное количество объектно-ориентированных языков программирования, наиболее популярными из которых в настоящее время являются C++, Delphi, Java, Visual Basic, Flash. Но, кроме того, многие языки, которые принято причислять к процедурной парадигме, тоже обладают свойствами ООП, имея возможность работать с объектами. Так, объектно-ориентированное программирование в C — это большой раздел программирования на данном языке, то же самое касается ООП в python и многих других структурных языках.
Говоря об ООП, часто всплывает еще одно определение — визуальное программирование. Оно дополнительно предоставляет широкие возможности использования прототипов объектов, которые определяются как классы объектов.
События. Во многих средах визуального программирования реализована характеристика (помимо инкапсуляции, полиморфизма и наследования) объекта – событие. Событиями в объектно-ориентированном программировании называется возможность обработки так называемых сообщений (или событий), получаемых от операционной системы Windows или самой программы. Данный принцип характерен для всех компонентов среды, которые обрабатывают различные события, возникающие в процессе выполнения программы. По сути, событие — это некоторое действие, которое активизирует стандартную реакцию объекта. Событием может рассматриваться, например, щелчок по кнопке мыши, наведение курсора мыши на пункт меню, открытие вкладки и т.п. Очередность выполнения тех или иных действий определяется как раз таки событиями, возникающими в системе, и реакцией на них объектов.
Классы и объекты в ООП — различные понятия. Понятие класса в ООП – это тип данных (такой же как, например, Real или String), а объект – конкретный экземпляр класса (его копия), хранящийся в памяти компьютера как переменная соответствующего типа.
Класс является структурным типом данных. Класс включает описание полей данных, а также процедур и функций, которые работают с этими полями данных. Метод ООП – это и есть такие процедуры и функции применительно к классам.
Классы имеют поля (как тип данных запись — record), свойства, которые похожи на поля, но имеют дополнительные описатели, определяющие механизмы записи и считывания данных и методы — подпрограммы, которые направленны на изменение полей и свойств класса.
Основные принципы ООП
Принципы объектно-ориентированного программирования помимо обработки событий – это инкапсуляция, наследование, подклассы и полиморфизм. Они особенно полезны и необходимы при разработке тиражируемых и простых в сопровождении приложений.
Объект объединяет в себе методы и свойства, которые не могут существовать отдельно от него. Поэтому если объект удаляется, то удаляются его свойства и связанные с ним методы. При копировании происходит то же самое: объект копируется как единое целое. Инкапсуляция ООП — это и есть описанная характеристика.
Принцип наследования ООП и подклассы
Абсолютно все объекты создаются на основе классов, при это они наследуют свойства и методы этих классов. В свою очередь классы могут создаваться на основе других классов (родителей), тогда такие классы называют подклассами (потомки). Подклассы наследуют все свойства и методы родительского класса. Кроме того для подкласса или класса-потомка можно определить новые, свои собственные, свойства и методы, а также изменять методы класса-родителя. Изменение свойств и методов родительского класса отслеживается в подклассах, созданных на основе этого класса, а также в объектах, созданных на основе подклассов. В этом и заключается наследование ООП.
Полиморфизм ООП
В объектно-ориентированном программировании полиморфизм характеризуется как взаимозаменяемость объектов с одинаковым интерфейсом. Это можно объяснить так: класс-потомок наследует экземпляры методов класса-родителя, но выполнение этих методов может происходить другим образом, соответствующим специфике класса-потомка, то есть модифицированным.
То есть, если в процедурном программировании имя процедуры или функции однозначно определяет выполняемый код, относящейся к данной процедуре или функции, то в объектно-ориентированном программировании можно использовать одни и те же имена методов для выполнения разных действий. То есть результат выполнения одного и того же метода зависит от типа объекта, к которому применяется данный метод.
На сайте представлена частичная теория объектно-ориентированного программирования для начинающих и ООП примеры решения задач. ООП уроки сайта представляют собой подробные алгоритмы выполнения поставленной задачи. На основе выполнения данных лабораторных работ учащийся сможет в дальнейшем самостоятельно решать другие аналогичные задачи.
Желаем Вам легкого и интересного изучения объектно-ориентированного программирования!
10 принципов ООП, о которых стоит знать каждому программисту
- Переводы, 21 мая 2019 в 10:17
- Klara Oswald
Многим опытным разработчикам, вероятно, знакома методология объектно-ориентированного программирования (ООП). Кроме известных её принципов (абстракция, инкапсуляция, полиморфизм, наследование и т. д.) существуют и другие — менее известные, но не менее важные и полезные для реализации. Некоторые из них собраны в специальный блок и известны по акрониму SOLID. Эта статья расскажет об этих и других существующих принципах объектно-ориентированной разработки и о том, какие преимущества они предлагают.
Принцип единственной ответственности (SRP)
Соответствует букве S акронима SOLID. Согласно этому принципу, не должно быть более одной причины для изменения класса, или класс должен всегда обрабатывать одну функциональность.
Основное преимущество состоит в том, что такой подход уменьшает связь между отдельным компонентом программного обеспечения и кодом. Если вы добавляете более одной функциональности в один класс, это вводит связь между двумя функциями, и даже если вы меняете только одну из них, есть шанс сломать другую, связанную с ней. Что в свою очередь требует больше раундов тестирования для избежания каких-либо неожиданностей в продакшене.
Принцип открытости/закрытости (OCP)
Соответствует букве O акронима SOLID. Принцип можно выразить так: «Классы, методы или функции должны быть открыты для расширения (добавления новой функциональности) и закрыты для модификации». Такой подход запрещает кому-либо изменять уже опробованный и протестированный код, а значит, он не ломается. В этом и состоит основное преимущество такого подхода.
Ниже приведён пример кода на Java, который нарушает этот принцип:
А вот пример после рефакторинга. Теперь соблюдается принцип открытости/закрытости: при добавлении новой реализации Shape не нужно менять код GraphicEditor .
Принцип подстановки Барбары Лисков (LSP)
Соответствует букве L акронима SOLID. Согласно этому принципу подтипы должны быть заменяемыми для супертипа. Другими словами, методы или функции, работающие с суперклассом, должны иметь возможность без проблем работать также и с его подклассами.
Ивент переехал в онлайн, есть новые даты ( 14 – 15 июля ) , Москва и онлайн, 10 750–138 000 ₽
LSP тесно связан с принципом единственной ответственности и принципом разделения интерфейса.
Если класс реализует больше функциональности, чем подкласс, то последний может не поддерживать некоторые функции и тем самым нарушает данный принцип.
Ниже приведён пример такого кода на Java:
Функция resize() провоцирует неявную ошибку при работе с экземпляром класса Square , потому что позволяет устанавливать отличные друг от друга значения ширины и высоты. Согласно принципу LSP, функции, использующие ссылки на базовые классы, должны иметь возможность использовать объекты производных классов, не зная об этом. Поэтому для корректной работы функция resize() должна проверять, является ли передаваемый объект экземпляром класса Square, и в этом случае не позволять установить разные значения ширины и высоты. Отсюда идёт нарушение принципа.
Принцип разделения интерфейса (ISP)
Соответствует букве I акронима SOLID. Этот принцип подразумевает, что интерфейс, который не используется, не должен быть реализован.
В основном это происходит, когда один интерфейс содержит несколько функциональностей, и клиенту нужна только одна из них, а другие — нет.
Написание интерфейса — сложная задача. Когда он готов, вы не сможете изменить его, не нарушив всю реализацию.
Ещё одно преимущество этого принципа в Java заключается в том, что интерфейс имеет недостаток. Необходимо сначала реализовать все методы, прежде чем какой-либо класс сможет их использовать. Поэтому наличие единственной функциональности означает меньшее количество методов для реализации.
Принцип инверсии зависимостей (DIP)
Соответствует букве D акронима SOLID. Прелесть этого принципа проектирования в том, что любой класс легко тестируется с помощью фиктивного объекта и проще в обслуживании, потому что код создания объекта централизован, а клиентский код не перегружен им.
Ниже приведён пример кода Java, который нарушает принцип инверсии зависимости:
Пример демонстрирует, что AppManager зависит от EventLogWriter . Если вам нужно использовать другой способ уведомления клиента (например push-уведомления, SMS или электронную почту), необходимо изменить класс AppManager .
Эту проблему можно решить с помощью принципа инверсии зависимостей. Вместо того, чтобы AppManager запрашивал EventLogWriter , последний следует внедрить в AppManager явно. Плюсом реализации общего интерфейса позволить внедрять любую реализацию для других способов уведомления.
Теперь перейдём к принципам, которые не входят в пятёрку SOLID, но не менее важны.
DRY (Don’t Repeat Yourself)
Переводится как «не повторяйся» и буквально означает, что нужно уходить от дублирующего кода и по возможности использовать абстракцию для общих вещей.
Если есть одинаковый блок кода в более чем двух местах, вынесите его в отдельный метод. Если вы используете жёстко запрограммированное значение более одного раза, сделайте его общедоступной константой. Преимущество этого принципа заключается в упрощении поддержки вашего кода.
Но важно не злоупотреблять этим принципом. Например, один и тот же код не подойдёт для проверки OrderId и SSN. Их форматы могут не совпадать, и на выходе функция выдаст некорректный результат. В качестве решения можно предусмотреть в методе проверку форматов для подобных наборов чисел.
Инкапсуляция изменяющегося кода
Сервисы стремительно развиваются. Продакшн подразумевает постоянные изменения кода и его поддержку. Отсюда следует второй принцип ООП — инкапсуляция кода, который с большой вероятностью будет изменён в будущем.
Преимущество этого принципа ООП заключается в том, что инкапсулированный код легко тестировать и поддерживать.
Воспользуйтесь алгоритмом, по которому переменные и методы по умолчанию имеют спецификатор private. Затем шаг за шагом увеличиваете доступ при необходимости (с private на protected, с protected на public).
Одним из вариантов инкапсуляции является Фабричный метод. Он инкапсулирует код создания объекта и обеспечивает гибкость для последующего создания новых объектов без влияния на существующий код.
Композиция вместо наследования
Существует два основных способа повторного использования кода: наследование и композиция. Оба они имеют свои преимущества и недостатки, но, как правило, предпочтение рекомендуется отдавать последнему, если это возможно. Обусловлено это тем, что композиция гибче наследования.
Композиция позволяет изменять поведение класса прямо во время выполнения через установку его свойств. Реализуя интерфейсы, вы, таким образом, используете полиморфизм, который обеспечивает более гибкую реализацию.
«Effective Java» Джошуа Блоха также советует отдавать предпочтение композиции вместо наследования. Если вы всё ещё не уверены, вы также можете посмотреть здесь, чтобы узнать, почему композиция лучше, чем наследование для повторного использования кода и его функциональности.
Программирование для интерфейса
Этот принцип подразумевает, что следует по возможности программировать для интерфейса, а не для его реализации. Это даст вам гибкий код, который может работать с любой новой реализацией интерфейса.
Другими словами, нужно использовать тип интерфейса для переменных, возвращаемых типов или типа аргумента метода. Например, использовать для хранения объекта суперкласс, а не подкласс.
Это также рекомендовано во многих книгах по Java, в том числе в Effective Java и Head First design pattern.
Ниже приведён пример для интерфейса в Java:
Принцип делегирования
Не делайте всё самостоятельно, делегируйте это в соответствующий класс. Классическим примером этого принципа являются методы equals() и hashCode() в Java. Если нужно сравнить два объекта, это действие поручается соответствующему классу вместо клиентского.
Основным преимуществом этого принципа является отсутствие дублирования кода и довольно простое изменение поведения. Этот принцип относится также к делегированию событий (событие делегируется соответствующему обработчику).
Заключение
Эти принципы разработки помогают писать гибкий код, стремящийся к высокой связности и низкому зацеплению. Как только вы это освоите, следующим шагом будет изучение шаблонов проектирования для решения общих проблем разработки приложений и программного обеспечения.