- 作者:老汪软件技巧
- 发表时间:2024-10-15 17:04
- 浏览量:
虽然我已经好久没更新技术博客,但我并没有放弃技术博客更新的意思。
今晚(2024年10月14日)翻到四年前看李建忠老师设计模式视频时记下的笔记,感觉笔记记得还算不错。既然已经有了初始素材,我便想着将这些素材做些整理后分享出来。
阅读这些笔记时,有些不懂之处我重新去看了视频,发现已经懂得老师意思。这种感受到自己进步的喜悦,更增加我的分享欲望。
于是有此系列,我给它起名叫做“我将4年前的设计模式笔记再看一遍”。
一、模式总结
组件协作模式分类,通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。
这是李建忠老师所讲的第一个设计模式,他认为这是面向对象设计中,最基础且应用最广的一个设计模式。
一开始,我认为Template Method应该是一个很高大上的东西,听过老师的讲解,再结合自己敲过的代码,发现确实基础,且应用许多。且先将讲解示例,从我的脑子中,搬到这里来。
1、原始实现
如下代码,有一个库中实现了3个方法,到一个具体应用中,实现了另外2个方法,待到主程序中的时候,一直使用固有的顺序调用。
以下代码所举示例,来源于Windows画窗口(之前学习OpenGL的时候,需要先复制粘贴一套画窗口的流程),main函数中的调用步骤是稳定的,Library中的内容也稳定,变化的只是Application中的实现。
class Library{
void step1() {}
void step3() {}
void step5() {}
};
class Application{
void step2() {}
void step4() {}
};
int main(){
Library lib;
Application app;
lib.step1();
if(lib.step3()){
app.step2();
}
for(int i=0; i<4; ++i){
app.step4();
}
lib.step5();
return 0;
}
2、改进实现
可以看到,因为调用顺序是稳定的,于是将step2和step4两个方法,作为虚函数,挪到Library中,将整个稳定的调用顺序也挪到Library中。step2和step4供Application实现。
step2和step4使用protected的原因是,他们两个对于Library来说,调用是没有意义的,不提供给外部是最好的。
不过,当这样设计完成之后,作为只写Application部分的人来说,就只知道step2与step4了,并不了解整个调用流程是怎样的,会存在一些问题:最明显示例是,对我来说,虽然知道怎么写服务器逻辑,但是对于底层的调用、实现,其实是不明就里的。
class Library{
void step1() {}
void step3() {}
void step5() {}
void run(){
step1();
if(step3()){
step2();
}
for(int i=0; i<4; ++i){
step4();
}
step5();
}
protected:
virtual void step2() = 0;
virtual void step4() = 0;
};
class Application: public Library{
virtual void step2() {}
virtual void step4() {}
};
int main(){
Application app;
// 四年后来看,此处依然很帅,只关注主流程,这对于理解业务需求来说,会快许多
app.run();
return 0;
}
二、项目应用
听完整个设计模式的讲解之后,想到,目前我们项目中,用到这个模式的地方是真的多。Library有我写的,有不是我写的。
就服务器代码,对于一个Service来说,当我们继承了Service基类,并且将它注册到全局Service管理模块之后,并不知道它是如何跑起来的。只需要继承(重写)某几个特定方法,你的逻辑就会在对的时机跑起来。
客户端,在世界聊天和好友聊天的设计的时候,为了少写代码,我提取了公用部分出来,作为两个界面的基类(即Library),完成收到服务器消息 -- 筛选 -- 展示结果这一套流程,但两个界面有自己不同的展示结果函数(Library中的step2和step4)。
Unity3D引擎,脚本中的Update、OnStart这些方法,其实也是Template Method的体现,Update作为Library的一个虚函数,被整体调用框架调用,写逻辑的我只需要在Update中写点东西,就会每一帧被调用到。
三、感想、记录节点
1、心理变化,今天(2020-7-5)下午睡完午觉后,彼时脑袋昏沉,知道自己需要学习,但是不想学习,于是打开YouTube,继续听这一课。
听的前期,想着再坚持一会会儿,就看看其他娱乐视频吧。没想到,慢慢地,被老师所讲的内容所吸引,竟然40分钟的一节课,很快就听完,并且有了共鸣。于是立马进行记录。
2、听C++ 版的设计模式,对于C++语言的熟练程度,也是有所帮助的。比如虚函数说到底,也是一个函数指针,这就意味着,函数指针是很重要的。
3、老师讲解的过程中有提到,其实模式并不是一敲代码就拿出来用的,往往是在重构之后,才发现,重构的结果,往往就对应了某一(几)种模式。
4、花半小时对40分钟的课程进行了总结、记录。感觉自己有点类似于金庸武侠小说《侠客行》中的石破天,知道怎么出招打人,但却不知道招数名称。(这说的是我当年的状态,即已经用过“模板方法”很多次,却不知道它叫“模板方法”。)