在编写程序过程中,特别是刚刚入行没有多久的程序员,经常会犯的一个错误就是大段大段的复制粘贴代码。把功能相近的代码直接复制过来而不加以修改。这个习惯也许来源于你的老师也许来源于你本身的原因。总之,对于这一类程序员最好的设计模式就是“Ctrl+C(复制)”和“Ctrl+V(粘贴)”。
但是复制代码虽然在一定程度上提高了编程的速度,但是更多的是带来了不可预计的问题:若要修改这个功能的代码,却只修改了一部分,被复制的其他部分忘记修改;粘贴之后的代码,其中的变量忘记修改过来,造成了未知的问题,回头查找的时候却也找不到问题的所在;代码啰嗦等。
如何重构重复的代码呢?
- 把重复的代码封装成一个函数,让需要的地方调用这个函数即可;
- 如果重复的代码是出现在“互为兄弟类”中,也就是这两个类有共同的父类,可以把相同的代码提到父类中;
- 如果代码只是类似而不是完全相同,可以把相同的部分和相异的部分提炼出来,设计成模板模式;
- 如果两个互不相干的类出现重复的代码,可以把相同的部分,提到一个父类中或者提取到一个接口中;
- 重复代码的类只属于某一个函数,而且让另外的类可以直接调用这个类中函数。
设计模式-模板模式
就是把相同的部分提取出来,重点是提取相同的代码执行顺序(算法),而不是执行的细节。
#pragma once
class Bird {
void showBird();
protected:
virtual void eat();
virtual void fly();
virtual void say();
};
class XiQie : public Bird {
private:
virtual void eat();
virtual void fly();
virtual void say();
};
class WuYa : public Bird {
private:
virtual void eat();
virtual void fly();
virtual void say();
};
#include "Bird.h"
#include <stdio.h>
void Bird::showBird() {
eat();
fly();
say();
}
void Bird::eat() {
}
void Bird::fly() {
}
void Bird::say() {
}
void XiQie::eat() {
printf("喜鹊在吃\n");
}
void XiQie::fly() {
printf("喜鹊在飞\n");
}
void XiQie::say() {
printf("喜鹊在叫\n");
}
void WuYa::eat() {
printf("乌鸦在吃\n");
}
void WuYa::fly() {
printf("乌鸦在飞\n");
}
void WuYa::say() {
printf("乌鸦在叫\n");
}
调用:
#include <stdio.h>
#include "Bird.h"
int main() {
Bird* bird = new XiQie;
bird->showBird();
Bird* bird2 = new WuYa;
bird2->showBird();
return 0;
}
解析:
定义个鸟类,里面有一个公共函数,就是展示这个鸟,展示这个鸟的一些行为,吃、飞、叫。首先要展示吃,然后在展示飞,最后再展示叫。这个先后顺序已经规定好了。任何一个继承这个类的子类必须按照这个顺序执行。所以每个子类只要把具体执行的内容完成就可以了,具体的执行顺序在父类中规定了一个模板。这就是设计模式中的-模板模式。