带参数的反射工厂模式

带参数的反射工厂模式

    • 0.引言
    • 1.带参数的反射工厂模式
    • 2.完整代码

0.引言

普通的反射工厂模式无法传入参数,工厂为单例模式。

1.带参数的反射工厂模式

  • 工厂端
#ifndef _FACTORY_H_
#define _FACTORY_H_

#include 
#include 

class Factory {
 public:
  static Factory* Instance() {
    if (!factory_ptr_) factory_ptr_ = new Factory();
    return factory_ptr_;
  }

  template <typename Base, typename... Args>
  Base* New(const char* class_name, Args... args) {
    if (func_map_.count(class_name)) {
      using newer_type = Base* (*)(Args...);
      return reinterpret_cast<newer_type>(func_map_[class_name])(
          std::forward<Args>(args)...);
    }
    return nullptr;
  }

  unsigned Register(const char* class_name, void* newer) {
    if (class_name && newer) {
      func_map_[class_name] = newer;
    }
    return 0;
  }

 private:
  Factory() {}
  static Factory* factory_ptr_;
  std::unordered_map<std::string, void*> func_map_;
};

Factory* Factory::factory_ptr_ = nullptr;

template <typename T, typename... Args>
void* Newer(Args... args) {
  return new T(std::forward<Args>(args)...);
}

#define CONCAT(A, B) A##B
#define REGISTER(name, ...)                                               \
  static unsigned CONCAT(name, __LINE__) = Factory::Instance()->Register( \
      #name, (void*)(&Newer<name, ##__VA_ARGS__>));

#endif  // _FACTORY_H_
  • 接口端
class Message {
 public:
  virtual std::string ToString() = 0;
  virtual ~Message() {}
};

  • 子类算法端
class Request : public Message {
 public:
  Request(const std::string& msg) : msg_(msg) {}
  std::string ToString() override { return msg_ + "Request"; }

 private:
  std::string msg_;
};

class Response : public Message {
 public:
  Response() : code_(200) {}
  Response(std::uint32_t code) : code_(code) {}

  std::string ToString() override { return std::to_string(code_) + "Response"; }

 private:
  std::uint32_t code_;
};

REGISTER(Request, std::string);
REGISTER(Response, std::uint32_t);
  • 客户端:只需要包含接口端和工厂端即可,不许知道内部如何实现。
int main() {
  auto request = Factory::Instance()->New<Message, std::string>("Request", "123");
  auto response = Factory::Instance()->New<Message, std::uint32_t>("Response", 123);

  std::cout << request->ToString() << std::endl;
  std::cout << response->ToString() << std::endl;

  return 0;
}

2.完整代码

#include "reflect_factory.h"

#include 

class Message {
 public:
  virtual std::string ToString() = 0;
  virtual ~Message() {}
};

class Request : public Message {
 public:
  Request(const std::string& msg) : msg_(msg) {}
  std::string ToString() override { return msg_ + "Request"; }

 private:
  std::string msg_;
};

class Response : public Message {
 public:
  Response() : code_(200) {}
  Response(std::uint32_t code) : code_(code) {}

  std::string ToString() override { return std::to_string(code_) + "Response"; }

 private:
  std::uint32_t code_;
};

REGISTER(Request, std::string);
REGISTER(Response, std::uint32_t);

int main() {
  auto request = Factory::Instance()->New<Message, std::string>("Request", "123");
  auto response = Factory::Instance()->New<Message, std::uint32_t>("Response", 123);

  std::cout << request->ToString() << std::endl;
  std::cout << response->ToString() << std::endl;

  return 0;
}
#ifndef _FACTORY_H_
#define _FACTORY_H_

#include 
#include 

class Factory {
 public:
  static Factory* Instance() {
    if (!factory_ptr_) factory_ptr_ = new Factory();
    return factory_ptr_;
  }

  template <typename Base, typename... Args>
  Base* New(const char* class_name, Args... args) {
    if (func_map_.count(class_name)) {
      using newer_type = Base* (*)(Args...);
      return reinterpret_cast<newer_type>(func_map_[class_name])(
          std::forward<Args>(args)...);
    }
    return nullptr;
  }

  unsigned Register(const char* class_name, void* newer) {
    if (class_name && newer) {
      func_map_[class_name] = newer;
    }
    return 0;
  }

 private:
  Factory() {}
  static Factory* factory_ptr_;
  std::unordered_map<std::string, void*> func_map_;
};

Factory* Factory::factory_ptr_ = nullptr;

template <typename T, typename... Args>
void* Newer(Args... args) {
  return new T(std::forward<Args>(args)...);
}

#define CONCAT(A, B) A##B
#define REGISTER(name, ...)                                               \
  static unsigned CONCAT(name, __LINE__) = Factory::Instance()->Register( \
      #name, (void*)(&Newer<name, ##__VA_ARGS__>));

#endif  // _FACTORY_H_

你可能感兴趣的:(编程技能,#,设计模式,单例模式,简单工厂模式,c++,反射工厂,带参数的反射工厂)