“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动”。——Christopher Alexander
上面这段话可以说是设计模式为什么会被总结归纳并值得学习的原因——“复用前人的经验”。
是的,它就像一本传世已久的武功秘籍,你在软件开发过程中遇到的大部分问题,其实你的先辈都曾遇到过,并且已经做了归纳,你只需学习这些经验并实践之就能解决你眼前的困难。当然,你也可能选择无视它,自己尝试去解决,但最终的效果大概率差强人意,并且在此过程中也浪费了大量时间。而当你撞了无数次南墙再回过头来看它时,可能这时你才会真正领略到它的魅力。
引言
本文主要针对《Head First设计模式》中的经典案例给出相应的C++版本,并对一些模式进行简单归纳,在此过程中并不会针对具体模式做深入分析,因为这些东西已经有人做过了,写本文的初衷也只是我自己想写个笔记简单归纳一下。
模式是在某情景下,针对具体问题给出的某种解决方案。
因此,这里会顺带给出一些案例,你可以先按照自己的想法,代入其中,尝试给出自己的解,之后再来看案例。通过对比,可能会留下更深刻的印象。
前置要求
- 需要你掌握C++的基本语法;
- 需要对“封装”,“继承”,“多态”有所了解(尤其是多态);
- 需要了解C++派生类与基类之间有三个特殊关系:
- 派生类对象可以使用基类的方法,条件是方法不是私有的。
- 基类指针可以在不进行显式类型转换的情况下指向派生类对象。
- 基类引用可以在不进行显式类型转换的情况下引用派生类对象。
在开始之前,希望你深刻理解这三个关系。这里给出一段代码,你可以先推测一下运行结果,再自己跑一下,如果全都判断对了,说明你已理解其中奥妙。
#include <iostream>
using namespace std;
class parent
{
public:
virtual void show()
{
cout << "parent -> show" << endl;
}
};
class son : public parent
{
public:
void show()
{
cout << "son -> show" << endl;
}
};
void passByReference(parent& p)
{
p.show();
}
void passByPointer(parent* p)
{
p->show();
}
void passByValue(parent p)
{
p.show();
}
int main()
{
son s;
passByReference(s);
passByPointer(&s);
passByValue(s);
return 0;
}
PS: 复制这段代码,在线运行