Concepts (Base principles: encapsulation, inheritance, polymorphism. Classes and Objects, State and Behavior, Abstraction and Implementation, интерфейсы VS абстрактные классы)

  • [x] Assosiacion vs. Inheritancy (наследование VS делигирование)
  • [x] OO principles (SOLID (SRP, OCP, LSP, ISP, DIP), maybe more)
  • [ ] Object model design (Application modules: grouping data and application logic by types, dependences)

Зачем:

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

Что нового?

Концепция:

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

public «открытый», метод доступен в любом месте программного кода, в любом классе из любого пакета;

protected «защищенный», метод доступен только внутри пакета (package);

private «закрытый», метод недоступен для других классов, виден только внутри класса хозяина;

final – «конечный», метод не может в дальнейшем быть переопределен в потомках;

abstract – «абстрактный», метод является абстрактным и реализация его будет произведена только в потомках. Класс, имеющий хотя бы один абстрактный метод, сам является абстрактным и должен быть объявлен с модификатором abstract;

static «статический», метод принадлежит «классу», и не может принадлежать какому либо из экземпляров этого класса. Установка данного модификатора элементу класса означает что данный элемент будет создан при компиляции и будет принадлежать тому классу, в котором он описан и не будет наследоваться потомками. Статические методы можно вызывать напрямую, не создавая при этом объектов класса, которому данный метод принадлежит.

Наследование – позволяет создавать новый класс на базе другого. Класс, на базе которого создается новый класс, называется базовым, а базирующийся новый класс – наследником.

Пример

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

Полиморфизм– способность объектов с одним интерфейсом иметь различную реализацию (один интерфейс, множество реализаций).

Пример

есть два класса, Круг и Квадрат. У обоих классов есть метод GetSquare(), который считает и возвращает площадь. Но площадь круга и квадрата вычисляется по-разному, соответственно, реализация одного и того же метода различная.

Абстракция - позволяет выделять из некоторой сущности только необходимые характеристики и методы, которые в полной мере (для поставленной задачи) описывают объект.

Пример

создавая класс для описания студента, мы выделяем только необходимые его характеристики, такие как ФИО, номер зачетной книжки, группа. Здесь нет смысла добавлять поле вес или имя его кота/собаки и т.д.

Классы и объекты.

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

Описав класс, можно создать его экземпляр –объект. Объект – это конкретный представитель класса.

Пример

Класс будет отображать сущность – автомобиль.
Атрибутами класса будут являться двигатель, подвеска, кузов, четыре колеса и т.д.
Методами класса будет «открыть дверь», «нажать на педаль газа», а также «закачать порцию бензина из бензобака в двигатель».

Объект (экземпляр)– отдельный представитель класса, имеющий конкретное состояние и поведение, полностью определяемое классом.

Объект имеет конкретные значения атрибутов и методы, работающие с этими значениями на основе правил, заданных в классе.

Пример

Если класс – это некоторый абстрактный автомобиль из «мира идей», то объект – это конкретный автомобиль, стоящий под окнами.

Mersedez и Лада – объекты данного класса.

StateandBehavior.

Состояние - совокупный результат поведения объекта : одно из стабильных условий (охарактеризованных количественно), в которых объект может существовать; в любой момент времени состояние объекта включает в себя перечень (чаще статический) свойств объекта и текущие значения (чаще динамические) этих свойств.

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

Пример

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

Если у человека есть удочка (есть связь с объектом "Удочка"), он может ловить рыбу, если удочки нет, то такое действие невозможно.
Соответственно, набор действий, которые может совершать человек, зависит от параметров объекта, его моделирующего.

Для рассмотренных выше примеров такими характеристиками объекта "Человек" являются:

  • текущее положение человека (стоит, сидит, лежит);
  • наличие удочки (есть или нет).

Поведение

Взаимодействие между объектами в программе происходит посредством передачи сообщений между ними.

В ООП термины "выполнить действие над объектом", "вызвать метод объекта" и "послать сообщение объекту для выполнения какого-либо действия" эквивалентны.

Поведение - действия / реакции объекта, выраженные в терминах передачи сообщений и изменения состояния; видимая извне и воспроизводимая активность объекта.

Пример

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

  • создать;
  • открыть;
  • читать из файла;
  • писать в файл;
  • закрыть;
  • удалить.

Результат выполнения действий зависит от состояния объекта на момент совершения действия, т.е. нельзя, например, удалить файл, если он открыт кем-либо (заблокирован). В то же время действия могут менять внутреннее состояние объекта - при открытии или закрытии файла свойство "открыт" принимает значения "да" или "нет", соответственно.

Состояние - одно из стабильных условий, в которых объект может существовать, охарактеризованных количественно; в любой момент времени состояние объекта включает перечень свойств и их текущее значение, которые определяют поведение объекта.

