下面以两个例子来解释开闭原则(程序代码)
【按例1】Windows 的桌面主题设计
分析:Windows 的主题是桌面背景图片、窗口颜色和声音等元素的组合。用户可以根据自己的喜爱更换自己的桌面主题,也可以从网上下载新的主题。这些主题有共同的特点,可以为其定义一个抽象类(Abstract Subject),而每个具体的主题(Specific Subject)是其子类。用户窗体可以根据需要选择或者增加新的主题,而不需要修改原代码,所以它是满足开闭原则的,其类图如图 1 所示。
#include <QCoreApplication>
#include <iostream>
/*!
* \brief 抽象主题类
*/
class AbstractSubject{
public:
virtual void Display(void) = 0;
};
/*!
* \brief The SpecificSubject1 class
*/
class SpecificSubject1:public AbstractSubject{
public:
virtual void Display(void){
std::cout<<"SpecificSubject1"<<std::endl;
}
};
/*!
* \brief The SpecificSubject2 class
*/
class SpecificSubject2:public AbstractSubject{
public:
virtual void Display(void){
std::cout<<"SpecificSubject2"<<std::endl;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
AbstractSubject *subject = new SpecificSubject1;
subject->Display();
delete subject;
return a.exec();
}
【例子2】简单运算器
#include <QCoreApplication>
#include <iostream>
/*!
* \brief 运算类
*/
class Calculator{
public:
Calculator(int a, int b, std::string mop)
{
this->_ma = a;
this->_mb = b;
this->_moperator = mop;
}
int getResult()
{
if (_moperator.compare("+") == 0)
return _ma + _mb;
else if (_moperator.compare("-") == 0)
return _ma - _mb;
else if (_moperator.compare("*") == 0)
return _ma * _mb;
else
return 0;
}
public:
int _ma;
int _mb;
std::string _moperator;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Calculator *myCal = new Calculator(10,20,"+");
std::cout<<myCal->getResult()<<std::endl;
delete myCal;
return a.exec();
}
以上代码代码不符合开闭原则,按开闭原则应修改如下:
#include <QCoreApplication>
#include <iostream>
/*!
* \brief 抽象计算器类
*/
class AbstractCalculator
{
public:
virtual int GetResult() = 0;
virtual void SetOperatorNumber(int a, int b) = 0;
public:
int _mA;
int _mB;
};
/*!
* \brief 加法计算器类
*/
class PlusCalculator :public AbstractCalculator
{
public:
virtual void SetOperatorNumber(int a, int b)
{
this->_mA = a;
this->_mB = b;
}
virtual int GetResult()
{
return _mA + _mB;
}
};
/*!
* \brief 减法计算器类
*/
class MinuteCalculator :public AbstractCalculator
{
public:
virtual void SetOperatorNumber(int a, int b)
{
this->_mA = a;
this->_mB = b;
}
virtual int GetResult()
{
return _mA - _mB;
}
};
/*!
* \brief 乘法计算器类
*/
class MultiplyCalculator :public AbstractCalculator
{
public:
virtual void SetOperatorNumber(int a, int b)
{
this->_mA = a;
this->_mB = b;
}
virtual int GetResult()
{
return _mA * _mB;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
AbstractCalculator *calculator = new PlusCalculator;
calculator->SetOperatorNumber(10, 20);
std::cout << calculator->GetResult() << std::endl;
delete calculator;
return a.exec();
}
增加一个方法,无需修改源代码,只需新增一个类即可。
开闭原则的核心思想是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
参考: