我觉得设计模式是对于面向对象类型语言所特有的,同时也是是学习自己进行软件构建的基础。进行设计模式学习之前,首先要知道软件构建的几个要求:
- 可维护:即要改,只需更改要改的地方
- 可复用:要用的代码并非用完一次就没用了,完全可以在后来的地方重复使用
- 可扩展:如果要加入新的需求,只需添加一些内容即可
- 灵活性好:使用的代码功能可以随意变换组合
一开始,我从最基础的设计模式学起:
简单工厂模式
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
举个例子,比如我现在要实现一个简单计算器。这时,我们可以创建一个符号基类,然后其他算术符号都可以继承这个类:
#ifndef SIGN
#define SIGN
#include <iostream>
class Sign{ //这里封装一个抽象类,因为数据比较简单,并且一开始就初始化了,因此使用默认构造函数,析构函数和拷贝构造函数
protected:
double _A = 0;
double _B = 0;
double _Result = 0;
public:
void setA(double a)
{
_A=a;
}
void setB(double b)
{
_B=b;
}
double getA(){return _A;}
double getB(){return _B;}
virtual double getResult() = 0;
virtual ~Sign(){} //根据《Effect C++》条款七:任何class只要带有virtual函数都几乎确定应该也有一个virtual析构函数。
};
//下面用到继承
class signAdd:public Sign //加法类,继承符号类
{
double getResult()
{
_Result = _A + _B;
return _Result;
}
};
class signMinus:public Sign //减法类,继承符号类
{
double getResult()
{
_Result = _A - _B;
return _Result;
}
};
class signMultiply:public Sign
{
double getResult()
{
_Result = _A * _B;
return _Result;
}
};
class signDivide:public Sign
{
double getResult()
{
if(_B == 0){
std::cerr<<"can't divide zero"<<std::endl;
throw 1;
}
_Result = _A / _B;
return _Result;
}
};
#endif // SIGN
然后在用一个简单工厂类,用来生成对应的符号类:
#ifndef SIGNFACTOR
#define SIGNFACTOR
#include "sign.h"
#include <QString>
class Signfactory{ //简单工厂类,为了根据传入参数返回对应需要的类
Sign * _S = NULL;
public:
Sign * createSign(QString str){
if(str=="+")
_S = new signAdd;
else if(str=="-")
_S = new signMinus;
else if(str=="*")
_S = new signMultiply;
else if(str=="/")
_S = new signDivide;
else
{
std::cerr<<"unknow sign!";
throw 0;
}
return _S;
}
};
#endif // SIGNFACTOR
这样,我们再简单做一个界面就看测试这个程序啦!界面程序请参考源代码。
这样一个简单的设计模式,就包含了类的三大特性:封装、继承、多态。而且这样一个设计就使得程序可以很好的扩展,比如当我需要再加入一个开根号的符号,只需要再继承一下符号类,然后加入开根号的算法,并且在工厂类里面多加入一个选择即可。这就是设计模式的高端之处!
最后从放上源码地址:https://github.com/Dongzhixiao/designMode_qt/tree/master/Caculate_simpleFactory_pattern_1
其实在进行程序类之间的关系的分析时,还需要指定两个概念,这里先说明一下,提醒自己不要忘记:
- 合成 也翻译成组合,是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
- 聚合 表示一种弱的“拥有”关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。
理解上面这两个概念后,以后在寻找类之间的关系时就能够用这两个术语进行区别了。