戒赌网站怎么做,网络培训心得体会,石家庄网络推广的优势,软件工程课程设计题目工厂方法模式的瑕疵 在前一篇笔记中我们介绍了工厂方法模式#xff0c;示例的类图如下#xff1a; 考虑一种情况#xff1a;现在要在程序运行时#xff0c;根据外部资源#xff0c;动态的实例化对象。也就是说在编译期我们无法知道要实例化的对象的类型。因此在实例化的过…工厂方法模式的瑕疵 在前一篇笔记中我们介绍了工厂方法模式示例的类图如下 考虑一种情况现在要在程序运行时根据外部资源动态的实例化对象。也就是说在编译期我们无法知道要实例化的对象的类型。因此在实例化的过程中就需要加以判断。 例如在我的例子中要根据连接到主机的相机来实例化相机对象那么客户端使用工厂方法创建实例的一方使用工厂方法模式创建对象的时候代码可能是这样
//运行时确定数组大小且确定后不可改变
auto camera_devices_ std::make_uniquestd::shared_ptrCameraDevice[](onlined_camera_num_);for(int i 0; i onlined_camera_num_; i)
{std::shared_ptrCameraDeviceFactory factory;if(Sick camera_name[i]) //camera_name[i]中元素是提前获取的与连接的相机对应的供应商名称factory std::make_sharedSickCameraFactory();else if(Basler camera_name[i])factory std::make_sharedBaslerCameraFactory();else if(Huaray camera_name[i])factory std::make_sharedHuarayCameraFactory();camera_devices_[i] factory-CreateCamera();
} 虽然工厂方法模式遵循了开闭原则即当有新类型的时候无需修改现有的代码只需新加产品类和对应工厂类即可。但是对于客户端来说当需要实例化的类型数量增加时就需要新增else if去适配这使得客户端代码变得冗长且难以维护。 注册表 为了解决上面问题我们可以实现一个类型的注册表允许动态创建对象。这种方法通过将关键字映射到构造函数指针使得可以根据字符串名称动态地实例化对象。
#ifndef Reflection_H
#define Reflection_H#include map
#include stringtemplate typename T, typename... ArgType
void* CreateInstance(ArgType... args)
{return new T(args...);
}//需要反射的类使用该宏注册
#ifndef ReflectRegister
#define ReflectRegister(identifier, class_name, ...) \static bool __type##class_name Object::Register(identifier, (void*)CreateInstanceclass_name, ##__VA_ARGS__);
#endifclass Object
{
public:template typename BaseClass, typename... ArgTypestatic BaseClass *CreateObject(const std::string vendor_name, ArgType... args){using CreateFactory BaseClass *(*)(ArgType...);auto class_map GetStaticFuncMap();auto iter class_map.find(vendor_name);if (iter class_map.end()){CRRC_ERROR(class_name not found in map);return nullptr;}else{CRRC_DEBUG(class_name found in map);return reinterpret_castCreateFactory(class_map[vendor_name])(args...);}} //向map中注册关键字和类的构造函数static bool Register(const std::string vendor_name, void *ctor_ptr){CRRC_DEBUG(Register class_name:vendor_name);GetStaticFuncMap()[vendor_name] ctor_ptr;return true;}private://获取全局唯一的map//map记录了关键字和类的构造函数的映射关系static std::mapstd::string, void* GetStaticFuncMap(){static std::mapstd::string, void* class_map_;return class_map_;}};#endif //Reflection_H 在具体相机工厂中我们可以使用ReflectRegister注册此类以Basler相机为例其余类似
class BaslerCameraDeviceFactory : public CameraDeviceFactory
{
public:std::shared_ptrCameraDevice CreateCameraDevice() override{return std::make_sharedBaslerCameraDevice();}
};ReflectRegister(Basler, BaslerCameraDeviceFactory); 好了现在回头再看客户端使用工厂方法模式创建对象的代码就可以简化为
//运行时确定数组大小且确定后不可改变
auto camera_devices_ std::make_uniquestd::shared_ptrCameraDevice[](onlined_camera_num_);for(int i 0; i onlined_camera_num_; i)
{auto p_factory Object::CreateObjectCameraDeviceFactory(camera_name[i]);//camera_name[i]中元素是提前获取的与连接的相机对应的供应商名称if (!p_factory)continue;elsecamera_devices_[i] p_factory-CreateCameraDevice();delete p_factory;
} 文章转载自paw5zx 原文链接https://www.cnblogs.com/paw5zx/p/18229334 体验地址引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构