Конструктор объекта "настройки" идиома - PullRequest
2 голосов
/ 28 октября 2011

Я помню, как читал некоторое время назад об идиоме конструктора для C ++ в случаях сложных конфигураций объектов. Это особенно полезно, поскольку помогает включить RAII для некоторых неприятных концепций, которые имеют way слишком много (часто конфликтующих) опций.

Вот простой пример. Предположим, вы написали класс-оболочку для окон Win32 API. Чтобы инициализировать окно, вам нужно знать стили окна, расширенные стили окна, начальное расположение окна, начальный размер окна и т. Д. Среди стилей окна множество параметров конфликтуют и не могут быть установлены вместе. Помещение всех этих методов в класс Window является запретительным и препятствует определению правильных инвариантов класса. Использование временного объекта для группировки всех значений параметров может помочь предотвратить невозможные конфигурации и определить хороший инвариант для класса Window (например, он всегда содержит действительный дескриптор окна).

class Settings
{
    ::DWORD myBasicStyles;     // takes lots of different flags.
    ::DWORD myExtentedStyles;  // even more flags.
    ::POINT myInitialLocation;
    ::SIZE myInitialSize;
    // lots more...
public:
    void setInitialPosition ( int x, int y );
    void setInitialSize ( int top, int left );
    void useSpecialBorder ();
    // lots more...
    void enableTransparency ();
    // lots more...
};

class Window
{
    ::HWND handle;
public:
    // map settings unto the horrible list of many parameters expected
    // by "CreateWindowEx()", then invoke it to allocate the resource.
    Window ( const Settings& settings );
};

// calling code.
int main ()
{
    Settings settings;
    settings.setInitialPosition(0, 0);
    settings.setInitialSize(500, 300);
    settings.setInitiallyVisible(true);
    Window window(settings);
    // ... rest of application ...
}

Тем не менее, я не могу найти страницу, где я читаю это или даже имя, под которым оно было названо. Может кто-нибудь сказать мне, как это называется, и, возможно, ссылку на хороший ресурс по теме?

Ответы [ 3 ]

3 голосов
/ 28 октября 2011

Похоже на смесь вещей.

Объект Settings создается с Именом именованного параметра .Хотя обычно вы видите, что он возвращает ссылку на себя, чтобы вы могли связать их.

struct Builder {
  Builder &one(int val) { one_ = val_; return *this; }
  Builder &two(int val) { two_ = val_; return *this; }
  int one;
  int two;
};

void foo() {
  Builder builder().one(1).two(2);
}

Settings используется как Шаблон инкапсулированного контекста .Ссылка довольно многословна.Основная идея заключается в том, что вы просто вставляете свои аргументы в объект и передаете объект.

В некотором роде я считаю обидой идею о том, что она заключает в себе что-либо.Впрочем, это могут быть просто люди, переоценивающие значение слов.:)

1 голос
/ 28 октября 2011

Я нашел имя Имена именованных параметров в паутинах.Это немного отличается, но служит той же цели.

0 голосов
/ 28 октября 2011

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

Идея состоит в том, чтобы сгруппировать набор связанных данных вместе с объектом, который несет все эти данные. Стоит обратить эти параметры в объект, потому что:

  • Уменьшает размер списков параметров, а длинные списки параметров трудно понять.
  • Определенные методы доступа в новом объекте также делают код более согласованным, что снова облегчает понимание.
  • Что еще более важно, это помогает вам идентифицировать эти общие поведения в этом наборе данных, чтобы вы могли перейти в новый класс. Перемещая это поведение в новый объект, вы можете идентифицировать дублированный код и удалить их. Кроме того, у вас есть хорошая инкапсуляция данных. После изменения выполнения какой-либо операции над данными остается только одно место для изменения, и клиенты не затрагиваются.
...