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

Рассмотрим эволюцию системы при гибкой методологии разработки (Agile software development).
В Agile методологии стараются получить как можно раньше простейшую рабочую версию системы, после чего продолжается итеративное наращивание её функциональности, под наблюдением заказчика.
По мере усложнения системы (когда количество классов начинает доходить до сотни) начинаются первые мероприятия по контролю сложности. Начинаются рефакторинги, направленные на "распутывание" кода и выделение компонентов из общей массы классов системы.
Под компонентом следует понимать набор взаимосвязанных классов, которые вместе реализуют функциональность, объявленную в интерфейсе компонента. Пользователь компонента имеет дело только с интерфейсом компонента. Компонент нужно рассматривать как черный ящик, из которого наружу торчит интерфейс, а реализация этого интерфейса спрятана внутри черного ящика.
Классы, внутри компонента (классы реализация компонента) не должны быть доступны для пользователя компонента для непосредственной работы с ними. В Java их нужно сделать скрытыми на уровне пакета, в C++ их нужно спрятать за пространство имён. Имя такого пакета или имя пространства имён должно оканчиваться суффиксом "_impl". Задача суффикса "_impl" – это лишний раз напомнить пользователю компонента о том, что здесь находятся классы, предназначенные только для внутреннего использования данным компонентом, и могут быть изменены и даже удалены в следующей версии компонента без предупреждения.
Следует учитывать, что далеко не все классы системы можно сгруппировать в компоненты. Например, низкоуровневые утилитные классы, которые используются из разных мест системы, должны быть сами по себе и публично доступны.
Итак, после первых рефакторингов, когда размер нашей системы меньше сотни классов, мы имеем несколько компонентов, выделенных из общей массы классов. С этого момента и впредь мы программируем не только объектно, но еще и компонентно, вовремя замечая и выделяя компоненты из временной монолитной конструкции. Сложность взята под контроль, эволюция системы продолжается.
При достижении размера системы в несколько сотен классов, сложность снова начинает выходить из-под контроля. Классы бизнес логики лежат вперемешку с утилитными классами, с классами GUI, с классами для работы с сетью, с базой данных и т.д. Имеет место смешивание уровней. Низкоуровневые классы системных утилит находятся по соседству с классами бизнес логики, путаются под ногами, мешая нам понять работу бизнес логики.
Очевидно, нужна следующая стадия разбиения, в этот раз на модули и уровни. Каждый модуль помещается в отдельный проект-библиотеку. В C++ это .lib-файл, а в Java это jar-файл. Сложность модуля должна быть такова, чтобы программист, незнакомый с этим модулем, смог бы полностью понять его внутренне устройство за промежуток времени приблизительно равный итерации.
Модули сортируются по уровням декомпозиции. Самые низкоуровневые модули, содержат только классы утилитного, системного назначения, которые являются надстройкой над стандартным API.
Модули среднего уровня содержат компоненты, имеющие привязку к какой-то предметной области, но не имеющую привязку к приложению. Например, модуль проверки орфографии, привязан к предметной области – орфографии, но может быть использован в самых разных приложениях.
Модули высокого уровня всегда привязаны к предметной области приложения. Это может быть модуль модели предметной области, модуль контроллера модели предметной области, модуль работы с базой данных, модули GUI представлений.
Здесь приведено всего 3 уровня декомпозиции. В зависимости от сложности системы их может быть и больше.
При распределении задач между участниками команды, учитываются их индивидуальные наклонности. Тем, кому нравится низкоуровневый, системный девелопмент, предлагают поработать над модулями системного уровня. Тем, кто больше склонен к высокоуровневому мышлению, предлагают модули уровня приложения. Модули среднего уровня хорошо подходят для аутсорсинга.
Для удобства модули можно группировать в подсистемы. Одна подсистема может включать модули их разных уровней декомпозиции. Разные подсистемы могут повторно использовать одни и те же модули.
Архитектура приложения, правильно использующая разбиение на компоненты, модули, уровни и подсистемы способна легко справиться со сложностью и в 10 тысяч классов.