Уникальность - это то, что отличает объект от других объектов. В ООП под параметром уникальности объекта чаще всего понимается адрес размещения объекта в памяти.

Identity (уникальность)объекта состоит в том, что всегда можно определить, указывают две ссылки на один и тот же объект или на разные объекты. При этом два объекта могут во всем быть похожими, их образ в памяти может представляться одинаковыми последовательностями байтов, но, тем не менее, ихIdentityможет быть различна.

Наиболее распространенной ошибкой является понимание уникальности как имени ссылки на объект. Это неверно, т.к. на один объект может указывать несколько ссылок, и ссылки могут менять свои значения (ссылаться на другие объекты).

Abstraction and Implementation.

Интерфейсы и абстрактные классы.
Интерфейс – это набор методов класса, доступных для использования другими классами.
Интерфейсом класса будет являться набор всех его публичных методов в совокупности с набором публичных атрибутов. (он специфицирует класс, чётко определяя все возможные действия над ним).

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

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

Какая разница между интерфейсом и абстрактным классом?

Абстрактные классы используются только тогда, когда есть "is a" тип отношений;
Интерфейсы могут быть реализованы классами которые не связаны друг с другом.

Абстрактный класс может реализовывать методы;
Интерфейс не может реализовывать методы.

Интерфейс может только описывать константы и методы, но не реализовывать их. Все методы интерфейса по-умолчанию являются публичными (public) и абстрактными (abstract), а поля - public static final.
Класс может наследоваться от многих интерфейсов, но только от одного абстрактного класса.

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

Assosiacion vs. Inheritancy.

Базовые связи между классами в рамках объектной модели:

  1. Агрегация(Aggregation);
  2. Ассоциация(Association);
  3. Наследование(Inheritance);
  4. Метаклассы (Metaclass).

Агрегация (включение)

Отношение между классами типа "содержит" (contain).

Пример

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

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

Ассоциация

Объекты одного класса ссылаются на один / более объектов другого класса, но ни в ту, ни в другую сторону отношение между объектами не носит характера "владения" / контейнеризации. Изображается так же, как отношение агрегации, но линия, связывающая классы, простая, без ромбика.

Пример

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

Ассоциация "многие-ко-многим":

Наследование vs Композиция vs Агрегация

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

Отношение ассоциации

Более точным типом отношений является отношение открытого наследования (отношение «является», IS A Relationship), которое говорит, что все, что справедливо для базового класса справедливо и для его наследника. Именно с его помощью получается полиморфное поведение, мы абстрагируемся от конкретной реализации классов, имея дело лишь с абстракциями (интерфейсами / базовыми классами) и не обращаем внимание на детали реализации.

Отношение наследование

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

В этом случае приходит другая пара отношений: композиция(composition) и агрегация(aggregation). Оба моделируют отношение «является частью» (HAS-A Relationship) и обычно выражаются в том, что класс целого содержит поля (или свойства) своих составных частей. Грань между ними достаточно тонкая, но важная, особенно в контексте управления зависимостями.

Отношение композиции и агрегации

OO principles (SOLID (SRP, OCP, LSP, ISP, DIP)).

Принцип единственной ответственности (Single responsibility)
«На каждый объект должна быть возложена одна единственная обязанность»
Для этого проверяем, сколько у нас есть причин для изменения класса — если больше одной, то следует разбить данный класс.

Принцип открытости/закрытости (Open-closed)
«Программные сущности должны быть открыты для расширения, но закрыты для модификации»
Для этого представляем наш класс как «чёрный ящик» и смотрим, можем ли в таком случае изменить его поведение.

Принцип подстановки Барбары Лисков (Liskov substitution)
«Объекты в программе могут быть заменены их наследниками без изменения свойств программы»
Для этого проверяем, не усилили ли мы предусловия и не ослабили ли постусловия. Если это произошло — то принцип не соблюдается

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

Принцип инверсии зависимостей (Dependency Invertion)
«Зависимости должны строится относительно абстракций, а не деталей»
Проверяем, зависят ли классы от каких-то других классов(непосредственно инстанцируют объекты других классов и т.д) и если эта зависимость имеет место, заменяем на зависимость от абстракции.

Object model design (Application modules: grouping data and application logic by types, dependences).

Достоинства ООП:

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

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

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

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

  5. Обработка разнородных структур данных.

  6. Изменение поведения во время исполнения

  7. Реализация работы с наследниками. Алгоритмы можно обобщить настолько, что они уже смогут работать более чем с одним видом объектов.

  8. Создание "каркаса" (framework). Независимые от приложения части предметной области могут быть реализованы в виде набора универсальных классов, или каркаса (framework), и в дальнейшем расширены за счет добавления частей, специфичных для конкретного приложения.

Недостатки ООП:

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

  2. Многоразовое использование требует от программиста познакомиться с большими библиотеками классов.

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

results matching ""

    No results matching ""