• 设计模式SOLID


    一:单一职责原则

    一个类或者一个模块只完成一个功能

    1. class UserInfo
    2. { userId, username, email, telephone}

    二:开闭原则

    对扩展开放,对修改关闭

    1. class Alert
    2. {
    3. void check(errorCount, duration)
    4. {
    5. if(errorCount > COUNT)
    6. notifiction.notify();
    7. if(duration > DURATION)
    8. notification.notify();
    9. }
    10. }

    此时如果要增加一个tps峰值检测,就需要在Alert中添加,其次check的调用入参也需要更改,不符合“对修改关闭”的原则

    可以这样:把errorCout和duration封装为class handler的子类,Alert中增加一个vector 数组,check()中轮询vector中数据,调用各handler子类的函数

    伪代码如下:

    1. class AlertHandler
    2. {//基类
    3. public:
    4. AlertHandler(AlertRule r, Notification n) : rule(r), notification(n)
    5. {
    6. }
    7. void check() = 0;
    8. public:
    9. AlertRule rule;
    10. Notification notification;
    11. };
    12. Class ErrorCountHandler : public AlertHandler
    13. {
    14. public:
    15. void check(ApiStateInfo info)
    16. {
    17. if(info.getErrorCount() > rule.errorCount )
    18. {
    19. notification.notify("errorCount error!")
    20. }
    21. }
    22. };
    23. Class DurationHandler : public AlertHandler
    24. {
    25. public:
    26. void check(ApiStateInfo info)
    27. {
    28. if(info.getDuration() > rule.duration )
    29. {
    30. notification.notify("duration error!")
    31. }
    32. }
    33. };
    34. class Alert
    35. {
    36. public:
    37. vector alterHandlers;
    38. void addAlertHandler(AlertHandler handler)
    39. {
    40. alertHandlers.emplace_back(handler);
    41. }
    42. void check()
    43. {
    44. for(auto handler : alterHandlers)
    45. {//apiStateInfo为初始阈值
    46. handler.check(apiStateInfo);
    47. }
    48. }
    49. }

    此时再新增一个告警监测只要继承AlertHandler,实现自己的check(),把TpsHandler 添加到Alert的vector即可,没有损坏原有结构,如下

    1. Class TpsHandler : public AlertHandler
    2. {
    3. public:
    4. void check(ApiStateInfo info)
    5. {
    6. if(info.tpsVal() > rule.tpsVal)
    7. {
    8. notification.notify("tpsValerror!")
    9. }
    10. }
    11. };

    三:里氏替换原则

    子类对象能够替换程序中的父类对象出现的任何地方,并且保证程序原有的逻辑不变以及正确性不被破坏

    四:接口隔离原则

    Clients should not be forced to depend upon interfaces that they do not use.

    不应该强迫客户端去依赖它不需要的接口。 客户端是指接口调用者或使用者

    例:

    微服务用户系统提供了一组用户相关的API,如注册,登录,获取用户信息等,

    1. class UserInfo
    2. {
    3. void register(string cellphone, string passwd);
    4. void login(string cellphone, string passwd);
    5. void getUserInfoById(int userId);
    6. }

    此时,后台管理系统要实现删除用户的功能,如果直接在上面UserInfo中添加deleteUserById(),会造成以下两点

    1. 会造成误删(应该在架构层面避免这种情况,而不是把权限放给用户)
    2. 用户并不需要删除用户的接口,违背了接口隔离原则

    应该把删除用户的接口单独封装,只提供给需要它的后台管理系统

    1. class UserInfo
    2. {
    3. void register(string cellphone, string passwd);
    4. void login(string cellphone, string passwd);
    5. void getUserInfoById(int userId);
    6. }
    7. class RetrictedUserService
    8. {
    9. bool deleteUserById(int userId);
    10. };

    五:依赖反转原则

    High-level modules shouldn’t depend on low-level modules. Both modules should depend on abstractions. In addition, abstractions shouldn’t depend on details. Details depend on abstractions.

    我们将它翻译成中文,大概意思就是:高层模块(high-level modules)不要依赖低层模块(low-level)。高层模块和低层模块应该通过抽象(abstractions)来互相依赖。除此之外,抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions)。

    例:

    Tomcat 是运行 Java Web 应用程序的容器。我们编写的 Web 应用程序代码只需要部署在 Tomcat 容器下,便可以被 Tomcat 容器调用执行。按照之前的划分原则,Tomcat 就是高层模块,我们编写的 Web 应用程序代码就是低层模块。Tomcat 和应用程序代码之间并没有直接的依赖关系,两者都依赖同一个“抽象”,也就是 Sevlet 规范。Servlet 规范不依赖具体的 Tomcat 容器和应用程序的实现细节,而 Tomcat 容器和应用程序依赖 Servlet 规范。

  • 相关阅读:
    vben-admin 学习记录
    ChatGPT + Flutter快速开发多端聊天机器人App
    【C++】C/C++内存管理
    【物理应用】基于粒子群优化算法实现瞬变电磁法视电阻率反演附matlab代码
    Linux 服务器运维管理面板1Panel体验
    pytorch-lightning的trainer的optimaze_step的详细分析
    CMake中string的使用
    突遇暴雨,怎样远程连接服务器
    IIoT(智能物联网)的现状、应用及安全
    前馈-反馈控制系统设计(过程控制课程设计matlab/simulink)
  • 原文地址:https://blog.csdn.net/yuhuqiao/article/details/126489271