Отделение общедоступного интерфейса от деталей реализации

#c

#c

Вопрос:

Мне нужно разработать Font класс, который будет иметь несколько реализаций, охватывающих платформы или разные библиотеки (например, Win32 GDI или FreeType). Таким образом, по сути, будет один общий файл заголовка / интерфейса и несколько реализаций .cpp (выбираемых во время сборки). Я бы предпочел сохранить общедоступный интерфейс (файл заголовка) чистым от любых деталей реализации, но обычно этого трудно достичь. Объект шрифта должен перетаскивать какое-то частное состояние — например, дескриптор в GDI или внешний объект FreeType внутри.

Каков наилучший способ отслеживания деталей частной реализации в C ? Должен ли я использовать статические данные в файлах реализации?

Редактировать: Нашел эту замечательную статью на тему: Разделение интерфейса и реализации в C .

p.s. Я помню, что в Objective-C есть закрытые категории, которые позволяют вам определять расширение класса в вашем частном файле реализации, что делает решение довольно элегантным.

Ответ №1:

Вы можете использовать шаблон проектирования PIMPL.

По сути, здесь ваш объект содержит указатель на фактическую часть, зависящую от платформы, и передает все вызовы, зависящие от платформы, этому объекту.

Font.h

 class FontPlatform;
class Font
{
   public:
       Font();
       void Stuff();
       void StuffPlatform();
   private:
       FontPlatform*  plat;
};
  

Font.cpp

 #include "Font.h"
#if Win
#include "FontWindows.h"
#else
#error "Not implemented on non Win platforms"
#endif

Font::Font()
  : plat(new PLATFORM_SPCIFIC_FONT)  // DO this cleaner by usin& factory.
{}

void Font::Stuff()  { /* DoStuff */ }
void Font::StuffPlatform()
{
    plat-&&t;doStuffPlat();  // Call the platform specific code.
}
  

Комментарии:

1. Преимущество pimpl в том, что классы реализации могут быть полиморфными (это имеет название в религии шаблонов проектирования iirc). Итак, действительно, вы можете использовать фабрики, вы также можете выбрать реализацию во время выполнения, если вам нужно (для размещения, например. Варианты ОС).