понедельник, 12 октября 2009 г.

PJP: Р.Мартин. Быстрая разработка программ (Пн, 12окт).

* принцип персональной ответственности
Для использование одной функциональноcти достаточно использования одного класса (хотя реализовываться может с использованием многих, [скажем это класс - Facade]) + у одного класса - одна функциональность (а не больше).

// bad idea
class User {
private int age;
private String name;
// getters-setters here
public String toXml() {...}
}

//good idea
class User {
private int age;
private String name;
// getters-setters here
}
class ToXmlConverter{
public String toXml(User user) {...}
}

* принцип открытия-закрытия

модуль/класс/библиотека/фреймворк должны быть открыты для расширения и закрыты для изменения. Расширение через наследование, оборачивание в делегировании, регистрации listeners, регистрации callback-функций, etc. Примеры - Spring, Hibernate - миллионы пользуются и расширяют, но никто не модифицирует сорцы. Как? Учите/читайте сорцы Spring, Hibernate, читайте "Practical API Design".

* принцип подстановки Лискоу
Потомок не может сужать контакт предка. Должен принимать все аргументы допустимые для предка, не кидать новых исключений, а вот результат - может быть Уже! Потомок может быть подставлен везде - где стоит предок. Square - is NOT Rectangle. Little Rectangle - is NOT Rectangle.

* принцип инверсии зависимостей (DIP/IoC)
Не клиент находит/создает/вызывает сервис, а IoC-Container находит/создает инсталирует клиенту сервис, а клиент вызывает. Т.е. клиент теряет Control в пользу контейнера.

* принцип отделения интерфейса
public interface Printer {
public void print(Paper paper);
}
class PrinterImpl implements Printer{
public void print(Paper paper) {...}
}
1) в пакете com.mysite.myproj.print Printer - публичен и доступен всем, конктерная реализация PrinterImpl - видна только тому кому нужно (IoC-Container?).
2) все клиенты принтера используют интерфейс Printer, а не конкретную реализацию PrinterImpl.
3) интерфейс принадлежит клиенту. Сервер не имеет право его менять. Реализацию - пожалуйста, но не публичный интерфейс.

3 комментария:

  1. не понял фразу "Square - is NOT Rectangle. Little Rectangle - is NOT Rectangle"

    Квадрат не является прямоугольником ? Маленький прямоугольник не являеся прямоугольником ?

    ОтветитьУдалить
  2. Это краткое напоминание примера с семинара в Пн.
    Квадрат не является прямоугольником (согласно принцыпу подстановки Лисков), так как сужает контраст предка. У предка-прямоугольника можно установить независимо размеры
    setWidth(100);
    setHeight(200);
    а у потомка-квадрата - нельзя. В техническом смысле - как должна реагировать реализация квадрата на установку РАЗЛИЧНЫХ ЗНАЧЕНИЙ ширины и высоты?
    Аналогично с маленьким прямоугольником (стороны меньше 100) - как отреагирует на установку ширина=1000? Предок - проглотит и переварит, а потомок? Бросит исключение?

    ОтветитьУдалить
  3. На семинарах в Пн я все это детально обсуждаю.

    ОтветитьУдалить