面向对象设计(OOD)是技术面试中几乎必考的问题,也算新手村中的老大难问题。常听那些半路转CS的学生朋友们感慨,「算法问题还有刷题网站可以练习,面向对象这种开放性的问题,可怎么回答啊?」的确,面向对象的问题不好准备,完成一个好的方案需要足够多的细节考虑。但从另外一个方面讲,OOD也可以是一个非常容易出彩的机会,如果把这个问题回答好,很容易给面试官留下深刻的印象,因此我们决定不能轻易放过它。
在面向对象设计特性的支持上,Java/C++一直是这么多年来最流行的语言,也是在面试中被使用最频繁的语言。一个很普遍的建议是:尤其对于OOD的问题,如果不是有特殊原因(极端喜好或者大牛),熟悉和了解这两种语言(之一)几乎是必须的。面向对象的三个原则:封装(Encapsulation),继承(Inheritance),多态(Polymorphism)在这两门语言中体现的非常典型。因此如果今天的你才第一次听说OOD以及相关的概念,那还是老老实实的拿一本「Think In Java」,过一遍背景知识吧,很重要。
回正题,有一大类的OOD问题可以用一句话概括:Design a class for XXX;XXX通常是日常生活常见的东西或者系统,比如停车场,电梯,动物等等。
「完全无从下手,面试官到底要什么呢?」
举例子:Design a car class.
准备的比较好的同学脑海里可能想的是:
但是在不同的应用场景里,上面这个设计可能根本就不沾边。比如从汽车装配厂的角度来看,面试官脑子里可能想的是下面的图,不同的配件可以组合成不同的车:
再换一个应用场景:如果这个Car类只是在停车场系统中的一个普通类,那么上面两个设计都是毫无用处的over-engineering,因为Car在停车场系统中不需要那么多细节,可能最多需要尺寸颜色的信息就足够。
总的来说,脱离使用场景来设计类,往往会偏离面试官的初衷。往深了说,意味着面试者缺少沟通能力,没搞明白怎么回事儿就匆匆忙忙开始设计,这是面试中的大忌。Nice一点的面试官可能会继续follow-up,碰上找茬的这些缺点就足矣挂人了。所以,我们要搞清楚状况,就必须学会有效提问,澄清模糊的地方。比如:
好的设计需要足够多的细节,也同样需要足够多的抽象。细节和抽象的取舍,归根结底,需要根据使用场景来确定。面向对象设计的第一篇:面试官究竟想要什么?答案很简单:沟通需求,搞清逻辑,拿出解决实际问题的设计。至于怎么做到后半句,请关注面向对象系列之后的文章。:)