Однажды я прочитал колонку, в которой сравнивали 3 вида моделей: модель Спагетти, модель Лазаньи и модель Равиоли.
В модели Спагетти весь код взаимосвязан, четкой структуры нет. Это ужасно, и мы, вероятно, все можем согласиться с этим.
В модели Лазанья код разделен на разные уровни, и только слой более высокого уровня может получить доступ к слою более низкого уровня, и никогда наоборот.
В модели Ravioli код сгруппирован в меньшие модули. Каждый модуль предоставляет только то, что нужно показать, но каждый модуль может получить доступ ко всем другим модулям.
Около 10 лет назад мне показалось, что модель Ravioli лучше, чем модель Lasagna. В конце концов, в Java также есть модули Java, которые могут легко вызывать друг друга (и у меня сложилось впечатление, что между всеми различными модулями Java нет реальной структуры). Мне модель Lasagna казалась результатом не-объектно-ориентированного старого кода, а модель Ravioli казалась более современной, более объектно-ориентированной.
В настоящее время я склоняюсь к модели Лазаньи, но со встроенной моделью Равиоли. Это:
- Приложение построено с использованием разных слоев, как в модели Lasagna
- Но внутри слоев код все еще разделен между различными модулями, которые могут обращаться друг к другу, как в модели Ravioli.
Определенные циклические ссылки могут быть трудными или невозможными для удаления. Примером является следующее:
Предположим, у вас есть класс FileWriter в вашем приложении и класс Debug. Классу Debug понадобится класс FileWriter, поскольку ему нужно писать файлы с отладочной информацией.
С другой стороны, класс FileWriter может также захотеть использовать класс Debug.
Обратите внимание, что циклическая ссылка в этом примере уже может привести к проблемам (класс FileWriter может вызывать класс Debug при написании строки, но класс Debug использует класс FileWriter для записи отладочной информации, результат: переполнение стека).
В этом случае проблему можно легко решить, если не использовать класс FileWriter в классе Debug, а использовать собственные iostreams (если вы разрабатываете на C ++). В других случаях проблему может быть гораздо сложнее решить.