周口网站设计,翻书效果网站,网站建设后台管理怎么管理,梧州网站建设贝尔利2023年8月27日#xff0c;周日下午
我觉得我的这篇博客还是写得很不错的#xff0c;哈哈哈。 目录
概述举例说明用开放-封闭原则重构 概述
开放-封闭原则#xff08;Open-Closed Principle#xff0c;OCP#xff09;是面向对象设计中的一个重要原则#xff0c;也是许多…2023年8月27日周日下午
我觉得我的这篇博客还是写得很不错的哈哈哈。 目录
概述举例说明用开放-封闭原则重构 概述
开放-封闭原则Open-Closed PrincipleOCP是面向对象设计中的一个重要原则也是许多设计模式的基础。它由Bertrand Meyer在他的书《面向对象软件构造》中提出并被广泛应用于软件开发中。
开放-封闭原则的核心思想是软件实体类、模块、函数等应该对扩展开放对修改封闭。换句话说当需要修改一个软件实体时应该通过扩展它的行为而不是修改它的源代码。
这个原则的目标是实现软件设计的稳定性和可维护性。通过遵循开放-封闭原则我们可以减少修改已有代码的需求从而降低了引入新错误的风险并提高了代码的可复用性。
实现开放-封闭原则的关键是使用抽象和多态。通过定义抽象的接口或基类可以将代码与特定的实现分离开来。这样在需要变更行为时我们只需要创建新的实现类并基于抽象进行扩展而不需要修改已有的代码。 举例说明
假如有一天公司要我写一个计算圆的面积的函数getArea
#include iostream// 计算圆的面积
double getArea(double radius) {return 3.14159 * radius * radius;
}int main() {// 计算面积double area getArea(3);// 输出面积std::cout area: area std::endl;return 0;
}这很简单是不是
但是后来公司要求这个getArea函数要增加计算正方形的面积的功能
假设我不懂开放-封闭原则那么我只能老老实实修改getArea函数内部的代码
#include iostream// 计算面积
double getArea(double num,std::string thing) {if(thing圆形)return 3.14159 * num * num;if(thing正方形)return num*num;
}int main() {// 计算面积double area1 getArea(3,圆形);double area2getArea(4,正方形);// 输出面积std::cout 圆形面积: area1 std::endl;std::cout 正方形面积: area2 std::endl;return 0;
}虽然我也完成了任务但可以看到getArea函数变得复杂了参数由1个变成2个内部的实现代码也更多了。
但是任务还没结束后来公司又让我给getArea函数添加计算长方形的功能
#include iostream// 计算面积
double getArea(double num1,double num2,std::string thing) {if(thing圆形)return 3.14159 * num1 * num1;if(thing正方形)return num1*num1;if(thing长方形)return num1*num2;
}int main() {// 计算面积double area1 getArea(3,0,圆形);double area2getArea(4,0,正方形);double area3getArea(4,3,长方形);// 输出面积std::cout 圆形面积: area1 std::endl;std::cout 正方形面积: area2 std::endl;std::cout 长方形面积: area3 std::endl;return 0;
}可以看出来我的getArea函数不仅变得更加难以理解而且变得更加复杂了参数由2个变成3个而且内部代码实现也变多了。
接下来就不用写照这么写下去随着需求的增多getArea函数只会变得越来越复杂和难以理解。 用开放-封闭原则重构
不难看出在getArea中不变的是要返回一个面积不断变化的是不同图形的计算方法
所以可以封闭getArea的”返回一个面积“而开放”计算方法“。
我把所有图形抽象成一个Shape抽象类要求所有Shape抽象类的派生类都必须提供一个返回面积的接口。至于这些派生类怎么实现父类Shape要求的返回面积的接口就各显神通、因地制宜了此之谓”开放扩展“
而getArea函数只需雷打不动地调用Shape类的派生类的返回面积的接口就可以了此之谓”封闭修改“。
#include iostream// 抽象基类用于表示图形形状
class Shape {
public:virtual double area() const 0;
};// 具体的图形形状矩形
class Rectangle : public Shape {
public:double width;double height;Rectangle(double w, double h) : width(w), height(h) {}double area() const override {return width * height;}
};// 具体的图形形状圆形
class Circle : public Shape {
public:double radius;Circle(double r) : radius(r) {}double area() const override {return 3.14159 * radius * radius;}
};// 计算所有图形的总面积
double getArea(const Shape* shape) {return shape-area();
}int main() {// 创建矩形和圆形对象Circle circle(3);Rectangle rect1(4, 4);Rectangle rect2(4, 3);// 计算总面积double area1 getArea(circle);double area2getArea(rect1);double area3getArea(rect2);// 输出面积std::cout 圆形面积: area1 std::endl;std::cout 正方形面积: area2 std::endl;std::cout 长方形面积: area3 std::endl;return 0;
}可以看到无论公司要求增加什么图形的计算面积功能都不需要修改getArea函数
只需要增加一个继承自Shape类的派生类就可以了
不信的话你们可以再添加一个计算梯形的面积试试就当作一个小作业。