1.Advantages and disanvantages of Peer Programming
advantages
The code are constantly validated by two people, reducing the possibility of indivudual making stupid mistakes.
2.Hiding Information,interface design,loose coupling
Information hiding is part of the foundation of both structured design and object-oriented design. In structured design, the notion of “black boxes” comes from information hiding. In object-oriented design, it gives rise to the concepts of encapsulation and modularity, and it is associated with the concept of abstraction.
----From Code Complete Section 5.3
信息隐藏是在面向对象中非常重要的方法,它和对象的封装与模式化密切相关。它可以将一个类内部非常敏感,开发人员不想让使用者直接操作的变量隐藏在自身内部。这样,增加了软件的健壮性和安全性。
Code Complete中列举了两类需要考虑隐藏的内容:
Hiding complexity so that your brain doesn’t have to deal with it unless you’re specifically concerned with it:复杂化的信息。这样某个模块的问题就不会被带入到另一个模块中。想这次的Elevator Framework,对于Elevator而言,不需要知道Scheduler当中到底发生了什么事情,只需等待调度器分配给他StopAt(floor)指令,接着到达指定楼层就可以了。同时Elevator更不需要知道每一个Passenger的信息,Passenger会在电梯停在相应楼层猴自己上电梯。这样的Information Hiding 很好地重现了现实生活的情况,有助于Object-Oriented Design的开发。
Hiding sources of change so that when change occurs the effects are localized:个人认为这样可以防止错误扩散到外部代码中去。这样可以将因为change产生的exception在该模块内部进行捕获。
接口设计实现了information hiding(只给用户提供接口让其调用)。这次pair work 中深深体会到了好的接口设计带来的方便。在编程的初期,及时我们不是很清楚整个代码的结构和运行原理,但是只要修改IScheduler,我们写的调度算法就可以很自然地接入到整个系统中。(老师就是老师,写的整个Elevator Framework能够很清楚地分清楚每个模块的功能,并且很好地实现了模块之间的通信,感觉我们的面向对象编程思想还很不成熟,根本达不到老师这样完善。希望以后能够多教授一些这方面技巧)
我们进行接口设计的目的就是为了各个模块之间的松耦合,两者之间相辅相成。
这里我们还在网上看到一个值得注意的误区。面向对象接口应该适当的使用。比如当电梯的实现只有一个SenElevator时,就不必再写一个IElevator接口了。千万不要“为了写接口而写接口”。
3.Design By Contract 契约式设计
调用者必须提供正确的参数,被调用者必须保证正确的结果和调用者要求的不变性。
4.unit test
我们测试的是elevator类,最后代码覆盖率又90%左右,因为只测试了单一方向,最后乘以二就对了
5.UML
这是VS搞出来的类图,看了一下还挺靠谱的,贴一个简单的,再贴一个详细的
6.算法实现:
T总 = Tdelay + Trun
Trun的具体计算方法用if else分支语句分为了7种情况(暂时不考虑disabled floor,<R,请求方向>为请求高度及方向,<D,电梯方向>为电梯高度及方向):
注意这里计算使用的是电梯高度而不是楼层进行时间,这非常关键:举个例子,#1在3层停靠,#2在36米上行(此时currentfloor为3),实际用时应分别为2tick,5tick+doorclosetick。如果用当前楼层计算,则都为5秒,因为循环特征会将任务分配给#1,而这明显是错误的。这个疏忽造成的bug导致我们花费了很长时间。
Tdelay 是电梯行驶过程中停靠花费的时间,等于DestinyFloor.count()*5ticks。
进行分配后,Elevator类会将将相应楼层位置1。每次停下后,首先将相应楼层的DestinyFloor置0,。通过遍历DestinyFloor[]找到相应方向最近的楼层作为下一目标,这里还要注意:当到达电梯目标楼层中的最大楼层是,电梯应将行驶方向反向,再寻找下一个停靠目标。
因为我们不能控制Passengers的行动(实际生活中是这样的,因此我们尽量模拟真实情况),所以我们对Passengers做的修改在此不赘述。但是对Passenger的代码做简要分析。Passenger类中自带了计时器,意味着它的每个实例都有自己的一个计时器,用来计算traveltime。同时,每次电梯停下后会由委托穿个每个实例一个事件,即电梯已经停下。SigmaPassenger进行简单判断就可在电梯停在自己的请求\目标楼层后上\下电梯。
之后考虑disAbled floors[]问题。这个属性是原本就在Elevator中的,只不过没有用到。TA的代码中通过加入lowestfloor 属性,我们认为用disabled floor这个数组就可以实现所有有关楼层的限制,就没有采用TA的方法。
我们还设想,当某一部电梯闲置时间超过一定时间时,它将获得下一个任务的优先权,即不管他的时间多少,都将这个任务分配给它,但是由于时间原因,这部分设想并没有体现在我们的代码中。
7.附一张合作照片,以示纪念