(Я не читал Чистый код и не знаю много Java.)
Имеет ли смысл применять идею создания множества крошечных объектов, каждый с четко определенной ответственностью, к пространствам имен?
Да, так же, как это происходит с рефакторингом на несколько классов и несколько функций.
Всегда ли небольшая группа связанных классов должна быть заключена в пространство имен?
На самом деле не отвечая: да, вы должны хотя бы использовать одно пространство имен верхнего уровня. Это может быть основано на проекте, организации или как угодно, но использование нескольких глобальных имен уменьшит конфликты имен. Единое пространство имен для группировки всего остального под ним вводит только одно глобальное имя. (Исключая внешние функции "C", но это связано с совместимостью C и влияет только на другие внешние функции "C".)
Следует ли заключить небольшую группу связанных классов в пространство имен, выделенное для них? Вероятно. Особенно если вы используете общий префикс для этих классов - FrobberThing, FrobberThang, FrobberDoohickey - вы должны рассмотреть пространство имен - frobber :: Thing и так далее. Это все еще будет в вашем корневом пространстве имен или другом пространстве имен, если они являются частью более крупного проекта.
Это способ управлять сложностью наличия множества крошечных классов, или затраты на управление множеством пространств имен будут чрезмерно высокими?
Используя приведенный выше пример с префиксными именами, управлять frobber :: Thing не сложнее, чем FrobberThing. Это может быть даже проще с некоторыми инструментами, такими как документирование и завершение кода. Есть разница с ADL, но это может работать в вашу пользу: меньшее количество имен в связанных пространствах имен упрощает ADL, и вы можете использовать объявления для вставки конкретных имен в одно или другое пространство имен.
Псевдонимы пространства имен позволяют вам использовать более короткое имя для более длинного пространства имен в определенном контексте, что опять же позволяет более легкое использование:
void f() {
namespace CWVLN = Company_with_very_long_name; // Example from the standard.
// In this scope, use CWVLN::name instead of Company_with_very_long_name::name.
namespace fs = boost::filesystem; // Commonly used.
}
Рассмотрим Boost, который имеет единственное корневое пространство имен, boost, а затем множество подпространств имен - boost :: asio, boost :: io, boost :: filesystem, boost :: tuples и т. Д. - для различных библиотек. Некоторые имена «повышаются» до корневого пространства имен:
Все определения находятся в пространстве имен :: boost :: tuples, но наиболее распространенные имена поднимаются до пространства имен :: boost с помощью объявлений. Эти имена: tuple, make_tuple, tie и get. Кроме того, ref и cref определяются непосредственно в пространстве имен :: boost.
Самое большое отличие от языков с «настоящими» модулями заключается в том, насколько распространено использование более плоской структуры, что в основном происходит потому, что так оно и работает, если только вы не приложите особых усилий для определения вложенных имен.