Принципы проектирования приложений

Выделите аспекты приложения , которые могут изменяться, и отделите их от тех, которые всегда остаются постоянными.

Иначе говоря, если некий аспект кода изменяется (допустим, с введением новых требований), то его необходимо отделить от аспектов, которые остаются неизменными.

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

Отдавайте предпочтение композиции перед наследованием. Системы, созданные на основе композиции, обладают значительно большей гибкостью. Они позволяют не только инкапсулировать семейства алгоритмов, но и изменять поведение во время выполнения - при условии, что объект, подключенный посредством композиции, реализует правильный интерфейс. Композиция используется во многих паттернах проектирования.

Программируйте на уровне интерфейсов, а не на уровне реализации. Для представления каждого аспекта поведения будет использоваться интерфейс, а каждая реализация аспекта поведения представлена реализацией этого интерфейса.

Стремитесь к слабой связанности взаимодействующих объектов. Если два объекта могут взаимодействовать, не обладая практически никакой информацией друг о друге, такие объекты называются слабосвязанными. На базе слабосвязанных архитектур строятся гибкие ОО-системы, которые хорошо адаптируются к изменениям благодаря минимальным зависимостям между объектами. В архитектуре паттерна Наблюдатель между субъектами и наблюдателями существует слабая связь.

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

Код должен зависеть от абстракций, а не от конкретных классов. На первый взгляд этот принцип сильно напоминает принцип "Программируйте на уровне интерфейсов, а не на уровне реализации", однако принцип инверсии зависимостей предъявляет еще более жесткие требования к абстракции. Он требует, чтобы высокоуровневые компоненты не зависели от низкоуровневых; вместо этого и те, и другие должны зависеть от абстракций.

Общайтесь только с близкими друзьями. Данный принцип требует сократить взаимодействие между объектами до нескольких близких "друзей". На практике это означает, что при проектировании системы для любого объекта следует обратить особое внимание на количество классов с которыми он взаимодействует, и каким образом организовано это взаимодействие. Этот принцип препятствует созданию архитектур с большим количеством тесно связанных классов, в которых изменение в одной части системы каскадно распространяется в другие части. При формировании многочисленных зависимостей между классами система теряет гибкость и становится сложной для понимания, а затраты на ее сопровождения возрастают.

Не вызывайте нас - мы вас сами вызовем. Данный принцип помогает предотвратить "разложение зависимостей" - явление при котором компоненты высокого уровня зависят от компонентов низкого уровня, которые зависят от компонентов низкого уровня, которые зависят и т.д. Разобраться в архитектуре такой системы очень трудно. Голивудский принцип позволяет компонентам низкого уровня подключаться к системе, но компоненты высокого уровня сами определяют, когда и как они должны использоваться. Иначе говоря, компоненты высокого уровня запрещают компонентам низкого уровня "проявлять инициативу".

Класс должен иметь только одну причину для изменений. Наличие нескольких причин для изменения повышает вероятность того, что класс изменится в будущем, а если это все же произойдет - изменения повлияют на несколько аспектов архитектуры. Изменений в классах следует по возможности избегать - модификация кода обычно сопровождается массой проблем. Принцип указывает на то, что каждому классу должна быть выделена одна - и только одна! - обязанность. Разделение обязанностей в архитектуре является одной из самых сложных задач.