结对编程-电梯调度
11061176王洛书-11061148吴文会
一、结对编程
1.1结对编程的优点
结对编程相对于个人编程有很多优点。
首先,督促作用,在讨论过程中能够很快投入工作,为了不耽误对方时间,我们会尽快完成各自的任务;
第二,节约时间,相互交流,能够更快的确定算法方案,比起一个人苦思冥想要来的快得多;
第三,优化算法,两个人的想法结合到一起,取精华弃糟粕,得到双方均认可的算法;
第四,取长补短,有不会的地方随时可以相互询问,学到了新的东西,增进对已有知识的掌握,还能学到一些好的编程习惯。
1.2结对编程的缺点
缺点:一同工作的时间受限;每个人对代码改动后的部分再相互整合较为麻烦。
1.3我们的合作流程
我的合作是这样进行的:
1、拿到题目,两个人在一起读题目,挖掘题目信息;
2、在约定时间内分工读代码,每人各读一半,分别写注释,再交换阅读对方的代码;
3、各自提出对程序的看法,讨论确定算法;
4、在一起编码,其中因为有国庆假期,一个人回家,所以中间有一段休息时间。两人分头写代码;
5、在实际编码中,发现最初讨论的算法并不是很好实现,通过QQ、电话等方式沟通,修改算法,修改代码;
6、原计划国庆结束回校时编好代码,提前完工;
7、一起对代码进行测试和优化;
8、对电梯调度算法基本满意;
9、开始写UI
10、写博客
1.4互评环节
吴文会评:
王洛书的优点:时间观念很强,能够合理安排时间,规划项目进度,才使得我们能够早作准备,作业有计划完成;编程能力很强;善于沟通交流;做事认真细致。
王洛书的缺点:有时效率不高。
王洛书评:
吴文会的优点:做事情非常认真,有钻研精神,在项目中遇到困难时会非常耐心地查阅资料,不达目的不罢休;性格友好,团队合作很愉快;对项目很热情。
吴文会的缺点:有时时间规划性不强。
二、关于Information Hiding, interface design, loose coupling
信息隐藏:
信息隐藏是指仔细地将外部规约与内部实现结合起来以改进设计可见性的一种方法。我们可以通过以下五种方式实现信息隐藏,限制类-模型遍历的范围、不直接访问外部属性、在较高的抽象层次上定义接口、隐藏外部对象、避免级联方法调用。在电梯调度算法的实现和测试中,定义的变量和方法时在名称之前加下划线,可以避免无意中对私有成员进行赋值。类与类之间交流私有变量时,要用事先设计好的方法来访问,如get()、set()方法。
接口设计:
本次作业中commons中是一些接口的设计,接口中没有繁杂的方法实现,而它提供给我们的是程序设计的框架。好的接口利于程序的设计,易于实现,更能让读者一目了然,我们通过接口能很快知道电梯、乘客、调度方案、请求等对象所具有的属性和要实现方法,而不用关心具体的实现细节。
松耦合:
耦合是类之间彼此联系程度的一种定性度量。顾名思义,松耦合架构可以降低整体复杂性和依赖性,每个模块具有各自的独立性,仅通过消息来传递信息,修改其中的某个模块并不会对其他模块造成破坏,方便我们对不同的模块的修改和管理。要更好的利用松耦合,就要选择合适的耦合类型,尽力降低耦合性。
三、关于Design by Contract, Code Contract
3.1
契约式设计或者Design by Contract (DbC)是一种设计计算机软件的方法。这种方法要求软件设计者为软件组合定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。这种方法的名字里用到的“契约”或者说“契约”是一种比喻,因为它和商业契约的情况有点类似。
DbC的核心思想是对软件系统中的元素之间相互合作以及“责任”与“义务”的比喻。这种比喻从商业活动中“客户”与“供应商”达成“契约”而得来。例如:
- 供应商必须提供某种产品(责任),并且他有权期望客户已经付款(权利)。
- 客户必须付款(责任),并且有权得到产品(权利)。
- 契约双方必须履行那些对所有契约都有效的责任,如法律和规定等。
同样的,如果在面向对象中一个类的函数提供了某种功能,那么它要:
- 期望所有调用它的客户模块都保证一定的进入条件:这就是函数的先验条件—客户的义务和供应商的权利,这样它就不用去处理不满足先验条件的情况。
- 保证退出时给出特定的属性:这就是函数的后验条件—供应商的义务,显然也是客户的权利。
- 在进入时假定,并在退出时保持一些特定的属性:不变式。
在我们的代码中,对于模块间使用了契约的思想,保证双方地位的平等。调用者的传入参数必须是正确的,否则责任不在被调用者,而在传入者。
3.2
程序代码合约(Code Contracts)是.NET Framework 4.0的新功能,它是微软对契约式编程(Design by contract)概念所提出的一种解决方案,主 要由前置条件(Preconditions)、后置条件(Postconditions)、与对象非变异(Object Invariants)这三大契约所构成,可以很容易的为程序代码加入验证 程序代码,降低程序的错误发生率,提高程序的质量,也可以整合单元测试,减少单元测试的工作量,甚至整合文档管理器,让产出的程序文件更为详细 。
使用Code Contracts主要可让我们享有下列四项特点:
1、提升自动测试程度
2、静态验证
3、执行阶段验证
4、文件产生
四、unit test
我们的单元测试结果
五、UML
六、算法
我们的电梯调度方案是将电梯分为两种状态讨论:
停靠状态和运动状态。对这两种状态的电梯分别采用不同的调度方法stillElev_manage()和moveElev_manage()。在此之前,我们设置了一个_Target动态数组,用来存储每个电梯的目标楼层。
stillElev_manage()方法的具体思路是:首先判断电梯当前所停靠楼层是否是目标楼层,如果是,从_Target数组中删去当前所在楼层; 如果删除后还有目标楼层,则要根据HistoryDirection从_Target动态数组中选择下一个目标楼层(分四种情况考虑:向上运行,目标在上;向上运行,目标在下;向下运行,目标在下;向下运行:目标在上)。
如果没有目标楼层了,则让电梯全部返回1层(此处经过测试,全部停在一层速度较快);在返回途中可能会遇到新的请求,再对新的请求进行优先级不同的处理,由于电梯在返回1层时,方向向下,所以确定新的目标楼层的顺序是:前方同向的请求优先,后方逆向的请求最后处理。
moveElev_manage()方法的具体思路是:电梯运行时分向上运行和向下运行讨论。
如果向上运行,下一个目标楼层是_Target[0],在前往_Target[0]过程中,如遇有人发出请求,且请求方向一致,发出请求的楼层高度>电梯现高度&&<目标楼层高度,则顺道呼应请求接人;向下运行也是同理,下一个目标楼层是_Target[Count - 1],在前往_Target[0]过程中,如遇有人发出请求,且请求方向一致,发出请求的楼层高度<电梯现高度&&>目标楼层高度,则顺道呼应请求接人。
我们的程序测试passenger1.xml大约用时81s,passenger2.xml大约用时226s,passenger3.xml大约用时180s