Андрей Попов. Доцент.

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

Объектно-ориентированное программирование

Короткий вводный курс в ООП: основные понятия, механизмы и паттерны проектирования.

Вопросы к экзамену

  1. История развития ООП как одной из парадигм программирования.
  2. Процедурный и объектно-ориентированный стили программирования.
  3. Базовые принципы объектно-ориентированного программирования.
  4. Пространства имен для классов.
  5. Области видимости полей и методов в классах и объектах.
  6. Создание и удаление объектов. Конструкторы и деструкторы объектов.
  7. Инкапсуляция в ООП.
  8. Наследование в ООП. Абстрактные класы.
  9. Принцип полиморфизма в ООП.
  10. Константы класса. Статические свойства и методы.
  11. Типы отношений между объектами: наследование, композиция, агрегация.
  12. Дополнительные инструменты ООП: интерфейсы и трейты.
  13. События и сообщения в ООП.
  14. UML-диаграммы классов.
  15. Компонентный подход к программированию. Бинарные объекты.
  16. Особенности ООП в JavaScript
  17. Паттерны проектирования в ООП: назначение и основные принципы.
  18. Паттерн проектирования "Стратегия".
  19. Паттерн проектирования "Декоратор".

Литература к курсу

  1. Зандстра М. "РНР: объекты, шаблоны и методики программирования", 4-е изд. ООО "И.Д. Вильяме", 2015. - 576 с.
  2. Фримен Э., Фримен Э., Сьерра К., Бейтс Б. "Паттерны проектирования" — СПб.: Питер, 2011. — 656 с.
  3. Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж. "Приемы объектно-ориентированного проектирования. Паттерны проектирования". – СПб.: Питер, 2016. – 368 с.
  4. Вайсфельд М. "Объектно-ориентированное мышление". – СПб.: Питер, 2014. – 304 с.
  5. Мартин Р. "Чистый код: создание, анализ и рефакторинг. Библиотека программиста". – СПб.: Питер, 2013. – 464 с.
  6. Блинов И.Н., Романчик В.С. "Java. Методы программирования : уч.-мет. пособие". – Минск : издательство «Четыре четверти», 2013. — 896 с.

Презентации и примеры к лекциям

Примеры: https://github.com/andpop/oop-examples

  1. Объектно-ориентированное программирование. Предыстория.
  2. Базовые понятия ООП. Классы, объекты, инкапсуляция, наследование, полиморфизм.
  3. Дополнительные механизмы ООП. Статические свойства и методы, интерфейсы, трейты, пространства имен.
  4. Отношения между классами и объектами. Наследование, композиция, агрегация. Диаграммы UML.
  5. Итераторы и генераторы.
  6. Паттерны (шаблоны) проектирования.

Лабораторные работы

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

I. Базовые операции с классами и объектами

1. (5 баллов) Создать класс Student для хранения данных о студентах с полями: id, Фамилия, Имя, Отчество, Дата рождения, Адрес, Телефон, Факультет, Курс, Группа.

  1. Определить конструктор и методы чтения/записи полей.
  2. Определить метод __toString() для вывода полной информацию об объекте в консоль.
  3. Поле id должно быть автоинкрементным (вычисляется автоматически).
  4. Методы записи полей должны быть написаны так, чтобы их вызовы можно было объединять в цепочки ($student->setName(...)->setLastname(...)->setAddress->...).
  5. Создать массив объектов-экземпляров класса Student. С помощью цикла вывести:
    • список студентов заданного факультета;
    • списки студентов для каждого факультета и курса;
    • список студентов, родившихся после заданного года;
    • список учебной группы.


2. (7 баллов) Создать класс Book для хранения данных о книгах с полями: id, Название, Автор (ы), Издательство, Год издания, Количество страниц, Цена, Тип переплета.

  1. Определить конструктор и методы чтения/записи полей.
  2. Определить метод __toString() для вывода полной информацию об объекте в консоль.
  3. Поле id должно быть автоинкрементным (вычисляется автоматически).
  4. Методы записи полей должны быть написаны так, чтобы их вызовы можно было объединять в цепочки ($book->setName(...)->setYear(...)->setPages->...).
  5. Создать массив объектов-экземпляров класса Book. С помощью цикла вывести:
    • список книг заданного автора;
    • список книг, выпущенных заданным издательством;
    • список книг, выпущенных после заданного года.


3. (5 баллов) Определить класс "Квадратное уравнение". Реализовать в нем методы для поиска корней, экстремумов, а также интервалов убывания/возрастания. Создать массив таких объектов и определить наибольшие и наименьшие по значению корни.


II. Расширенные средства ООП и паттерны проектирования

4. (8 баллов) Создать классы StudentList и BookList для работы с массивами экземпляров классов Student и Book из заданий 1 и 2. Классы StudentList и BookList должны реализовывать интерфейс Iterator для перебора элементов массива объектов с помощью foreach.
Создать классы Students и Books, которые будут содержать поля типа StudentList и BookList, и определить в этих классах методы для вывода информации из заданий 1 и 2.


