Навеяно холиварами на RSDN…

Если вы читали книгу «Программист-прагматик» Эндрю Ханта и Дэйва Томаса, то наверное знаете о чем пойдет речь.

Ортогональность также называют Separation of Concerns или применением принципа “Разделяй и властвуй” в архитектуре программ, принцип SRP является отражением идеи ортогональности.

Сам термин заимствован из геометрии и обозначает что линии пересекаются под прямым углом (на самом деле из алгебры и обозначает что скалярное произведение векторов равно нулю). В программировании этим термином обозначают независимость.

Об ортогональности мало пишут в книжках и умных статьях по архитектуре.  Обычно пишут о паттернах, доменной модели, базах данных и об Ubiquitous Language (боюсь даже переводить). При этом ортогональность является основополагающим принципом разработки ПО.

Вы сами часто сталкивались с ортогональностью в разных проявлениях:  разделение модели и представления, отделение Data Access Layer от Business Logic Layer, разделение данных и алгоритмов их обработки в паттернах State, Strategy.

Идея ортогональности в архитектуре программ очень проста – разделять на независимые части все что только можно разделить. Если какая-то задача может быть решена независимо от других, то в решении этой задачи не должно появляться лишних связей любой природы с другими частями программы.

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

Использование IoC-контейнеров делает управление зависимостями и временем жизни объектов независимым от пользователей этих объектов. AOP ортогонализирует (ух какое слово) так называемую сквозную функциональность. Методу, результат которого кешируется, и вызывающему его коду абсолютно не надо знать что происходит кеширование и как оно происходит. Применение паттернов MVC, MVP, MVVM делает независимыми сам интерфейс, от логики работы с низлежащей моделью, и даже если модель переедет на другую машину в сети, то интерфейс править не придется. Это все примеры ортогональности.

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

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

Информация от алгоритмов её обработки не зависит поэтому они должны быть отделены. Это не значит что объекты с методами должны быть без полей. Во-первых многие объекты могут быть параметризованы, во-вторых некоторые объекты могут иметь внутреннее изменяемое состояние, то таких объектов обычно очень мало.

Под конец лирического отступления хочу привести пример очень популярного способа нарушать ортогональность.

Доменная модель или почему Фаулер неправ.

Domain Model – очень популярный паттерн построения бизнес-логики в бизнес-приложении. Заключается как раз в объединении данных, хранимых чаще всего в БД, и методов бизнес-логики в одном объекте. Все это преподносится как соответствие модели предметной области из реального мира.

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

Во-первых не все методы бизнес-логики удается распихать по доменным объектам, приходится создавать искусственные объекты – контейнеры методов, что уменьшает согласованность и ухудшает читаемость.

Во-вторых данные, объединенные с методами становится невозможно передавать по сети в многозвенных приложениях, а также возникают сложности с передачей доменных объектов просто в другой модуль. Для этих целей начинают создавать DTO, фактически моделируя передачу информации, это приводит к расползанию изменений при изменении модели данных.

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

Заключение

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

Теги : архитектура