敏捷开发笔记 原则篇 OCP [开放 封闭] 原则

描述

  • 对于程序的扩展是开放的
  • 对于程序牵一发而动全身的更改是封闭的

实现

模块可以操作一个抽象体。由于一个模块依赖一个固定的抽象体,所以抽象体对于更改是关闭的。但是他可以通过派生来达到扩展其行为的目的。

简单的说 符合 OCP 原则的设计 是对一个模块的改动是动过新增加代码实现的,而不是修改原先的代码,不会引起连锁反应。

示例

假如现在需要绘制图形界面,有圆形,矩形,三角形 等等 。需要创建一个列表,让后按一定的顺序绘制他们 。

  • 遵循OCP 的设计
class Shape
{
public:
    virtual void Draw() const = 0;
};

class Circle
    :public Shape
{
public:
    // 通过 Shape 继承
    virtual void Draw() const override
    {
        std::cout << "circle" << std::endl;
    }

};

class Square
    :public Shape
{
public:
    // 通过 Shape 继承
    virtual void Draw() const override
    {
        std::cout << "Square" << std::endl;
    }

};
  • 使用“数据驱动”的方法实现封闭性
#include<iostream>
#include<typeinfo>
#include<vector>
#include<cstring>
#include<list>

class Shape
{
public:
    virtual void Draw() const = 0;
    //实现排序策略的封闭
    bool Precedes(const Shape & s) const
    {
        auto this_name = typeid(*this).name();
        auto s_name = typeid(s).name();

        int this_ord = -1;
        int s_ord = -1;

        for (size_t i = 0; i < typeOrderTable.size(); i++)
        {
            if (strcmp(this_name,typeOrderTable.at(i))==0)
            {
                this_ord = i;
            }
            if (strcmp(s_name,typeOrderTable.at(i))==0)
            {
                s_ord = i;
            }

            if (this_ord!=-1 && s_ord!=-1)
            {
                break;
            }
        }

        return this_ord < s_ord;
    }
    bool operator< (const Shape & s) const { return Precedes(s); }

private:
    static std::vector<const char *> typeOrderTable;
};

class Circle
    :public Shape
{
public:
    // 通过 Shape 继承
    virtual void Draw() const override
    {
        std::cout << "circle" << std::endl;
    }

};

class Square
    :public Shape
{
public:
    // 通过 Shape 继承
    virtual void Draw() const override
    {
        std::cout << "Square" << std::endl;
    }

};

//图形绘制的先后顺序实际上是有这个数据表来驱动 
//新派生的图形只需要修改一个表即可 不需要修改已有的代码实现 
std::vector<const char *> Shape::typeOrderTable
{
    typeid(Square).name(),
    typeid(Circle).name()
};

//按序绘制所有图形方法的封闭 
void DrawAllShape(std::list<Shape * > & shape_list)
{
    //排序 

    shape_list.sort([](const Shape * a, const Shape* b) {return *a < *b; });

    //渲染 

    for (const auto & v:shape_list)
    {
        v->Draw();
    }
}


int main()
{
    Circle *c1 = new Circle;
    Circle * c2 = new Circle;
    Square * s1 = new Square;
    Square * s2 = new Square;

    std::list<Shape *> list;
    list.push_back(c1);
    list.push_back(s1);
    list.push_back(s2);
    list.push_back(c2);


    DrawAllShape(list);

    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_33775402/article/details/81436306