вторник, 19 июля 2011 г.

Разработка больших систем. Часть 4. Принципы ООП.

Принципы ООП очень хорошо описаны тут: http://www.oodesign.com/design-principles.html (правда по английски).

Их всего 5.

Здесь я хочу показать, что , по-сути, каждый из них служит описанной в третей части идее «программирования основанного на контрактах». Все они направлены на то, что контракты будут существовать, будут понятными и будут соблюдаться.

Принцип open-close

Класс должен быть закрыт для модификаций, но открыт для расширений.

Другими словами, если вам нужно новое поведение (новый контракт) наряду со старым поведением (существующий контракт), вы не должны вносить исправления в существующий код класса (чтобы не повредить выполнению старого контракта). Вместо этого, класс надо отнаследовать, и уже наследник должен соблюдать новый контракт.

Принцип инверсии зависимостей

Состоит из двух утверждений:
1. Высокоуровневые модули не должны зависеть от низкоуровневых модулей. И те и другие должны зависеть от абстракций.
2. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций (конкретизируя их)

По сути, именно абстракции задают контракты. Отсутствие зависимостей между модулями — это перефразированное утверждение, приведенное в третей части «каждый класс - самостоятельная сущность, которая НИЧЕГО не знает о внутреннем строении других классов».
Второе утверждение говорит о первичности контрактов (абстракций) относительно деталей их реализаций. Иными словами, контракт не должно волновать, каким образом он будет выполнен.

Принцип сегрегации интерфейсов

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

Пример плохого интерфейса
interface HrenovaTucha {
void sentToPrinter(String text);
Image scan();
void burnCD(Image cd)
}


Что мне делать, если у меня нет сканера?

С точки зрения программирования, основанного на контрактах, данный принцип запрещает создание плохих контрактов: тех, которые в совокупности не определяют поведение одного разумного объекта.

Принцип единственной зоны ответственности

У каждого класса должна быть ровно одна причина для изменения.
Этот принцип запрещает создание классов неясного или смешанного назначения.
Если приглядеться к такому классу, всегда можно увидеть два или более разных, не связанных между собой, контракта , которые один класс пытается исполнять.
В результате мы получаем переусложненный класс, который невозможно поддерживать, и переусложненный контракт, который стоило бы разделить.

Принцип подменяемости Лискова

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

Другими словами — класс наследник обязан соблюдать контракт класса-родителя. Однако наследник имеет право расширить контракт, введя новые методы. И полное право изменить способ выполнения контракта, перегрузив существующие методы.

Комментариев нет: