Определение ООП

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

Основные концепции

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

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

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

SOLID

SOLID — аббревиатура пяти основных принципов проектирования классов в объектно-ориентированном программировании: Single responsibility, Open-closed, Liskov substitution, Interface segregation и Dependency inversion.

  • Single responsibility principle, принцип единственной обязанности, обозначает, что каждый объект должен иметь одну обязанность и эта обязанность должна быть полностью инкапсулирована в класс. Все его сервисы должны быть направлены исключительно на обеспечение этой обязанности.
  • Open-closed principle, принцип открытости-закрытости устанавливает следующее положение: программные сущности должны быть открыты для расширения, но закрыты для изменения. Существующий класс может быть изменён только для исправления ошибок, при изменении логики необходимо писать новый класс, который может наследоваться от первого.
  • Liskov substitution principle, принцип подстановки Барбары Лисков: «Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.» Если есть класс A и отнаследованный от него класс B, если заменить все использования класса A на B, ничего не должно измениться в работе программы. Класс B должен лишь расширять функционал класса A.
  • Interface segregation principle, принцип разделения интерфейса говорит о том, что слишком «толстые» интерфейсы необходимо разделять на более маленькие и специфические, чтобы клиенты маленьких интерфейсов знали только о методах, которые необходимы им в работе.
  • Dependency inversion principle, принцип инверсии зависимостей устанавливает правило, абстракции не должны зависеть от деталей, а детали должны зависеть от абстракций. Проще говоря, следует избавляться от композиции, заменяя её на агрегацию.

Агрегирование

В ООП под агрегировием подразумевают методику создания нового класса из уже существующих классов путём включения, называемого также делегированием. Об агрегировании также часто говорят как об «отношении принадлежности» по принципу «у машины есть корпус, колёса и двигатель». На базе агрегирования реализуется методика делегирования, когда поставленная перед внешним объектом задача перепоручается внутреннему объекту, специализирующемуся на решении задач такого рода. Существует два типа агрегирования:

  • Агрегация (агрегирование по ссылке) — отношение «часть-целое» между двумя равноправными объектами, когда один объект (контейнер) имеет ссылку на другой объект. Оба объекта могут существовать независимо: если контейнер будет уничтожен, то его содержимое — нет.
  • Композиция (агрегирование по значению) — более строгий вариант агрегирования, когда включаемый объект может существовать только как часть контейнера. Если контейнер будет уничтожен, то и включённый объект тоже будет уничтожен.

Закон Деметры

Общее описание правила: Объект A не должен иметь возможность получить непосредственный доступ к объекту C, если у объекта A есть доступ к объекту B и у объекта B есть доступ к объекту C.

Закон Деметры для функций требует, что метод М объекта О должен вызывать методы только следующих типов объектов:

  • Собственно самого О.
  • Параметров М.
  • Других объектов, созданных в рамках М.
  • Прямых компонентных объектов О.
  • Глобальных переменных, доступных О, в пределах М.

Что такое шаблон проектирования?

Шаблон проектирования, он же паттерн (design pattern), в разработке программного обеспечения — повторимая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.

Виды полиморфизма

Ad hoc (лат. «специально для этого») - вид полиморфизма, в котором полиморфная функция может работать с аргументами различного типа за счет переопределения. То есть одноименные функции с различными типами аргументов распознаются как разные функции.

func Foo(int $varName) {
    // Do some
}

func Foo(string $varName) {
    // Do some
}

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

func Foo($varName) {
    switch get_type($varName) {
        case 'int':
            // Do some
        case 'string':
            // Do some
    }
}

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