В последнее время я пытался лучше понять, как использовать Factory Pattern в C ++.
Я ознакомился со следующими ресурсами:
Как реализовать фабрикушаблон метода в C ++ правильно
https://www.geeksforgeeks.org/design-patterns-set-2-factory-method/
https://sourcemaking.com/design_patterns/factory_method/cpp/1
https://www.codeproject.com/Articles/363338/Factory-Pattern-in-Cplusplus
https://www.bogotobogo.com/DesignPatterns/factorymethod.php
https://gist.github.com/pazdera/1099562
https://en.wikibooks.org/wiki/C%2B%2B_Programming/Code/Design_Patterns
Прежде чем кто-то пометит это как "не вопрос", у меня есть несколько явных вопросов, которые я скоро получу.Но чтобы прояснить мое понимание, сначала я хотел бы начать с примера.Это лучший пример, который я смог сделать из информации, представленной в приведенных выше ссылках (наилучшее значение иллюстрирует шаблон фабрики, но он настолько прост, насколько это возможно, поэтому новички в этом шаблоне могут ясно видеть связанные с этим проблемы):
// FactoryPattern.cpp
#include <iostream>
#include <vector>
enum AnimalSpecies { dog, cat };
class Animal
{
public:
virtual void makeSound() = 0;
};
class Dog : public Animal
{
public:
void makeSound() { std::cout << "woof" << "\n\n"; }
};
class Cat : public Animal
{
public:
void makeSound() { std::cout << "meow" << "\n\n"; }
};
class AnimalFactory
{
public:
static Animal* makeAnimal(AnimalSpecies animalSpecies);
};
Animal* AnimalFactory::makeAnimal(AnimalSpecies animalSpecies)
{
if (animalSpecies == AnimalSpecies::dog)
{
return(new Dog());
}
else if (animalSpecies == AnimalSpecies::cat)
{
return(new Cat());
}
else
{
std::cout << "error in AnimalFactory::makeAnimal(), animalSpecies = " << animalSpecies << " does not seem to be valid" << "\n\n";
return(nullptr);
}
}
int main(void)
{
std::vector<Animal*> animals;
animals.push_back(AnimalFactory::makeAnimal(AnimalSpecies::dog));
animals.push_back(AnimalFactory::makeAnimal(AnimalSpecies::cat));
for (auto &animal : animals)
{
animal->makeSound();
}
for (auto& animal : animals)
{
delete(animal);
}
return(0);
}
Вывод этой программы (как и предполагалось):
woof
meow
Вот мои вопросы на данный момент:
1) Некоторые из прочитанных мною наФабричный шаблон привел меня к убеждению, что устранение утверждений является частью выгоды.Вышеприведенный пример не подходит в этом отношении, поскольку в AnimalFactory::makeAnimal()
для определения вида необходимо использовать if-else
.Есть ли способ реорганизовать это для удаления операторов if?
2) В последнее время с различными изменениями и улучшениями в C ++ 14/17/20 многие из нас уходят от указателей, чтобы избежать возможности утечек памяти,Есть ли способ изменить это так, чтобы не использовать указатели?
3) В чем преимущество Factory Pattern?т.е. в приведенном выше примере почему бы не опустить класс AnimalFactory
и просто сделать main()
следующим образом:
int main(void)
{
Dog dog;
dog.makeSound();
Cat cat;
cat.makeSound();
return(0);
}