Factory Method II
Description:
Example:
Note
Idea:
User可以直接往engine factory里加入可用的engine,然后就不用修改engine factor的code了。非常炫酷。
注意定义的顺序,有些必须那样。
Code:
Method 1 engine factory里有很多static members。
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
class CalcEngine{
public:
CalcEngine()=default;
virtual ~CalcEngine()=default;
virtual int run(const vector<int> &)=0;
};
class Multiplier: public CalcEngine{
public:
Multiplier();
int run(const vector<int> & nums) override{
int result=0;
for(auto e: nums){
result += e;
}
return result;
}
};
class EngineFactory{
public:
static CalcEngine * newCalcEngine(const string& engine_name){
if(engine_dict_.find(engine_name)==engine_dict_.end()) return nullptr;
else return engine_dict_[engine_name];
}
static void setEngineDict(string engine_name, CalcEngine& engine_obj){
cout<<"Set engine: "<<engine_name<<endl;
engine_dict_[engine_name] = &engine_obj;
}
static void listEngines(){
cout<<"Engine list:\n";
for(auto e: engine_dict_){
cout<<e.first<<endl;
}
}
private:
EngineFactory(){}
EngineFactory(const EngineFactory &);
~EngineFactory(){}
static unordered_map<string, CalcEngine *> engine_dict_;
};
// Initialize static variable hash_map as empty
unordered_map<string, CalcEngine *> EngineFactory::engine_dict_;
// 这个顺序! after class Multiplier and EngineFactory
Multiplier multiplier_obj;
Multiplier::Multiplier(){
EngineFactory::setEngineDict("multiplier", multiplier_obj);
}
int main(){
string engine_name="multiplier";
vector<int> nums={1, 2, 3, 4};
CalcEngine * engine_ptr = EngineFactory::newCalcEngine(engine_name);
if(engine_ptr!=nullptr)
cout<<engine_ptr->run(nums)<<endl;
EngineFactory::listEngines();
}
Method 2 engine factory用singleton design。避免用很多的static members。
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
class CalcEngine{
public:
CalcEngine()=default;
virtual ~CalcEngine()=default;
virtual int run(const vector<int> &)=0;
};
class Multiplier: public CalcEngine{
public:
Multiplier();
int run(const vector<int> & nums) override{
int result=0;
for(auto e: nums){
result += e;
}
return result;
}
};
class EngineFactory{
public:
CalcEngine * newCalcEngine(const string& engine_name){
if(engine_dict_.find(engine_name)==engine_dict_.end()) return nullptr;
else return engine_dict_[engine_name];
}
void setEngineDict(string engine_name, CalcEngine& engine_obj){
cout<<"Set engine: "<<engine_name<<endl;
engine_dict_[engine_name] = &engine_obj;
}
void listEngines(){
cout<<"Engine list:\n";
for(auto e: engine_dict_){
cout<<e.first<<endl;
}
}
static EngineFactory * getInstance(){
if(instance_ptr_==nullptr){
instance_ptr_=new EngineFactory();
}
return instance_ptr_;
}
private:
EngineFactory(){}
EngineFactory(const EngineFactory &);
~EngineFactory(){}
unordered_map<string, CalcEngine *> engine_dict_;
static EngineFactory * instance_ptr_;
};
EngineFactory * EngineFactory::instance_ptr_=nullptr;
Multiplier multiplier_obj;
Multiplier::Multiplier(){
EngineFactory::getInstance()->setEngineDict("multiplier", multiplier_obj);
}
int main(){
string engine_name="multiplier";
vector<int> nums={1, 2, 3, 4};
CalcEngine * engine_ptr = EngineFactory::getInstance()->newCalcEngine(engine_name);
if(engine_ptr!=nullptr)
cout<<engine_ptr->run(nums)<<endl;
EngineFactory::getInstance()->listEngines();
}