上一篇文章谈到了OOP设计中的重要部分,即分析使用场景(use case)。今天我们就用一个具体的例子来分析这类问题的思路。
Design an elevator class.
电梯是我们生活中经常使用的物件,在开始设计之前,我们先看看电梯是如何被使用的。
首先,电梯谁来用?开展想象。电梯的使用者可以是:
a. 普通用户;(可以上下基本楼层)
b. 刷卡用户;(可以上下基本楼层+卡权限所允许的楼层)
c. 特殊工作人员;(不但可以上下所有楼层,还可以锁定、开启电梯,查看电梯配置等高级行为)
d ...
OK,有这么多类型的用户,有必要考虑这么全面呢?很简单,问面试官,「我想到了abcd这些情况,需要都考虑么?」面试官通常会说,「啊,咱们先从最简单的普通用户开始,假设电梯的使用者只有这一种用户,开始设计,之后有时间我们再扩展」。大家想想,如果我们上来就假设所有的用户都是普通用户,可以进出电梯、上下所有层。面试官估计也会觉得OK,但是显然前者可以给人「思考更全面、成熟」的印象。Why not?
其次,电梯怎么被使用?注意,请把电梯当作一个整体,从使用者的角度来考虑电梯的交互行为。面向对象的一个核心原则叫封装(encapsulation),对象对外暴露行为(interface)而隐藏状态(state)。作为普通用户,电梯的行为可以被描述为:
a. 在电梯外,按上下键呼叫电梯。
b. 电梯内,按具体楼层。
c. 电梯内,按开关门键。
d....
当然大家可能说,很多高级的电梯系统的使用方法是:在电梯外按楼层数,然后系统告知你去某一个电梯处等。Great! 想到了一个使用场景,就和面试官沟通,没准他也是这么想的。再次重申,OOP设计类问题没有唯一答案,面试官想要挖掘的是你设计的思路以及沟通的能力。因此,我们假设面试官对于我们的行为设计表示认可,于是继续按上面的行为进行设计。
在明确了使用者、使用者使用电梯的方式之后,电梯类的大致轮廓就基本出现啦:
确定了电梯类的对外行为(public methods)之后,我们就可以进入「实现」的阶段啦。
最后补刀:很多朋友说面试OOP根本没机会写代码。很残酷的事实是,很可能你设计的类行为、方法不能自圆其说,面试官就很难想象如何使用你设计的类,那他就只能不断的问你问题,帮你理清楚到底类和类的使用者到底是怎样的调用关系。如果这个过程过于长,那就没有时间去实现具体方法啦。
下一篇,我们讲解如何通过设计类的内部状态、方法来实现对外的方法接口。