入门设计原则C++实现五:依赖倒置原则

高层次的模块不要依赖低层次的模块,二者都应该依赖于其抽象

抽象不应该依赖于具体,而是具体应该依赖于抽象

为了更好理解该原则,首先明确以下概念:

  • 高层次模块:也叫上层代码,一般可以认为是调用方(客户端)。以系统三层结构(表示层,业务逻辑层,数据访问层)为例子,表示层相对于业务逻辑层来说,就是高层;业务逻辑层相对于数据访问层来说就是高层;

  • 底层次模块:也叫作下层代码,一般可以认为是被调用方(提供服务的一方)。如上例子,业务逻辑层相对于表示层来说,就是底层;数据访问层相对于业务逻辑层来说,就是底层。

  • 抽象:设计原则/模式中的抽象可以理解为约束/规范,代码中表现为接口/抽象类

  • 具体:抽象的具体化,代码中表现为实现类/抽象类的派生

比如:鱼类和鸟类是具体类,动物类是抽象类;游泳类和飞行类是具体类 ,行为类是抽象类;App端签到类和PC端签到类是具体类,签到行为类是抽象类。

系统三层结构:https://blog.csdn.net/weixin_28683065/article/details/119067965

考虑以下案例:实现一个多终端(App、PC、…)签到的系统

实例1:

#include <iostream>

class AppClient
{
public:
    void signIn() {
        std::cout<<"App签到成功!"<<std::endl;
    }
};

class PCClient
{
public:
    void signIn() {
        std::cout<<"PC签到成功!"<<std::endl;
    }
};

class User
{
public:
    void signInApp(AppClient* client) {
        client->signIn();
    }
    void signInPC(PCClient* client) {
        client->signIn();
    }
};

class App
{
public:
    void appRun() {
        User* user = new User;
        user->signInApp(new AppClient);
        user->signInPC(new PCClient);
    }
};

int main() {
    App app;
    app.appRun();
    return 1;
}

上述实例中,AppClient类、PCClient类、User类、App类都是具体类,没有抽象;按照层次划分,AppClient和PCClient类相对于User类是低层次类,User类相对于App类是低层次类。

存在的缺点为:

  • App类(高)需要调用User类(低)的方法实现不同签到,如果User类更改(增加或者删除)某些签到方法,App类中也要做响应的更改。此时App类严重依赖User类,违反了原则中的 [高层次的模块不要依赖低层次的模块]

  • 同时,本实例中App具体类依赖User具体类;User具体类依赖AppClient/PCClient具体类,没有抽象类的设计,违反了 [而是具体应该依赖于抽象]

  • User类需求变动时,比如添加了小程序签到,User类就必须变更添加小程序签到的方法。同时违反了开闭原则中的[对拓展开放,对修改关闭]原则

开闭原则见:。。。。。。。

因此对上述代码依照设计原则进行修改,将不同的具体签到方式抽象为签到接口类,让User类不再依赖具体的AppClient和PCClient类,而是依赖抽象接口类(签到接口类);同时期望User类是稳定地,不会因为签到方法的增多而改变User代码,实现高层次代码不依赖低层次代码。

示例2:

#include <iostream>

//接口类
class ISign {
public:
    virtual void signIn() = 0; //纯虚函数
};

//具体依赖抽象
class AppClient : public ISign {
public:
    virtual void signIn() override {
        std::cout<<"App签到成功!"<<std::endl;
    }
};

class PCClient : public ISign  {
public:
    virtual void signIn() override {
        std::cout<<"PC签到成功!"<<std::endl;
    }
};
//add new function 
class WechatClient : public ISign  {
public:
    virtual void signIn() override {
        std::cout<<"Wechat签到成功!"<<std::endl;
    }
};

//稳定点: 高层模块不依赖低层次的模块,二者依赖抽象
//增加新的签到方法时,不影响User类
class User {
public:
    void signIn(ISign* sign) {
        sign->signIn();
    }
};

class App
{
public:
    void appRun() {
        User* user = new User;
        ISign* signPC = new PCClient;
        ISign* signApp = new AppClient;
        //add new function 
        ISign* signWeChat = new WechatClient;

        user->signIn(signApp);
        user->signIn(signApp);
        user->signIn(signPC);
        
        //add new function 
        user->signIn(signWeChat);
        user->signIn(signWeChat);
    }
};

int main() {
    App app;
    app.appRun();
    return 1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值