例:假设我是一个学术联合会的讲师。参加我的课程的人在你的课程之后还将参加其它的课程,但他们不知道下一节课的上课地点。我的责任之一,就是确保每个人都知道到哪里去上下一节课。
分析之前,我们先以结构化的程序设计方法来尝试解决问题:
1. 获取课堂上人的名单
2. 对于名单上的每个人:
a) 查找他的下一节课程。
b) 查找下一节课的地点。
c) 查找去的路径。
d) 告诉他怎样去上下一节课
这是理想的执行步骤,没有任何问题。但是大家想想,我们真的会按照上面的流程去做吗?
可能实际中,我们应该会采用这种方法:把从我讲课的教室到其他教室的路径张贴出来,然后告诉上我课的所有人:“我把其它的课程和相应教室的地址张贴在教室后面了。大家按照这份表去你们的下一个教室。”。这样就完事了。
那我们来看看这两种方法有什么不同呢?
第一种方法——对每个人都需要去明确的指出路径。你会疯掉!
第二种方法——你给了一个告示,并期望每个人都能自己知道如何完成你的告示。
两者最大的区别就是责任的转移。在第一种方案中,我对所有事情负责;第二种方案中,学生对他们自己的行为负责。两者用于实现同样的目的,但组织方式有巨大的差异。
这样做有什么效果?我们来看新需求出现时会发生什么。
这样子做有什么效果呢?我们来看当有新需求出现时会发生什么?也就是需求发生变化时。
假设我们被告知:需要给毕业后助教的学生特殊的指令。也许他们需要在到下一个教室之前先收集课程评价并把课程评价交到办公室。在第一种方案中,我必须修改控制程序来区分毕业和未毕业的学生,然后给毕业的学生特殊的指令。很可能我必须对程序做相当多的修改。
但,在第二种方案中——每个人对自己的行为负责——我只需要给毕业生一个附加的说明。然后仍然是执行“去你的下一个教室”的动作。
这是控制程序中重大的区别。第一种放啊,每当出现一种新需求时,控制程序都必须修改。
第二种方案:新类型的学生也必须对自己的行为负责。
三处改变早就了这样的效果:
每个人对自己负责,而不再有控制程序对他们负责。
控制程序可以与不同类型的人对话。
控制程序不需要知道学生在教室之间的任何步骤。
这里引进一些专门的UML术语:
软件开发过程中的三个不同的视角:
概念:展现问题领域中的概念
规格:只看软件的接口,不要看具体的实现
实现:也就是实体的代码
从这三个角度,我们再看看上面的那个例子:
我也就是讲师是在概念层上跟学生做交流。换句话说,我告诉学生“希望他做什么”,而不是“怎样做”。但是,他们各有有各自的课和,走到下个教室的路径也是不同的,可以自由选择,这就是实现层的事情了。
在一个概念层上通信,而在别一个实现层上执行。其结果就是我不需要知道具体发生了什么,只要在“概念上”发生了什么。