Peer Programming Project: 4 Elevators Scheduler 学号后三位 157,165

1.Advantages and disanvantages of Peer Programming

  advantages

The code are constantly validated by two people, reducing the possibility of indivudual making stupid mistakes.

    • The code belongs to two people simutaneously, avoiding consulting each other some trivial problem, such as variable definition, occuring too frequently. To some extent, this also abbandoned individualism.
    • Under the supervisoion of your partener, we tend to resolve the tasks from within. The more concentrated, the more efficient. We kind of like one statement about peer programming: While sit besides your partener, the keyboard that lies beneath your hands turns into a piano. It is not you programming a front of your teammate, but performing a pleasing symphony in front of your audience. Wholeheartedly, Peer Programming is really a creative and interesting ways of programming.
    • share experiences and knowledges
  •   Disadvantages
      • need time to get to know each other for better cooperation. May feel uncomfortable at the beginning.
      • Not every situation suit this method.
      • The experienced may become frustrated about fresh-man. The fresh-man, in contrast, may feel too nervous to perform well.
      还有一些在网上看到的,感觉都是会遇到的问题:
        •   喜欢发号施令的人总是对敲键盘的人说:“到末行,加个反括号,然后…”。他不去关注解决方法和下一步该怎么做,而过度关注一些编程细节。
        •   拼写纠错者坐在你旁边,纠正你输入的每个错误字符。当然,他没有时间来真正的进行导航。
        •   深藏不露者仅仅自己敲着代码而不告诉别人他在做什么。领航员不得不靠自己去弄懂代码。关于该用什么方法,该选择哪种设计,领航员和实施者之间完全没有交流。
        •   跳跃很大的人喜欢在代码中进行大范围的跳跃,这样领航员不知道进行到哪里了。
  •   In brief, one should contemplate before conducting peer programming. All in all, just like the <Peopleware> said, human is always the one that we should consider first.

2.Hiding Information,interface design,loose coupling  

  • Information Hiding 

  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在该模块内部进行捕获。

  • Interface Design and loose coupling

  接口设计实现了information hiding(只给用户提供接口让其调用)。这次pair work 中深深体会到了好的接口设计带来的方便。在编程的初期,及时我们不是很清楚整个代码的结构和运行原理,但是只要修改IScheduler,我们写的调度算法就可以很自然地接入到整个系统中。(老师就是老师,写的整个Elevator Framework能够很清楚地分清楚每个模块的功能,并且很好地实现了模块之间的通信,感觉我们的面向对象编程思想还很不成熟,根本达不到老师这样完善。希望以后能够多教授一些这方面技巧)

  我们进行接口设计的目的就是为了各个模块之间的松耦合,两者之间相辅相成。

  这里我们还在网上看到一个值得注意的误区。面向对象接口应该适当的使用。比如当电梯的实现只有一个SenElevator时,就不必再写一个IElevator接口了。千万不要“为了写接口而写接口”。

 

3.Design By Contract 契约式设计

  调用者必须提供正确的参数,被调用者必须保证正确的结果和调用者要求的不变性。

  •   优点: 双方都有必须履行的义务,也有使用的权利,这样就保证了双方代码的质量,提高了软件工程的效率和质量。
  •   缺点
    • 契约式编程需要一种机制来验证契约的成立与否。但是并不是所有的程序语言都有断言机制。那么强行使用语言进行模仿就势必造成代码的冗余和不可读性的提高。比如.NET4.0以前就没有assert的概念,只在4.0后全面引入了契约式编程的概念。
    • 契约式编程并未被标准化,因此项目之间的定义和修改各不一样,给代码造成很大混乱。

4.unit test

我们测试的是elevator类,最后代码覆盖率又90%左右,因为只测试了单一方向,最后乘以二就对了

5.UML

    这是VS搞出来的类图,看了一下还挺靠谱的,贴一个简单的,再贴一个详细的

 

6.算法实现:

 

 

  •   Scheduler:修改scheduler,放弃了StopatEachFloor,使用了新的方法Allocate。Allocate算法不同于BUS调度。每当有外部请求时,调度器会根据每个电梯各自的CurrentFloor计算到达请求楼层所需的时间。然后将四个时间比较得出最短时间,将请求交给时间最短的电梯完成。

     T总 = Tdelay + Trun

     Trun的具体计算方法用if else分支语句分为了7种情况(暂时不考虑disabled floor,<R,请求方向>为请求高度及方向,<D,电梯方向>为电梯高度及方向):

    •   R上,D上,D<R,(上行顺路) t = (R-D)/v
    •   R上,D上,D>R,t = [2*maxfloor(电梯当前要到达的最高楼层)-R-D]/v
    •   R上,D下  t= (D+R-2*minfloor)/v
    •   R下,D上,  t = (2*maxfloor-R-D)/v
    •   R下,D下,D<R,t= (D+R-2*minfloor)/v
    •   R下,D下,D>R,(下行顺路) t=(D-R)/v
    •   D停止  t=|D-R|/v

      注意这里计算使用的是电梯高度而不是楼层进行时间,这非常关键:举个例子,#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.附一张合作照片,以示纪念

posted on 2014-10-16 00:16  皮皮鼠标垫  阅读(308)  评论(2编辑  收藏  举报