有关结对编程

结对编程:马骏   白帆


 

      好处1,起到了很好的相互督促的作用,不仅是不好意思偷懒,而是打破习惯性的打岔,信息爆炸的时代,我们总是被淹没在信息洪流之中,做一件事情总是不能专心,一会想查邮件,一会想看SNS,一会还想看看手机。但是两个人用一台电脑一起共事的时候,你就没办法用这台电脑干自己别的想干的事情。这也是一种约束吧。

      好处2,在一定范围内,算是能力的相加吧,看同一段代码,相互解释,互相提问题,进度十分快。(相互提问题很关键,有时候你为了给他解释这个东西,就要逼自己弄得很懂,而不是一知半解。这样另一方面促进了你自己的进步。)

      好处3,加快编程的速度,一个人在键盘录入的时候,另一个人可以思考相关的算法,整理思路,然后还不至于太疲惫,这样比一个人的时候效率高了很多。

 

      坏处1,两个人的水平差距有时候导致了很多冲突的发生,对于一个方法的实现,即时有时候算法思路是一致的,但是由于个人编程习惯,以及稍微的思路不清晰地一致就会导致冲突,不得不停下来向对方解释自己为什么要这么做,两个人的沟通和相互信任不是一朝一夕就能完成的。

      坏处2,对于两个水平都不高的程序员进行结对编程活动,无法真正到达预期的效果,对于这个新方式的不熟悉是一个十分大的阻力。


UML图

先画一张大的

再一张是自己的对于Schedule的修改的UML图


算法关键

在 MyScheduler中对于IRequest和IElevator的调度,将未进入电梯的乘客申请进入 _Passenger_Wait并对四个电梯进行一个较优的选择,然后将该乘客装入该电梯,存入elevStop,电梯将要将乘客运往的目标楼层,进一步确定进入电梯的乘客的目标楼层的排序与调度。

其中对_Passenger_Wait的选择方法为:选择一个 HistoryDirection与申请运行方向不违背(相同或者电梯停靠未运行),离其距离最近并且剩余装载量FreeCapacity大于100(测试了一些其他体重的数据,但是最后发现貌似100是一个最好的值,所以就用这个了)或者乘客的平均体重的电梯,让其进入。停靠电梯的处理,这种情形比较多。如果电梯是到达了一个目标楼层后,就在数组_Passenger_Wait里该电梯对应的ArrayList里 面去掉当前电梯所在的楼层。这时候,如果数组_Passenger_Wait里该电梯对应的ArrayList不为空,就是说电梯的还有目标楼层没有到达,那 么就将电梯的下一个目标设为数组_Passenger_Wait里该电梯对应的ArrayList里面最近的那个目标楼层(这里,向上运行的电梯和向下运行的 电梯情况不同);如果数组_Passenger_Wait里该电梯对应的ArrayList为空,即电梯已经完成了之前数组_Passenger_Wait里该电 梯对应的ArrayList里面的所有任务,那么如果这个时候所有楼层里都没有人发出请求了,那么电梯就往第零层和第一层走,如果有请求,那么电梯就去发 出请求的地方接人。

运行电梯的处理,又分为向上运行的电梯和向下运行的电梯,但这是一个对称的过程。如果电梯和电梯目前要前往的目标楼层之间楼层有和电梯运行方 向一样的的方向请求时,并且电梯的剩余重量还大于所有人统计平均质量时,就可以使电梯在这一层里停靠一下,接上发出请求的乘客。接上乘客之 后,乘客就会发出目标请求,目标请求会加入到数组elevStop里该电梯对应的ArrayList里面。

还遗留的问题是,如果电梯在楼层中间运行的时候,比如,电梯在7楼,这时候3楼有请求Up,0楼也有请求Up,但是电梯只下降到3楼就Up了,导致0楼的人有时候会等上一两个小时才会坐上电梯,相当于被“饿死”了。


Information Hiding, interface design, loose coupling的运用

       Information Hiding:信息隐蔽,指在设计和确定模块时,使得一个模块内包含信息(过程或数据),对于不需要这些信息的其他模块来说,是不能访问的。

       Interface desig:接口设计。接口定义实施者必须提供的一组成员的签名。

      下面的准则有助于确保正确设计接口。

      如果一组包含某些值类型的类型需要支持某些常用功能,则必须定义接口。

      避免使用标记接口(没有成员的接口)。

      对于定义的每个接口,请提供至少一个使用该接口的成员(例如,采用该接口作为参数的方法,或类型化为接口的属性)。

      如果从某些其他类型继承的类型需要支持其功能,则考虑定义接口。

      loose coupling:松散耦合,是在一个系统或网络中使各组件互相连接的方法,因此这些组件,也称为元素,在最小的可行范围内彼此依赖。耦合指的是一个元素对另一元素的直接了解程度。

 

信息隐藏:首先,在类中,定义的变量和方法可以再前面加上一个下划线"_"来标识,这是 一个好的命名规范,可以避免无意中对私有成员进行赋值。类与类之间交换信息时,要交流私有变量时,要用事先设计好的方法来访问,这样如果我们在其它类里面 调用另外一个类的私有变量,那么我们必须定义一个获得该类私有变量的方法;要在另一个类里面改变另外一个类里面的变量时,我们也要定义一个改变该类私有变 量的方法。在C#里特别方便的一点就是有set和get,我们可以很方便的定义访问一个类私有变量的方法。

接口设计:一个好的接口能够提供给后面的程序设计一个良好的框架,在这次电梯调度项目里,接口IElevator、IPassenger、 IScheduler、IRequest,我们通过接口能很快的知道电梯、乘客、调度方案、请求都有哪些属性,要实现哪些方法,而不用关心具体的实现细 节;这样我们的软件测试也变得更简单了。

松耦合:在我们的代码设计时,不用担心会破坏其它地方的代码。这种类与类之间依赖性低的设计方法,使一个类与另外一个类仿佛隔开了,它们之间只是通 过消息来联系的,所以设计一类时,可以不用担心破坏另外一个类。当代码有改动时,可以不用大规模的改动我们的代码,我们只用定位于一个出问题的模块,然后 对其进行更改就好了,而且能做到不改变其它模块的服务。

信息隐藏、接口设计、松耦合都是面向对象设计的重要方法,都是使程序设计时更接近日常认识,在大模块之间关系中不用过于担心细节,只需在模块设计时下功夫。

 


 

Design by contract的运用

       Design by Contract的核心是断言(assertion)。所谓“断言”,是指永远为真的布尔型语句,如果不为真,则程序必然存在错误。通常情况下,检查断言的时机,应该局限于调试(debug)阶段,而不是代码的实际执行阶段。实际上,完成的程序永远不应期望断言会被检查。

       Design by Contract使用了三类断言:后继条件(post-conditions),前提条件(pre-conditions),以及不变量(invariants)。

      在程序设计中,使用断言有很多好处,能给程序员带来许多便利。

       举例来说,如果我们定义对某个数的“求平方根”操作,则该操作的后继条件为:input = result * result,这里的result是输出结果,而input是输入的数值。在描述“做什么”(what we do)而不涉及“怎样做”(how we do it)——换言之,将接口和实现分离开来——时,后继条件是非常有用的方法。

       在继承关系中,断言扮演着独特的角色。继承的风险之一在于,开发人员为子类重新定义的行为,可能会违背父类的行为。断言减少了这种风险。对某个类来说,其 不变量和后继条件必须能够应用于所有的子类。子类可以加强这两类断言,而不能削弱它们。而前提条件则只能削弱,而 不能增强。

posted @ 2012-10-22 16:20  Melee7  阅读(158)  评论(3编辑  收藏  举报