Pair Project: Elevator Scheduler [电梯调度算法的实现和测试] 10061178 刘宇翔
Design and implement an Elevator Scheduler to aim for both correctness and performance, in managed code.
在project 1过后我们立即进入了Pair Project中。
同组人:10061178 刘宇翔 & 10061204 姚铭
通过这次结对编程我体会的结对编程的优点和缺点:
优点:
1、每个人的项目负担会减轻,压力不会太大。
2、可以相互学习相互帮助,互相提高。
3、降低了程序错误的可能性。
缺点:
1、不同的意见导致讨论时间过长导致编写程序的延期。
2、编写程序是不同人的编写习惯不同,需要事先进行约定才能在编写是不会出现不必要的麻烦。
3、每编写一段时间就要相互交换一下信息,确定项目进度,进行起来不像单人编程那样方向。
我的队友姚明的优点和缺点:
优点;
1、热情开朗,知识丰富,心态乐观,一起工作会无形中感染到轻松的心情。
2、学习兴趣很高,思路广,能够提出自己独特的简介。
3、乐于助人,总是能够给我许多很好的帮助和建议。
缺点:
1、做事有时候太心急、欠考虑,编程有时会走一些弯路。
关于 Information Hiding(信息隐蔽)、interface design(接口设计) 和loose coupling (松耦合)
Information Hiding:信息隐藏指的是在设计模块时将某些特定的信息,包括属性或方法隐藏起来,对于不需要这些信息的其他类来说是不可访问的。信
息隐藏提高了数据的安全性,避免了信息在无关的其他地方被非法更改,也有益于程序模块化的设计。在面向对象方法中,信息隐蔽是通过对象的封装性
来实现的。信息隐蔽的概念与模块的独立性直接相关。
在本次编程过程中,定义了许多诸如电梯,乘客,搭乘请求的接口,并将接口封装到commons.cs文件中,在program,elevator等上都有应用。
Interface design:接口是把公共的非静态方法和属性组合起来,以封装特定功能的一个集合。一旦定义了接口,就可以在类中实现它。
实际工程中,当我们遇到模块中一些固定的特定功能时,我们可以把这些功能封装成接口。一方面我们可以利用这些接口实现固定功能的不同实现方法,使得不同的实现
方法可以更加灵活的运用,另一方面在程序的维护和升级阶段,我们可以扩展接口,实现更加完备的功能,方便特定功能模块的管理。在电梯调度算法scheduler中使用这些接口,继承和拓展原来简单的scheduler,并拓展初始化类和QueueReq类,将各种判断条件从主题函数ru方便)中分离出来,便于以
后修改复用。
loose coupling:模块与模块之间要求是可分拆的、少依赖的(松耦合)。类与类之间通常通过接口的契约实现服务提供者/服务请求者模式,这就是典
型的松耦合。“强内聚、松耦合”对于程序编写分工、程序的可维护性以及测试都有重要的关系。便于以后的继承、修改和复用。
关于Design by Contract 和 Code Contract
契约式设计或者Design by Contract (DbC)是一种设计计算机软件的方法。这种方法要求软件设计者为软件组件定义正式的,精确的并且可验证
的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。这种方法的名字里用到的“契约”或者说“契约”是一种比喻,因为它和
商业契约的情况有点类似。契约式设计是一个软件范例,使用它可以确保你的编码的错误更少。它通过执行“契约”来达到这一步。当你输入参数(前提
条 件)时,你期望得到什么,当你退出(后置条件)时又会产生什么样的结果,这些功能决定了一份契约的订立。例如,在函数int factorial(int n)
中,你希望n是正的(前提条件),也希望它会产生一个正值(后置条件)。
契约式设计的三个关键词
一、前置条件(precondiction):为了调用函数,必须为真的条件,在其违反时,函数决不调用,传递好数据时调用者的责任。
二、后置条件 (postcondion):函数保证能做到的事情,函数完成式的状态,函数有这一事实表示它会结束,不会无休止的循环
三、类不变项(class invariant):从调用者的角度来看,该条件总是为真,在函数的内部处理过程中,不变项可以为变,但在函数结束后,控制返回
调用者时,不变项必须为真。
优点:
契约能使文档更出色;契约是类特性的公开视图中的固有成分;
有着更可靠的文档,运行时要检查断言,以便保证制定的契约与程序的实际运行情况一致;
断言定义了测试的预期结果,并且由代码进行维护,使程序有明确的测试指导;
既能够获得精确规范得到的益处,同时还使得程序员继续以他们所熟悉的方式工作。
缺点:
断言不能沿着继承层次往下遗传。如果你重新定义 了某个具有合约的基类方法,实现该合约的的断言不会被正确调用(除非你再新的代码中复制他们),你必须手工调类不变项,基本的合约不会主动实现。
程序代码合约(Code Contracts)是.NET Framework 4.0的新功能,它是微软对契约式编程(Design by contract)概念所提出的一种解决方案,主要由前置条件(Preconditions)、后置条件(Postconditions)、与对象非变异(Object Invariants)这三大契约所构成,可以很容易的为程序代码加入验证程序代码,降低程序的错误发生率,提高程序的质量,也可以整合单元测试,减少单元测试的工作量,甚至整合文档管理器,让产出的程序文件更为详细。
使用Code Contracts主要可让我们享有下列四项特点:
1、提升自动测试程度
2、静态验证
3、执行阶段验证
4、文件产生
关于 unit test
VS2012中unit test的问题详见我上一篇博客。
UML 图:
算法说明:
算法概要
初步的算法和现实中的电梯差不多。首先根据电梯当前的状态,若电梯目前静止,检查电梯上下方是否有请求,若存在,寻找距离电梯最近的请求层数作为目标。
若电梯此时正在上行,检测其上方是否有请求,选择符合停止条件且最近的楼层作为目标。当达到最高层或某层以上再无请求时,运行方向置为no。
若电梯正在下行,情况与电梯上行的情况类似,方向相反。考虑到需求中说用户从0层和1层上电梯的较多的情况,进行了一个小优化,当电梯空闲时使其运行到1层。起初设计的是运行到0层或1层(取0,1随机数),但考虑到0,1概率基本相等且若存在高层请求时1层距其更近,改为了运行到1层。进行实际测试结果符合预测。另一方面,考虑到体重限制,原本电梯剩余容量小于45kg即不再载客。但考虑到某些情况剩余容量稍大于45但也不多的情况下载客量有限,不利于平均时间的优化,我们适当加大了容量限制,即大于100kg再载客。通过实际检测,效率确实可以快一点。