bogolyubskiyalexey

hse seminar: factory

Sep 29th, 2020
633
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <map>
  5. using namespace std;
  6.  
  7. class Human {
  8. protected:
  9.     std::string name;
  10.     std::string place;
  11.    
  12. public:
  13.     Human() = default;
  14.     Human(const std::string& _name, const std::string& _place):
  15.         name(_name),
  16.         place(_place)
  17.         {}
  18.    
  19.     virtual void print_info() const = 0;
  20.    
  21. };
  22.  
  23. class Student : public Human {
  24. public:
  25.     Student(const std::string& _name, const std::string& _university):
  26.         Human(_name, _university) {}
  27.    
  28.     void print_info() const override {
  29.         std::cout << name << " studies at " << place << '\n';
  30.     }  
  31. };
  32.  
  33.  
  34. class Teacher : public Human {
  35. public:
  36.     Teacher(const std::string& _name, const std::string& _school):
  37.         Human(_name, _school) { }
  38.        
  39.     void print_info() const override {
  40.         std::cout << name << " teaches at " << place << "\n";
  41.     }
  42. };
  43.  
  44. class Programmer : public Human {
  45. public:
  46.     Programmer(const std::string& _name, const std::string& _company):
  47.         Human(_name, _company) {}
  48.    
  49.     void print_info() const override {
  50.         std::cout << name << " works at " << place << "\n";
  51.     }
  52. };
  53.  
  54.  
  55. enum class HumanType {
  56.     student,
  57.     teacher,
  58.     programmer
  59. };
  60.  
  61.  
  62.  
  63. class FactoryElementCreator {
  64. public:
  65.     virtual Human* create(
  66.         const std::string& name,
  67.         const std::string& organization
  68.     ) = 0;
  69. };
  70.  
  71. class StudentCreator : public FactoryElementCreator{
  72. public:
  73.     Human* create(
  74.         const std::string& name,
  75.         const std::string& organization
  76.     ) override {
  77.         return new Student(name, organization);
  78.     }
  79. };
  80.  
  81.  
  82.  
  83. class HumanFactory {
  84. private:
  85.     map<HumanType, FactoryElementCreator*> creators;
  86. public:
  87.     template <class T>
  88.     void add(HumanType type) {
  89.         if (creators.count(type)) {
  90.             throw invalid_argument("type already added");
  91.         }
  92.         creators[type] = new T();
  93.     }
  94.     Human* create(
  95.         HumanType type,
  96.         const std::string& name,
  97.         const std::string& organization
  98.     ) {
  99.         auto it = creators.find(type);
  100.         if (it == creators.end()) {
  101.             return nullptr;
  102.         }
  103.         return it->second->create(name, organization);
  104.     }
  105.     ~HumanFactory() {
  106.         for (auto& [type, ptr] : creators) {
  107.             delete ptr;
  108.         }
  109.     }
  110. };
  111.  
  112.  
  113.  
  114.  
  115. int main() {
  116.     HumanFactory factory;
  117.     factory.add<StudentCreator>(HumanType::student);
  118.  
  119.     auto ptr = factory.create(HumanType::student, "Alex", "HSE");
  120.     if (ptr) {
  121.         ptr->print_info();
  122.     } else {
  123.         std::cout << "not created" << std::endl;
  124.     }
  125.     auto ptr2 = factory.create(HumanType::teacher, "Alex2", "HSE");
  126.     if (ptr2) {
  127.         ptr2->print_info();
  128.     } else {
  129.         std::cout << "not created" << std::endl;
  130.     }
  131.  
  132.     delete ptr;
  133.     delete ptr2;
  134.  
  135. }
RAW Paste Data