计划模式学习(二)工厂模式——抽象工厂模式+注册表 ...

打印 上一主题 下一主题

主题 537|帖子 537|积分 1611

前言

在上一篇文章中我们提到了抽象工厂模式初版代码的一些缺点:①客户端违反开闭原则②提供方违反开闭原则。本文将针对这两点进行讨论
使用简单工厂改进

对于缺点①,我们可以使用简单工厂的思路来改进抽象工厂的初版代码。对于上一篇文章中的例子,我们去除CameraFactory、BaslerCameraFactory和SickCameraFactory,取而代之的是SimpleFactory类。
类图如下:

代码如下:
  1. //工厂类
  2. class SimpleFactory
  3. {
  4. public:
  5.     BaslerCamera* CreateBaslerCamera()
  6.     {
  7.         if ("Linux" == os_name_)
  8.         {
  9.             return new LinuxBaslerCamera();
  10.         }
  11.         else if ("Windows" == os_name_)
  12.         {
  13.             return new WindowsBaslerCamera();
  14.         }
  15.         else
  16.         {
  17.             return nullptr;
  18.         }
  19.     }
  20.     SickCamera* CreateSickCamera()
  21.     {
  22.         if ("Linux" == os_name_)
  23.         {
  24.             return new LinuxSickCamera();
  25.         }
  26.         else if ("Windows" == os_name_)
  27.         {
  28.             return new WindowsSickCamera();
  29.         }
  30.         else
  31.         {
  32.             return nullptr;
  33.         }
  34.     }
  35. public:
  36.     std::string os_name_ = "Linux";
  37. };
  38. //客户端
  39. int main()
  40. {
  41.     SimpleFactory* camera_factory = new SimpleFactory();
  42.    
  43.     BaslerCamera* basler_camera = camera_factory->CreateBaslerCamera();
  44.     basler_camera->OpenCamera();
  45.     SickCamera* sick_camera = camera_factory->CreateSickCamera();
  46.     sick_camera->OpenCamera();
  47.     return 0;
  48. }
复制代码
留意,上述方法固然改进了缺点①,但是缺点②仍存在。
使用注册表改进

对于缺点②,其本质是:增加新产物时,对工厂类带来的修改违反了开闭原则。对于这种情况,我们可以参考《计划模式学习(二)工厂模式——工厂方法模式+注册表》中提到的注册表,来去除switch或if这种分支判断,排除分支判断带来的耦合。
对于详细产物,我们可以这样将它注册:
  1. class LinuxBaslerCamera : public BaslerCamera
  2. {
  3. public:
  4.     ~LinuxBaslerCamera() override = default;
  5.     bool OpenCamera() override
  6.     {
  7.         return true;
  8.     }
  9. };
  10. ReflectRegister("LinuxBasler", LinuxBaslerCamera);
复制代码
然后工厂类的代码可以简化为:
  1. class SimpleFactory
  2. {
  3. public:
  4.     BaslerCamera* CreateBaslerCamera()
  5.     {
  6.         std::string name = os_name_ + "Basler";
  7.         return Object::CreateObject<BaslerCamera>(name);
  8.     }
  9.     SickCamera* CreateSickCamera()
  10.     {
  11.         std::string name = os_name_ + "Sick";
  12.         return Object::CreateObject<SickCamera>(name);
  13.     }
  14. public:
  15.     std::string os_name_ = "Linux";
  16. };
复制代码
这样,在产物族增加时(好比增加一个HarmonyOS),我们只必要在它下面的产物类对应的文件中使用ReflectRegister注册,然后改变os_name_即可(固然os_name_也可以在运行时从设置文件中加载,这样更好)。
而对于现有的产物族内增加新产物(好比增加一个Huaray相机),工厂类中还是要增加一个CreateHuarayCamera函数。
参考文章

1.《谎话计划模式》

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表