开闭原则是对扩展开放,对修改关闭。增加功能是通过增加代码来实现的,而不是去修改源代码。

什么意思呢?

下面看一个具体的案例

有一个计算器类,其目前的功能有加、减、乘、除。

//计算器类
class Calculator
{
public:
	//构造函数
	Calculator(int a, int b, string m_operator) :m_A(a), m_B(b), m_Operator(m_operator)
	{

	}

	int getResult()
	{
		if (m_Operator.compare("+") == 0)
		{
			return m_A + m_B;
		}
		else if (m_Operator.compare("-") == 0)
		{
			return m_A - m_B;
		}
		else if (m_Operator.compare("*") == 0)
		{
			return m_A * m_B;
		}
		else if (m_Operator.compare("/") == 0)
		{
			return m_A / m_B;
		}
	}

	//数据
private:
	int m_A;
	int m_B;
	string m_Operator;
	int m_Ret;
};

void test01()
{
	Calculator* cal = new Calculator(10, 20, "*");
	cout<< cal->getResult()<<endl;
}

假如我们此时又要增加新的功能,比如说增加取余操作。

那么对于这样的类,我们需要在getResult中,再增加一个else if来判断取余,这就修改了代码,就有可能导致整体出错,

我们应该在增加新功能的时候,不影响其它已经完成的功能。这就是开闭原则。

 

下面使用开闭原则来完成功能的增加

//写一个抽象类
class AbstractCalculator
{
public:
	//纯虚函数
	virtual int getResult() = 0;
	virtual void setOperatorNum(int a, int b) = 0;
};

//加法计算器  继承 抽象类   重写抽象类的纯虚函数
class PlusCalculator :public AbstractCalculator
{
public:
	//set方法
	virtual void setOperatorNum(int a,int b)
	{
		this->mA = a;
		this->mB = b;
	}

	virtual int getResult()
	{
		return mA + mB;
	}
private:
	int mA;
	int mB;
};


//减法计算器
class SubCalculator :public AbstractCalculator
{
public:
	//set方法
	virtual void setOperatorNum(int a, int b)
	{
		this->mA = a;
		this->mB = b;
	}

	virtual int getResult()
	{
		return mA - mB;
	}
private:
	int mA;
	int mB;
};


//乘法计算器
class MultibCalculator :public AbstractCalculator
{
public:
	//set方法
	virtual void setOperatorNum(int a, int b)
	{
		this->mA = a;
		this->mB = b;
	}

	virtual int getResult()
	{
		return mA * mB;
	}
private:
	int mA;
	int mB;
};


//如果增加取莫运算  通过增加代码来实现的,不需要修改前面的代码
class ModeCalculator :public AbstractCalculator
{
public:
	//set方法
	virtual void setOperatorNum(int a, int b)
	{
		this->mA = a;
		this->mB = b;
	}

	virtual int getResult()
	{
		return mA % mB;
	}
private:
	int mA;
	int mB;
};

void test02()
{
	AbstractCalculator* cal = new PlusCalculator;
	cal->setOperatorNum(10, 20);
	cout << cal->getResult() << endl;
	delete cal;                                    //释放指针

	cal = new SubCalculator;
	cal->setOperatorNum(10, 20);
	cout << cal->getResult() << endl;
	delete cal;                                    //释放指针

}

写一个抽象的计算器类,即接口,定义相应的方法,将方法定义成纯虚函数,以便子类继承时实现。

当我们需要加法时,定义加法类继承抽象的计算器类,再实现接口里面的方法。当加入其他功能时,再写个类继承抽象类即可,以此类推。

这就满足了 增加功能是增加代码实现的,而不是修改代码。

当然,在这个案例中,使用开闭原则让代码更加复杂了,在比较大的项目中,开闭原则的优势就凸显出来了。当某个功能无法实现时,只需找对应的类即可。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