Named Constructor Idiom



Конструкторы - вещь хорошая, но довольно ограниченная. Если вы хотите создать объект класса ТяжеленнаяФиговина, то логично было бы ввести разные конструкторы для разных систем измерения. Ну например, чтобы фиговина могла создаваться из киллограммов и из фунтов. Но это невозможно.



Дело в том, что конструктор класса - такая же функция, как и все остальные. У него есть имя(имя класса), список аргументов(включая неявный this) и пустое возвращаемое значение. В языке С++ конструкторы вообще ничего не возвращают, но они так или иначе реализованы на обычных ассемблерных функциях, а они имеют все эти обязательные характеристики.



А раз это функция и неизменяемым именем, то различать разные конструкторы мы можем только с помощью разного списка параметров.



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



Допустим, что с фиговиной помогут справиться strong typedefs. Но со сложностью различий конструкторов для пользователя они не помогут. А вот что может помочь.



Named Constructor Idiom. Давайте дадим имена конструкторам!



Точнее мы немного схитрим. Добавим именные статические функции-фабрики, которые и будут конструировать наши объекты, и переместим все конструкторы в private секцию.



Покажу на примере фиговины, чтобы было по-проще и по-короче



struct HeavyThing {

static HeavyThing ConstructFromKilos(float kilos) {

return HeavyThing(kilos);

}

static HeavyThing ConstructFromPounds(float pounds) {

return HeavyThing(0,453592 * pounds);

}

private:

HeavyThing(float kilos) : kilos_{kilos} {}



float kilos_;

};



int main() {

HeavyThing a = HeavyThing::ConstructFromKilos(100500.0);

HeavyThing b = HeavyThing::ConstructFromPounds(12345678.0);

}





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



Make convenient interfaces. Stay cool.



#design