Upgrade to Pro — share decks privately, control downloads, hide ads and more …

АФТИ ООП 2014-2015. Лекция I/15

АФТИ ООП 2014-2015. Лекция I/15

Oleg Dashevskii

December 15, 2014
Tweet

More Decks by Oleg Dashevskii

Other Decks in Education

Transcript

  1. РЕАЛИИ НАШЕГО ДНЯ • ООП везде. Из 10 самых популярных

    языков программирования 10 поддерживают ООП на уровне синтаксиса.
 http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html • Программы на C++ работают быстро. • Ergo: Занимаемся ООП на C++.
  2. СХОДСТВА И РАЗЛИЧИЯ •Порода •Рост •Вес •Цвет •... Свойства: •Лаять

    •Выть •Кусать •Приносить палочку •... Поведение:
  3. НАСЛЕДОВАНИЕ • «Этот объект ведет себя так же, как тот,

    только немного по-другому» • Поведение класса A наследуется от класса B (с изменениями). • B — базовый класс (суперкласс). • A — производный класс (подкласс).
  4. ОБЪЕКТНАЯ СИСТЕМА НА C // new.h struct Class { size_t

    size; void *(*ctor)(void *self, va_list *app); void *(*dtor)(void *self); void (*draw)(const void *self); }; void *new(const void *class, ...); void delete(void *item); void draw(const void *self); // new.c void *new(const void *_class, ...) { const struct Class *class = _class; void *p = calloc(1, class—>size); assert(p); *(const struct Class **)p = class; if (class—>ctor) { va_list ap; va_start(ap, _class); p = class—>ctor(p, &ap); va_end(ap); } return p; } // продолжение следует ... p Объект size ctor dtor draw Класс struct Class
  5. ВЛАДЕНИЕ C++ • Уровень 1. «Более удобный C». • Уровень

    2. «Обычный ООП». Классы, наследование, полиморфизм. • Уровень 3. «Специфичный C++». Переопределение операторов, шаблонные классы и т.д.
  6. • Классы, конструкторы, деструкторы. • new и delete. • Наследование.

    • Ссылки. • Новый синтаксис преобразования типов. • Расширение смысла const. • Перегрузка функций. • namespace и using. • Шаблоны функций и классов. • Переопределение операторов. • Исключения. Что есть в C++, чего нет в C
  7. • Потоки ввода и вывода. • Строки. • Контейнеры. std::vector<T>

    • Итераторы как абстракция доступа к элементу контейнера. • std::list<T> и std::forward_list<T>. • std::map<K, V>, std::multimap<K, V>, std::set<T>. • std::unordered_map<K, V>, std::unordered_multimap<K, V>, std::unordered_set<T>. • Алгоритмы. Стандартная библиотека С++
  8. V. МОДУЛЬНАЯ ЗАЩИЩЕННОСТЬ Аварийная ситуация в одном из модулей ограничится

    только этим модулем или максимум несколькими соседними
  9. ПРИНЦИП ОДНОЙ ЗОНЫ ОТВЕТСТВЕННОСТИ • Single responsibility principle (SRP). •

    Должна существовать только одна причина, которая может привести к изменению класса.
  10. Класс Rectangle Зона ответственности 1.
 Вычисление площади Зона ответственности 2.


    Отрисовка прямоугольника class Rectangle { public: double area() const; // вычислить площадь void draw(); // нарисовать прямоугольник private: // ... };
  11. ЧЕМ ХОРОШО НАСЛЕДОВАНИЕ? • Расширяемость. Полиморфизм. Имея указатель на объект

    базового класса, код может работать с любым его наследником. • Отсутствие дублирования. В идеале:
 
 Новый функционал = Старый функционал + Переопределение некоторых методов
  12. КОМПОЗИЦИЯ • Членами одного класса (хозяина) являются объекты других классов

    (рабы?). • Класс-хозяин управляет порождением и уничтожением этих объектов.
  13. class Boss { Slave slave; std::unique_ptr<AnotherSlave> slave2; public: Boss() :

    slave(), slave2(new AnotherSlave) {} }; Композиция
  14. class Order { // ... }; class User { std::vector<Order

    *> orders; public: // ... }; Агрегация
  15. АССОЦИАЦИЯ • Самая свободная форма связи между классами. • Один

    класс содержит указатель или ссылку на объект другого класса и вызывает его методы. • Порождение и уничтожение объекта происходит где-то вовне.
  16. Ассоциация class Auditor { public: // ... bool auditRead(const string

    &key); bool auditWrite(const string &key); }; class AuditedKVStore { AuditedKVStore(Auditor &_auditor, map<string, string> *_storage) : auditor(_auditor), storage(_storage) {} string get(const string &key); // ... private: Auditor &auditor; map<string, string> *storage; };
  17. Текущее состояние
 системы + = Система с новой возможностью Шаг

    второй Шаг третий Система с новой возможностью Фича’ + = Система с реализованной новой возможностью Абстракция
  18. ПРИНЦИП ПОДСТАНОВКИ ЛИСКОУ • Liskov Substitution Principle (LSP). • «Подтипы

    должны быть заменяемы их исходными типами».
  19. SQUARE И RECTANGLE • Если класс Rectangle имеет интерфейс, предполагающий

    раздельность изменений ширины и высоты (setWidth, setHeight), то Square нельзя наследовать от Rectangle. • Можно сделать, чтобы у класса Square и setWidth, и setHeight устанавливали как высоту, так и ширину, поддерживая «квадратность», но…
  20. ПРИНЦИП ИНВЕРСИИ ЗАВИСИМОСТЕЙ • Dependency Inversion Principle (DIP). • Модули

    высокого уровня не должны зависеть от модулей низкого уровня. Оба типа модулей должны зависеть от абстракций. • Абстракции не должны зависеть от подробностей, наоборот, подробности должны зависеть от абстракций.
  21. Сильная зависимость.
 Невозможно использовать Button
 для управления чем-то еще Button

    Lamp class Lamp { public: void on(); void off(); }; class ToggleButton { Lamp lamp; bool is_on; public: ToggleButton() : is_on(false) {} void toggle() { is_on = !is_on; if (is_on) lamp.on(); else lamp.off(); } };
  22. ToggleButton Lamp Switchable class Switchable { public: virtual void on()

    {} virtual void off() {} }; class Lamp: public Switchable { /* ... */ }; class ToggleButton { Switchable *object; bool is_on; public: ToggleButton(Switchable *o) : object(o), is_on(false) {} void toggle() { is_on = !is_on; if (is_on) object->on(); else object->off(); } };
  23. ПРИНЦИП ОТДЕЛЕНИЯ ИНТЕРФЕЙСА • Interface Segregation Principle (ISP). • Клиенты

    не должны попадать в зависимость от методов, которыми они не пользуются.
  24. class Timer { public: void register(int timeout, TimerClient *client); };

    class TimerClient { public: virtual void timeout() = 0; }; Как сделать класс TimedDoor с сигналом о незакрытии? class Door { public: virtual void lock() = 0; virtual void unlock() = 0; virtual bool isOpen() = 0; };
  25. Single Responsibility Principle
 Open-Closed Principle Liskov Substitution Principle Interface Segregation

    Principle Dependency Inversion Principle Solid – прочный, крепкий, надежный…
  26. На первом этапе нужно вкладываться в ядро и довольствоваться 


    простой периферией! Ядро (прототип) + 
 простенькая периферия = 
 первая версия системы!