5. (7 баллов) Определить абстрактный класс Фигура с абстрактными методами вычисления периметра и площади. Унаследовать от него классы Прямоугольник, Треугольник, Круг.

  • Создать несколько экземпляров этих классов и вычислить их периметры и площади с помощью двух функций calcPerimeter(figure) и calcSquare(figure), используя принцип полиморфизма. Функции должны корректно работать для любой фигуры, передаваемой им в качестве параметра.
  • Сделать то же самое, но вместо абстрактного класса использовать интерфейс Фигура.
  • Решить эту задачу без использования полиморфизма.


6. (9 баллов) В компьютерной игре участвуют различные персонажи (Тролли, Эльфы, Гоблины, Гномы, Рыцари и т.п.), которым доступно несколько типов оружия (Топор, Молот, Лук и стрелы, Меч, Нож и т.п.). Каждый персонаж в любой момент времени использует только один вид оружия, но может свободно поменять его в ходе игры.
Создать объектную иерархию персонажей, в каждом классе реализовать метод fight(), который будет выводить в консоль результат применения текущего оружия объектом-персонажем (например, "Гном ударил топором", "Гном выстрелил из лука", "Рыцарь ударил мечом" и т.п.). Замену оружия реализовать методом setWeapon(), использование оружия - методом useWeapon().
При построении классов для решения задачи воспользоваться паттерном "Стратегия".


7. (9 баллов) Создать иерархию классов для рачета стоимости бронирования номеров в гостинице. Имеются номера "Эконом" - 1000 руб/ночь, "Стандарт" - 2000 руб/ночь, "Люкс" - 3000 руб/ночь. В любой номер можно заказать дополнительные услуги: выделенный Интернет - 100 руб, дополнительный диван - 500 руб, доставка еды в номер - 300 руб, завтрак "шведский стол" - 500 руб, ужин - 800 руб и т.п.
Вывести в консоль категорию заказанного номера и перечень дополнительных услуг, а также общую стоимость заказа.
Для решения задачи воспользоваться паттерном "Декоратор".


III. Практическое применение ООП

8. (20 баллов) Разработать веб-калькулятор для компании, сдающей автомобили поминутно (каршеринг).
У компании есть ряд тарифов. Вам необходимо реализовать каждый тариф в своем классе.
У каждого тарифа две основные характеристики - цена за 1 км, цена за 1 минуту. Каждый тариф обязан иметь метод для подсчета цены поездки. В некоторых тарифах возможно использование дополнительных услуг, которые могут быть объявлены с помощью механизма trait.
Минимальный возраст водителя - 18 лет, максимальный - 65 лет. В случае возраста от 18 до 21 года, тариф повышается на 10%.
Ваша задача - посчитать цену, которую получит пользователь, если проедет Х км и Y минут по тарифу Z.

Тариф базовый

  • цена за 1 км = 10 рублей
  • цена за 1 минуту = 3 рубля
Тариф почасовой
  • Цена за 1 км = 0
  • Цена за 60 минут = 200 рублей
  • Округление до 60 минут в большую сторону
Тариф суточный
  • цена за 1 км = 1 рубль
  • цена за 24 часа = 1000 рублей
  • округление до 24 часов в большую сторону, но не менее 30 минут. Например 24 часа 29 минут = 1 сутки. 23 часа 59 минут = 1 сутки. 24 часа 31 минута = 2 суток.
Тариф студенческий
  • цена за 1 км = 4 рубля
  • цена за 1 минуту = 1 рубль
  • Возраст водителя не может быть более 25 лет
Дополнительные услуги (трейты):
  • GPS в салон - 15 рублей в час, минимум 1 час. Округление в большую сторону. Доступно на всех тарифах.
  • Дополнительный водитель - 100 рублей единоразово, доступен на всех тарифах, кроме базового и студенческого.
Ожидаемая реализация:
  1. Создать интерфейс, который будет содержать описание метода подсчета цены и другие необходимые функции.
  2. Реализовать абстрактный класс, который будет описывать основные методы, заниматься определением возраста и имплементировать описанный в п.1 интерфейс.
  3. Все тарифы должны наследоваться от абстрактного тарифа из п.2.
  4. Дополнительные услуги реализовываются с помощью механизма трейтов (если они поддерживаются выбранным языком программирования). Они доступны по умолчанию, но не активированы. Активация происходит путем передачи аргументов в конструктор класса.
Калькулятор должен представлять собой веб-форму, в которой вводится возраст водителя, длительность и протяженность планируемой поездки, выбирается тариф и дополнительные услуги. В результате подсчета пользователь должен увидеть итоговую сумму и ее слагаемые.
Все цены на тарифы и дополнительные услуги должны храниться в отдельном конфигурационном файле или базе данных.

Статистика группы 402

  • Полное выполнение задания к контрольному сроку - 100% баллов за это задание.
  • Задержка с выполнением задания на срок до 14 дней - 80% баллов за это задание.
  • Задержка с выполнением задания на срок более 14 дней - 50% баллов за это задание.