-
Notifications
You must be signed in to change notification settings - Fork 0
/
FactoryMethod.hpp
80 lines (70 loc) · 2.69 KB
/
FactoryMethod.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#pragma once
#ifndef _FACTORYMETHOD_HPP_
#define _FACTORYMETHOD_HPP_
#include <map>
#include <memory>
#include <string>
namespace ohtoai
{
// Base class, product registration template interface class
template <typename ProductType_t>
class IProductRegistrar
{
public:
virtual std::shared_ptr<ProductType_t> createProduct() = 0;
protected:
IProductRegistrar() = default;
virtual ~IProductRegistrar() = default;
IProductRegistrar(const IProductRegistrar&) = delete;
IProductRegistrar& operator=(const IProductRegistrar&) = delete;
};
// Factory template class for getting and registering product objects
template <typename ProductType_t>
class ProductFactory
{
public:
static ProductFactory<ProductType_t>& instance()
{
static ProductFactory<ProductType_t> instance;
return instance;
}
// Product registration
void registerProduct(IProductRegistrar<ProductType_t>* registrar, std::string name)
{
productRegistry_.emplace(name, registrar);
}
// Based on the name, get the corresponding specific product object
std::shared_ptr<ProductType_t> product(std::string name)
{
if (productRegistry_.find(name) != productRegistry_.end())
return productRegistry_.at(name)->createProduct();
else
return nullptr;
}
protected:
ProductFactory() = default;
~ProductFactory() = default;
ProductFactory(const ProductFactory&) = delete;
ProductFactory& operator=(const ProductFactory&) = delete;
// Save the registered products. Key: product name, value: product type
std::map<std::string, IProductRegistrar<ProductType_t>*> productRegistry_;
};
// Product Registration template class for creating concrete products and registering products from the factory
template <typename ProductType_t, typename ProductImpl_t, typename = typename std::enable_if<std::is_base_of<ProductType_t, ProductImpl_t>::value>::type>
class ProductRegistrar : public IProductRegistrar<ProductType_t>
{
public:
// The constructor, used to register the product to the factory, can only show the call
explicit ProductRegistrar(std::string name)
{
// Register the product to the factory through the factory singleton
ProductFactory<ProductType_t>::instance().registerProduct(this, name);
}
// Create a pointer to a concrete product object
std::shared_ptr<ProductType_t> createProduct()
{
return std::make_shared<ProductImpl_t>();
}
};
}
#endif