SOLID——组合复用原则

组合复用原则

组合复用原则(Composite Reuse Principle)强调在设计中优先使用对象组合而非类继承,以提高系统的灵活性和可维护性。它提倡通过组合对象来实现功能复用,避免因继承而导致的复杂类层次。

主要思想

  • 优先组合:在实现功能扩展时,应优先选择对象组合的方式,而不是通过继承创建新的子类。
  • 减少类的数量:通过组合可以减少系统中类的数量,从而降低复杂性。
  • 提高灵活性:动态组合功能使得系统能够适应变化,满足不同需求。

代码示例分析

以下是一个使用装饰模式实现的代码示例,展示了组合复用原则的应用。

#include <iostream>
using namespace std;

// 抽象控件类
class Control {
public:
    virtual void draw() = 0; // 绘制方法
    virtual ~Control() {}
};

// 列表控件类
class ListCtrl : public Control {
public:
    void draw() override {
        cout << "绘制普通的列表控件!" << endl;
    }
};

// 抽象装饰器类
class Decorator : public Control {
public:
    Decorator(Control* tmpctrl) : m_control(tmpctrl) {}
    void draw() override {
        m_control->draw(); // 调用被装饰控件的绘制方法
    }
private:
    Control* m_control;  // 组合控件
};

// 边框装饰器类
class BorderDec : public Decorator {
public:
    BorderDec(Control* tmpctrl) : Decorator(tmpctrl) {}
    void draw() override {
        Decorator::draw(); // 复用已有的绘制逻辑
        drawBorder(); // 添加边框绘制
    }
private:
    void drawBorder() {
        cout << "绘制边框!" << endl;
    }
};

// 垂直滚动条装饰器类
class VerScrollBarDec : public Decorator {
public:
    VerScrollBarDec(Control* tmpctrl) : Decorator(tmpctrl) {}
    void draw() override {
        Decorator::draw();
        drawVerScrollBar();
    }
private:
    void drawVerScrollBar() {
        cout << "绘制垂直滚动条!" << endl;
    }
};

// 水平滚动条装饰器类
class HorScrollBarDec : public Decorator {
public:
    HorScrollBarDec(Control* tmpctrl) : Decorator(tmpctrl) {}
    void draw() override {
        Decorator::draw();
        drawHorScrollBar();
    }
private:
    void drawHorScrollBar() {
        cout << "绘制水平滚动条!" << endl;
    }
};

int main() {
    // 创建带边框和垂直滚动条的列表控件
    Control* plistctrl = new ListCtrl();
    Decorator* plistctrl_b = new BorderDec(plistctrl);
    Decorator* plistctrl_b_v = new VerScrollBarDec(plistctrl_b);
    plistctrl_b_v->draw(); // 绘制

    cout << "-------------------------------" << endl;

    // 创建只带水平滚动条的列表控件
    Control* plistctrl2 = new ListCtrl();
    Decorator* plistctrl2_h = new HorScrollBarDec(plistctrl2);
    plistctrl2_h->draw(); // 绘制

    // 释放资源
    delete plistctrl_b_v;
    delete plistctrl_b;
    delete plistctrl;
    delete plistctrl2_h;
    delete plistctrl2;

    return 0;
}

组合复用原则体现

1. 组合而非继承

  • 实现方式Decorator 类持有一个 Control 类型的指针 m_control,通过组合来扩展功能,而不是通过继承创建多个子类。

    class Decorator : public Control {
    public:
        Decorator(Control* tmpctrl) : m_control(tmpctrl) {}
        void draw() override {
            m_control->draw(); // 调用被装饰控件的绘制方法
        }
    private:
        Control* m_control;  // 组合控件
    };
    

2. 动态功能组合

  • 实现方式:在 main() 函数中,动态创建装饰器来组合不同功能。例如,创建一个带边框和垂直滚动条的列表控件。

    Control* plistctrl = new ListCtrl();
    Decorator* plistctrl_b = new BorderDec(plistctrl);
    Decorator* plistctrl_b_v = new VerScrollBarDec(plistctrl_b);
    plistctrl_b_v->draw(); // 绘制
    

3. 复用已有功能

  • 实现方式:每个装饰器通过调用 Decorator::draw() 方法复用已有的绘制逻辑。

    void draw() override {
        Decorator::draw(); // 复用已有的绘制逻辑
        drawBorder(); // 添加边框绘制
    }
    

4. 接口隔离

  • 实现方式Control 类定义了一个接口,所有控件和装饰器都实现了这个接口,降低了耦合度。

    class Control {
    public:
        virtual void draw() = 0; // 抽象方法
        virtual ~Control() {}
    };
    

5. 单一职责

  • 实现方式:每个装饰器类只负责添加特定功能,如 BorderDec 负责绘制边框。

    class BorderDec : public Decorator {
    public:
        void draw() override {
            Decorator::draw(); // 复用已有的绘制逻辑
            drawBorder(); // 负责绘制边框
        }
    private:
        void drawBorder() {
            cout << "绘制边框!" << endl;
        }
    };
    

优势

  • 灵活性:可以在运行时根据需要组合不同的功能,适应变化。
  • 可扩展性:通过添加新的装饰器类来扩展功能,而不需要修改已有类。
  • 降低复杂性:避免因功能组合而产生大量子类,简化类层次结构。

总结

组合复用原则通过强调对象组合而非继承,提供了一种灵活、可扩展且易于维护的设计方式。通过使用装饰模式,可以在不修改现有类的情况下,动态地扩展对象的功能,满足不断变化的需求。理解并应用这一原则,有助于提升代码的可维护性和可重用性。

  • 13
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值