系列文章目录
前言
在一个新人刚入编程这一行的时候,可能在正式参加到一个项目之前跟着书本或者教学视屏写了一些五子棋、贪吃蛇等等的小程序。
在参加工作之后,领导直接扔过来一个项目让你看看代码,你可能专心的在看这个接口调用了哪些接口、一个类包含哪些功能。
再之后,大多会让你先参与维护的工作,等工作了一两年,可能让你独立支持一个项目的部分功能实现。
但是在工作了两三年后,如果让你直接挑战一个大项目,从零开始设计、搭建项目,你真的可以设计出既满足功能、代码又很优雅、迭代维护性高的工程吗?
或者你了解一些什么工厂模式、开闭原则等浅薄的知识,觉得自己可以挑战一个大型项目,但实际上这远远不够。
或许有人会说这是架构师的职责,但是假如等到你以后跳槽了,或者工龄大了升职了,还不能挑起一个大项目,想到这些你会不会想现在提升一下自己呢?
如果可以全面按照C++的设计原则,并灵活应用设计模式的话,就可以磨练出支撑大型项目的能力,在我们设计的时候要时刻牢记这些原则。
|版本声明:山河君,未经博主允许,禁止转载
一、开闭原则到底有什么用?
开闭原则属于六大设计原则之一,百度百科上面介绍开闭原则:开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。
所谓的开闭,也正是对扩展和修改两个行为的一个原则。强调的是用抽象构建框架,用实现扩展细节。可以提高软件系统的可复用性及可维护性。
二、开闭原则有什么特点
以下是构造了一个计算器,它具有最基本的加、减、乘、除的功能。运行虚函数的方法使得计算机是一个纯虚父类,使用时使用父类指针指向子类,直接使用父类指针调用计算方法即可。
其实特点在上面已经说过了,可以扩展,但是不能修改,开闭原则充分利用了父类指针指向子类的原理,在实际应用中,实际上我们能拿到的只有父类指针,根据指向去使用子类,所以会经常出现一种问题,使用开闭原则,我们有的时候压根就不知道父类指针指向的是哪里。
关于以上特性我们直接看一下代码输出。
#include <iostream>
#include <stdlib.h>
using namespace std;
//计算器类
class Calculator
{
public:
//抽象接口类,子类实现
virtual double getompute() = 0;
virtual void getParam(double a, double b) = 0;
};
//除
class Division : public Calculator
{
public:
virtual double getompute()
{
return mA / mB;
}
virtual void getParam(double a, double b)
{
mA = a;
mB = b;
}
private:
double mA;
double mB;
};
//乘
class Multiplication : public Calculator
{
public:
virtual double getompute()
{
return mA * mB;
}
virtual void getParam(double a, double b)
{
mA = a;
mB = b;
}
private:
double mA;
double mB;
};
//减
class Subtraction : public Calculator
{
public:
virtual double getompute()
{
return mA - mB;
}
virtual void getParam(double a, double b)
{
mA = a;
mB = b;
}
private:
double mA;
double mB;
};
//加
class Addition : public Calculator
{
public:
virtual double getompute()
{
return mA + mB;
}
virtual void getParam(double a, double b)
{
mA = a;
mB = b;
}
private:
double mA;
double mB;
};
int main()
{
Calculator* Add = new Addition;
Add->getParam(1,2);
double c = Add->getompute();
cout << c << endl;
system("pause");
return 0;
}
父类是一个计算器类,是一个抽象类,当然不一定非得是抽象类,但是如果不是抽象类,就要注意释放问题,其四个子类分别为加、减、乘、除。而在实际使用中,我们也是直接定义父类指针指向子类。当然,我们也可以直接使用子类,只用加功能,但是实际上我们的逻辑是用计算器的加功能,我们用的是计算器,而不是拆分下来的东西。
为什么说这样就可以保证扩展性而不能修改呢,实际上什么代码只要你想,都可以修改,只是有没有需要,而使用开闭原则就可以在实际开发过程中,让开发人员自然而然的不会想到直接修改代码,而是通过扩展功能来实现需求。
比方说,在这个基础上我想增加求根的功能:
如果咱们现在只有一个计算器类,这个类里面有加、减、乘、除四种方法,那么想增加求根功能我们自然而然会想到在计算器中增加求根的方法,这样就修改了我们的源代码。
而使用了开闭原则,父类中的纯虚函数就有一个求值的接口getompute,开发人员就会增加一个新的子类,进行求根的操作,这样就不会直接修改源代码。