Ответ 1
Пространство имен сообщает вам о том, кому принадлежит определение. Конечно, имеет смысл, что интерфейс принадлежит другой группе, чем реализация; что вся точка интерфейса, разделение проблем.
Стоит ли иметь отдельные пространства имен для интерфейсов и реализаций?
Совет Stroustrup в своей книге на С++ (четвертое издание) заключается в том, что мы должны использовать отдельные пространства имен для интерфейсов и реализаций. Могут ли более опытные люди сказать что-то на этом? Я имею в виду, это звучит неплохо, но действительно ли это практично, имеет ли смысл проекты в реальном мире?
Пространство имен сообщает вам о том, кому принадлежит определение. Конечно, имеет смысл, что интерфейс принадлежит другой группе, чем реализация; что вся точка интерфейса, разделение проблем.
В коде, который очень тяжелый для реализации (скажем, некоторая метапрограммируемая чудовищность внутри Boost), может быть полезно сразу заметить, какой код вы, как ожидается, сможете использовать напрямую, и какой код вы можете безопасно игнорировать, Код в библиотеке detail
namespace считается внутренним кодом, поэтому вам не нужно тратить время на поиск документации, когда вы видите символ detail
в трассировке стека.
Я бы не сказал, что там огромное преимущество и, конечно, не так в общем случае, но поскольку он не наносит никакого вреда, вы можете сохранить вещи аккуратными и разделенными.
это имеет смысл в реальных проектах?
Да, например, в boost он широко используется. Например, boost::shared_ptr
. Как только я увижу namespace detail
, я сразу же знаю, что я не слишком заглядываю в этот сегмент кода, если там не появляется сообщение об ошибке, сообщающее мне сделать это (и даже тогда, скорее всего, это моя ошибка).
Я думаю, вы знаете, как управлять автомобилем. Существует много интерфейсов: рулевое колесо, педали газа/разрыва/сцепления, дисплеи и т.д. Вы заинтересованы в использовании этих интерфейсов, ведь именно так вы используете свой автомобиль:
namespace the_company{
struct wheel{
void turnLeft(deg);
void turnRight(deg) { turnLeft(-deg); }
};
struct pedal{
void tap();
void press_completely_till_something_happens();
//!< might deadlock if using break and car isn't moving
};
struct display{
so_many_colors lookat();
};
}
Для этого примера мы собираемся объединить их вместе как автомобиль, но разделение вещей на разные пространства имен не только практично для ООП.
namespace the_company{
struct car{
public:
wheel & getWheel();
pedal & getBreakPedal();
...
};
}
Что мы можем ожидать от car
? Мы можем ожидать, что мы сможем использовать колесо автомобиля или педаль, и он будет работать:
car myCar;
myCar.getGasPedal().press_completely_till_something_happens();
// OH GOD; WHAT HAVE I DONE!?
myCar.getWheel().turnLeft(360);
myCar.getBreakPedal().press_completely_till_something_happens();
// Shew. That was close.
И мы полностью используем этот car
. Кстати, мы не помещали wheel
в car
, так как наша компания могла производить другие вещи, которые используют колесо, такие как лодки, грузовики, надутые самолеты, клапаны и другие предметы, не связанные с транспортным средством, и display
могут быть использованы еще более разными вещами (телефоны, мониторы, телевизоры, вы называете это).
Однако, чтобы фактически запустить автомобиль, у него должен быть двигатель. Поскольку двигатели являются довольно сложным оборудованием, мы спрячем их под hood
:
namespace the_company{
namespace hood{
struct engine{
// heavily optimized code
// not so nice interface anymore
// maybe not even documentated
...
};
}
}
Это engine
- зверь, он масштабируемый и может работать на любом автомобиле или тяжелой технике, и ваша компания прилагает много усилий для оптимизации. Теперь, когда у владельца автомобиля возникает проблема с его движком, он может просто заглянуть в hood
и проверить, что не так.
Но тот факт, что он скрывается за чем-то, уже говорит пользователю с самого начала, что он должен знать, что он собирается делать. И если он не понимает металл/код, он должен обратиться за помощью в службу поддержки/поддержки.
Кроме того, engine
может измениться или даже полностью удалиться, потому что наша компания придумала fusion_engine
, что дает лучшую прибыль.
И это то, что namespace detail
для меня: сложные детали, которые могут измениться и даже могут иметь смысл только для первоначальных сопровождающих. Но это прекрасно. Это не часть интерфейса.