Jungle花了几个月的时间整理出了《C++设计模式系列》,将源码放到了Github上,并且自从这一系列博客发布至今,陆续在修复bug、完善代码和说明文档。当然,文章还存在很多不足,Jungle也将持续完善。

C++设计模式系列文章汇总

但23种设计模式,要全部记住怎么可能呢?若是应对面试,哪些设计模式是考察的重灾区呢?本文Jungle将结合个人校招和社招面试经验,总结在面试过程中经常考察的设计模式。

开放式问题

一些面试官会考察关于设计模式的开放式的问题,比如:

了解设计模式吗?说说你对设计模式的理解/认识?你知道哪些设计模式?

这类问题比较轻松愉快,但凡了解过设计模式都能回答上来。比如可以从设计模式分为创建型、结构型、行为型三类说起,每一类包含的具体的设计模式,再详细点,可以谈谈每一类设计模式的特点。每一类不必说全,像结构型、行为型总共包含18种设计模式,全部说完会花很长的时间,所以挑重点或者你熟悉的来说。

尽管这个问题很开放,但也要注意回答的重点。因为这个问题后,面试官往往会根据你回答的设计模式提出进一步的问题,所以面试时要注意为后面的回答做好铺垫!

设计模式的优点/好处?

参见下面这篇,第二章,设计模式的作用。 设计模式——设计模式概述

你用过哪些设计模式?

这个问题说难也难,如果不了解设计模式,你可能说不上来,即使你在coding过程中已经用上某些设计模式了(比如工厂模式、原型模式、组合模式等),但不自知。没办法,得提早准备了解设计模式才行,否则错过一道送分题!

经常考察的设计模式

单例模式

毫无疑问,单例模式以其简洁的概念、密集的使用频次和重要的使用场景、加上简洁的编码实现,成为了众多设计模式中考察频次最多的一个。除了其简洁的概念以外,辅之以具体的应用场景(比如操作系统全局唯一的任务管理器等)则更有说服力。白板编程实现单例模式几乎成了必考点。面试时尤其要注意:

  • 懒汉模式和恶汉模式的实现(判空!!!加锁!!!),并且要能说明原因(为什么判空两次?)
  • 构造函数的设计(为什么私有?除了私有还可以怎么实现(进阶)?)
  • 对外接口的设计(为什么这么设计?)
  • 单例对象的设计(为什么是static?如何初始化?如何销毁?(进阶))
  • 对于C++编码者,需尤其注意C++11以后的单例模式的实现(为什么这么简化?怎么保证的(进阶))

工厂模式、简单工厂模式、抽象工厂模式

工厂模式系列(工厂方法模式、工厂模式、简单工厂模式、抽象工厂模式)在实际项目开发过程中经常使用。比如Jungle最近在分析的NVDLA的源码,其中就大量使用到了工厂模式,其优点显而易见:增加需求的时候扩展方便!

当然,原始的工厂模式存在一定的不足,所以进而衍生出了简单工厂、抽象工厂模式等。每种工厂模式的特点需要了解下,不必死记硬背,记住Jungle文章中的实例就ok了。Anyway,工厂模式系列,不论是在面试中还是在实际项目开发中,频率都很高。

观察者模式(发布订阅模式、模型-视图模式、源-监听器模式、从属者模式)

从这个模式有这么多变种的名称就知道它使用有多么广泛!

观察者模式建立了一种一对多的联动,一个对象改变时将自动通知其他对象,其他对象将作出反应。这个概念实在是太强大了,粗略思考下:一个系统内有许多存在耦合关系的对象,对象之间存在某种联动关系。这是不是很常见?消息更新、广播机制、消息传递、链式触发(高级啊)……凡是涉及到这些概念,是不是都会考虑到观察者模式?

问题1:哪些场景可以使用此设计模式?(上述加粗部分的场景)

问题2:观察者模式有什么特点?看下文即可: “牵一发而动全身”——我用观察者模式简单模拟吃鸡

职责链模式(责任链模式)

项目中责任链模式也比较常用,从其概念可以看出其适合的应用场景:链!

避免将一个请求的发送者和接收者耦合在一起,让多个对象都有机会处理请求。将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止。

解耦,不仅是该模式的作用和特点,更是软件设计的原则之一。如何来判定某个对象是否有机会处理链上的请求,这个判断的过程是不是像极了过滤器?所以过滤器的设计可以说是该模式的一个特点。

此外,采用职责链模式不仅可以方便扩展(当增加一个接受者时,只需要在链上的适当位置插入对应的处理方法即可),而且可以替换掉代码中可能存在的switch-case或者if-else,从代码简洁的考量也是一个不错的回答角度。(当然,替换掉switch-case或if-else不仅仅只有这种设计模式可以达到)。

适配器模式

开发中会经常使用到适配器模式,比如,不经意间的类的组合,或者为了设计某个class的接口,就一不小心把它变成了Container(哈哈哈)。需要注意的是:适配器模式分为类适配器和对象适配器。一定要注意二者的概念和区别。

可以详细去了解下什么是适配器模式,因为它实在太常用了,了解完以后对于回答本文第一个问题也有帮助!

此外,对于C++开发者,适配器模式之所以重要,还有个原因:**STL中的容器适配器,stack和queue!**如果面试官借此延展到对STL的考察~~

写在最后

前面举的例子仅仅是Jungle根据个人面试经验总结而成,其他设计模式,比如策略模式、组合模式、代理模式,在实际开发中也经常使用到。各位需要根据面试实际情况早做准备。这些设计模式在Jungle的《C++设计模式系列》文章里都有详细的概念、实例、代码和应用场景介绍。

还需要说两点:

1. 与设计模式有关的编程基础知识

以C++为例,前面在单例模式的说明里提到了一些问题,实际上都是考察C++类的基础知识、操作系统基础知识(锁、互斥);大部分设计模式的实现里,都会用到虚函数、虚基类(多态);繁多的类对象里,如何避免内存泄露等等,这些知识同样重要。否则,当着面试官的面,写出一套漏洞百出的单例模式,恐怕也是一曲凉凉~

2. 认识设计模式

C++设计模式这个系列,最开始我仅仅是在刚工作的时候作为基础知识来学习和记录,并通过一些简单易懂的例子来coding以加深理解。其实现在而言,我认为初学者并不需要深入理解掌握每一种设计模式。随着工作的深入,某些常用设计模式和代码复用的思想会让代码设计更加清晰并易于扩展。