回顾
在上一篇里使用了简单的控件构建了一个简单的计算器界面,按道理说这篇应该学习计算器的核心算法了,但是在之前实现的代码中有一点比较糟糕的是我们直接就在main函数里写的代码,那么我们要是需要加入其它逻辑代码时main函数就会显得杂乱无章了,所以在学习业务逻辑之前进行一个代码重构的操作。
那么什么是代码重构呢?代码重构需要做些什么事?
- 代码重构是以改善代码质量为目的的代码重写,使其代码的设计和架构更合理,经过代码重构后将会提高软件的扩展性和可维护性,并且代码重构应该做到不改变原来的功能,不引入新的BUG。
- 在软件编码初期,我们首先需要进行的工作是代码实现,即实现预期的功能,此时对代码的架构需求还不高,只考虑功能的实现,当功能实现后就需要考虑代码架构是否具有可持续性开发,那么此时就需要进行代码重构,代码重构是以提高代码质量为目的的软甲架构优化,但是此时不能改变之前实现了的功能,当然也不能引入bug。
那么什么时候进行代码重构?
- 当发现项目中的重复代码越来越多。
- 当发现项目中的某个或某些函数功能越来越不清晰时。
- 当发现项目中的代码离设计越来越远时。
- 在软件开发中通常将重构放在功能测试期间,在完成部分功能后刚好处于一个结点(这个功能已完成,下一个功能未开始),此时肯定需要对功能进行测试,也叫特性测试,同时对当前的代码进行一次代码重构则有利于优化结构,解决一些代码复用的问题和修正函数功能。
计算器界面代码重构
- 基于上一节课的计算器界面代码,我们也可以进行一次代码重构,对程序设计进行一次小小的优化。
- 首先界面代码肯定是需要封装起来的,所以需要一个放置界面代码的类,叫做QCalculatorUI,它组合使用QWidget、QLineEdit以及QPushButton。将界面相关的代码放置到一个类里面不仅方便阅读也方便管理维护。
那么接下来就是代码实现了。
既然要设计类,那么就需要有类的声明内容。
class QCalculatorUI : public QWidget
{
private:
QLineEdit* m_edit;
QPushButton* m_buttons[20];
QCalculatorUI();
bool construct();
public:
static QCalculatorUI* NewInstance();
void show();
~QCalculatorUI();
};
由于采用了动态资源,所以我们使用二阶构造模式来创建对象,并且二阶构造也能防止产生半成品对象。
bool QCalculatorUI::construct()
{
bool ret = true;
const char* btnText[20] =
{
"7", "8", "9", "+", "(",
"4", "5", "6", "-", ")",
"1", "2", "3", "*", "<-",
"0", ".", "=", "/", "C",
};
m_edit = new QLineEdit(this);
if( m_edit != NULL )
{
m_edit->move(10, 10);
m_edit->resize(240, 30);
m_edit->setReadOnly(true);
}
else
{
ret = false;
}
for(int i=0; (i<4) && ret; i++)
{
for(int j=0; (j<5) && ret; j++)
{
m_buttons[i*5 + j] = new QPushButton(this);
if( m_buttons[i*5 + j] != NULL )
{
m_buttons[i*5 + j]->resize(40, 40);
m_buttons[i*5 + j]->move(10 + (10 + 40)*j, 50 + (10 + 40)*i);
m_buttons[i*5 + j]->setText(btnText[i*5 + j]);
}
else
{
ret = false;
}
}
}
return ret;
}
QCalculatorUI* QCalculatorUI::NewInstance()
{
QCalculatorUI* ret = new QCalculatorUI();
if( (ret == NULL) || !ret->construct() )
{
delete ret;
ret = NULL;
}
return ret;
}
void QCalculatorUI::show()
{
QWidget::show();
setFixedSize(width(), height());
}
- 有了声明,那么就需要有实现。
- 首先就是二阶构造的实现,具体详解请参考C++部分的二阶构造模式。其中第一阶段就是类的构造函数,它不带有任何可能出现异常的代码;第二阶段就是关于资源申请会操作文件等可能存在失败情况的操作,比如此处的按钮对象指针和文本框对象指针。两个阶段都实现了,但是还需要一个能直接调用它们的成员函数以达到最终的对象能够构造成功并完成正常的初始化的目的。
- 当然是使用静态成员函数实现,为什么要静态的,普通成员函数是需要通过对象或对象指针调用的,在还没创建对象时显示两者都是不存在的,所以通过静态函数来创建对象再合适不过了。
- 可以将窗口样式放在构造函数中,使用一个Qt枚举参数值。
- 那如何实现窗口固定尺寸?当然是重写show()函数,先将界面显示出来,再设置尺寸固定。
小结
- 重构是软件开发中的概念
- 重构是以提高软件开发质量为目的的开发活动
- 重构不能影响已有的功能
- 当软件功能实现到一定阶段时需要考虑对代码进行重构