Введение в программирование

Введение в ОО дизайн

Принципы SOLID

Содержание

Принципы SOLID

  • Single Responsibility
  • Open/Closed
  • Liskov Substitution
  • Interface Segregation
  • Dependency Inversion

Single Responsibility

  • Принцип единственной ответственности
    • Один класс – одна ответственность
    • Одно изменение - одно место

Open/Closed

  • Принцип открытости/закрытости
    • Открытость для расширения
    • Закрытость для изменения

Liskov Substitution

  • Принцип подстановки Лисков
    • Тип заменяется любым подтипом
    • Ослабление предусловий
    • Сохранение инвариантов
    • Усиление постусловий
    • Ограничение истории

Interface Segregation

  • Принцип разделения интерфейсов
    • Зависимость только от используемого

Dependency Inversion

  • Принцип инверсии зависимостей
    • Клиенты зависят от абстракций
    • Реализация зависит от абстракций

Задача о прямоугольнике и квадрате

Содержание

Постановка задачи

  • Прямоугольник
    • Ширина
    • Высота
  • Квадрат
    • Сторона

Является (is-a)

  • Квадрат является прямоугольником
  • Следовательно
    Square extends Rectange
  • Как реализовать setWidth?
    • Изменить сторону
    • Перестать быть квадратом

Расширение

  • Интерфейс прямоугольника «шире»
  • Следовательно
    Rectangle extends Square
  • Как реализовать getSide?
    • Не понятно

Возможные решения

  • Неподдерживаемые действия
  • Ослабление контракта
  • Возврат нового
  • Выделение общего предка
  • Вынос изменений
  • Отказ от наследования
  • Подмена класса

Неподдерживаемые действия

  • Не все действия поддерживаются
    • boolean setWidth(int w)
  • Square extends Rectangle
  • Постоянные проверки
  • Поддержка со стороны Rectangle

Ослабление контракта

  • Действия имеют побочные эффекты
    • setWidth ≡ setSide
  • Square extends Rectangle
  • Как этим пользоваться?

Возврат нового

  • Операция возвращает новый объект
  • Rectangle setWidth(int w)
  • Square extends Rectangle
  • Неизменяемые объекты

Вынос изменений

  • Изменения выносятся в отдельный класс
  • Square extends Rectangle
    MutableRectangle extends Rectangle
    MutableSquare extends Square
    
  • Много классов
  • Комбинаторный взрыв

Выделение общего предка

  • Выделить общего предка
  • Square extends SquareOrRectangle
    Rectangle extends SquareOrRectangle
    

Отказ от наследование

  • Два независимых класса
    Square::asRectangle
    Rectangle::boundingSquare
    

Подмена класса

  • Класс может меняться
  • setWidth преобразует в Rectangle
  • Square extends Rectangle
  • Не поддерживается популярными языками

Равенство

Содержание

Сущности и значения

  • Изменение частей
    • Сущность не изменяется
    • Новое значение
  • Примеры
    • Студент
    • Точка
    • Адрес

Поддержка в Java

  • Чему соответствует ==?
    • Сущностям
  • Поддержка значений
    • public boolean equals(Object o)

Реализация equals

  • Точка
    • class Point {
          int x, y;
      
  • Сравнение
    • public boolean equals(Object o) {
          if (o instanceof Point) {
              Point that = (Point) o;
              return this.x == that.x && this.y == that.y;
          }
          return false;
      }
      
    • Почему нет проверки на null?
    • null instanceof Tfalse

Свойства равенства

  • Рефлексивность
    • x.equals(x)true
  • Симметричность
    • x.equals(y) y.equals(x)
  • Транзитивность
    • x.equals(y) && y.equals(z)x.equals(z)
  • Устойчивость
    • x.equals(y) не изменяется, если x и y не изменяются
  • Обработка null
    • x.equals(null) false

Реализация equals (2)

  • Цветная точка на плоскости
    • public class ColorPoint extends Point {
          protected int c;
          public boolean equals(Object o) {
              if (o instanceof ColorPoint) {
                  ColorPoint that = (ColorPoint) o;
                  return this.x == that.x && this.y == that.y && this.c == that.c;
              }
              return false;
          }
      }
      
  • Где проблема?
    • Несимметричность

Пример equals (3)

  • Цветная точка на плоскости
    • public class ColorPoint extends Point {
          protected int c;
          public boolean equals(Object o) {
              if (o instanceof ColorPoint) {
                  ColorPoint that = (ColorPoint) o;
                  return this.x == that.x && this.y == that.y && this.c == that.c;
              }
              return super.equals(o);
          }
      }
      
  • А теперь?
    • Нетранзитивность

Наследование и equals

  • equals и наследование ⇒ проблемы
  • Варианты решения
    • Сравнивать объекты только одинакового класса
    • Сравнивать как предков
    • Послойное сравнение
      • canEquals

Заключение

Содержание

Литература

Вопросы

???