Подтвердить что ты не робот

Стоит ли иметь отдельные пространства имен для интерфейсов и реализаций?

Стоит ли иметь отдельные пространства имен для интерфейсов и реализаций?

Совет Stroustrup в своей книге на С++ (четвертое издание) заключается в том, что мы должны использовать отдельные пространства имен для интерфейсов и реализаций. Могут ли более опытные люди сказать что-то на этом? Я имею в виду, это звучит неплохо, но действительно ли это практично, имеет ли смысл проекты в реальном мире?

4b9b3361

Ответ 1

Пространство имен сообщает вам о том, кому принадлежит определение. Конечно, имеет смысл, что интерфейс принадлежит другой группе, чем реализация; что вся точка интерфейса, разделение проблем.

Ответ 2

В коде, который очень тяжелый для реализации (скажем, некоторая метапрограммируемая чудовищность внутри Boost), может быть полезно сразу заметить, какой код вы, как ожидается, сможете использовать напрямую, и какой код вы можете безопасно игнорировать, Код в библиотеке detail namespace считается внутренним кодом, поэтому вам не нужно тратить время на поиск документации, когда вы видите символ detail в трассировке стека.

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

Ответ 3

это имеет смысл в реальных проектах?

Да, например, в 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 для меня: сложные детали, которые могут измениться и даже могут иметь смысл только для первоначальных сопровождающих. Но это прекрасно. Это не часть интерфейса.