设计模式SOLID

一:单一职责原则

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

class UserInfo
{ userId, username, email, telephone}

二:开闭原则

对扩展开放,对修改关闭

class Alert
{
    void check(errorCount, duration)
    {
        if(errorCount > COUNT)
            notifiction.notify();
        if(duration > DURATION)
            notification.notify();
    }
}

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

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

伪代码如下:

class AlertHandler
{//基类
    public:
        AlertHandler(AlertRule r, Notification n) : rule(r), notification(n)
        {
                    
        }
        void check() = 0;
        
    public:
        AlertRule rule;
        Notification notification;
};

Class ErrorCountHandler : public AlertHandler
{
    public:
        void check(ApiStateInfo info)
        {
             if(info.getErrorCount() > rule.errorCount )           
             {
                 notification.notify("errorCount error!")             
             }
        }
};

Class DurationHandler : public AlertHandler
{
    public:
        void check(ApiStateInfo info)
        {
             if(info.getDuration() > rule.duration )           
             {
                 notification.notify("duration error!")             
             }
        }
};
class Alert
{
    public:
        vector<Handler> alterHandlers;
        void addAlertHandler(AlertHandler handler)
        {
            alertHandlers.emplace_back(handler);        
        } 
        void check()
        {
            for(auto handler : alterHandlers)
            {//apiStateInfo为初始阈值
                 handler.check(apiStateInfo);              
            }        
        }   
}

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

Class TpsHandler : public AlertHandler
{
    public:
        void check(ApiStateInfo info)
        {
             if(info.tpsVal() > rule.tpsVal)           
             {
                 notification.notify("tpsValerror!")             
             }
        }
};

三:里氏替换原则

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

四:接口隔离原则

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

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

例:

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

class UserInfo
{
    void register(string cellphone, string passwd);
    void login(string cellphone, string passwd);
    void getUserInfoById(int userId);
}

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

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

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

class UserInfo
{
    void register(string cellphone, string passwd);
    void login(string cellphone, string passwd);
    void getUserInfoById(int userId);
}

class RetrictedUserService
{
    bool deleteUserById(int userId);
};

五:依赖反转原则

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 规范。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值