结对编程人员:050/184

1 结对编程

  1.1 结对编程的优缺点 

  优点:

  ● 与单独开发相比,结对能够使人们在压力之下保持更好的状态。结对编程鼓励双方保持代码的高质量,即使在出现了让人不得不飞快地编写代码的压力时仍然如此。

  ● 它能够改善代码质量。代码的可读性和可理解性都倾向于上升至团队中最优秀的程序员的水平

  ● 它能够缩短进度时间表。结对往往能够更快地编写代码,代码的错误也更少。这样一来,项目组在项目后期花费在修正缺陷的时间会更少。

  缺点:

  ● 对于有不同习惯的编程人员,可以在一起工作会产生麻烦,甚至矛盾。

  ● 两个人在一起工作可能会出现工作精力不能集中的情况。程序员可能会交谈一些与工作无关的事情,反而分散注意力,导致效率比单人更为低下。

  ● 可能让某些人有滥竽充数的机会。

  1.2 结对伙伴的优缺点

  并肩编程的好伙伴~~!

  

  *我*

  优点是:偶尔比较机智,肯于思考,对算法的设计比较有想法;

  缺点是:约好的时间经常会迟到……,有时候粗心,有时候想得太多……

  *我的小伙伴*

  优点是:比较务实,做事不拖沓,对于编程任务的参与比较积极;

  缺点是:有点小小的选择恐惧症,细节再注意一点,耐心还要多一点。

  总之合作还是很愉快的!两人可以相互提醒,感觉不错,多了一个视角。但是我有时自己想着就陷入自己了……半天回不过神。。。

2 Information Hiding, interface design, loose coupling

  2.1 Information Hiding

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

  信息隐藏是结构化设计与面向对象设计的基础。在结构化中函数的概念和面向对象的封装思想都来源于信息隐藏。软件业对这个原则的认同也是最近十年的事情。
      David Parnas在1972年最早提出信息隐藏的观点。他在论文"On the Criteria To Be Used in Decomposing Systems into Modules"中指出:代码模块应该采用定义良好的接口来封装,这些模块的内部结构应该是程序员的私有财产,外部是不可见的。

  (论文链接:http://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf

  Fred Brooks在《人月神话》的20周年纪念版中承认了当时自己对Parnas的批评是错误的。他说道:“我确信信息隐藏--现在常常内建于面向对象的编程中--是唯一提高设计水平的途径”。
  以下列举了一些信息隐藏原则的应用:
       1.  多层设计中的层与层之间加入接口层;
       2.  所有类与类之间都通过接口类访问;
       3.  类的所有数据成员都是private,所有访问都是通过访问函数实现的。

  2.2 interface design

  每一个大的系统都是有许多模块系统组成的,系统的开发是一个很大的工程,开发起来得难度也是比较大。因此任何一个有一定规模系统,通常会把系统做一定分解降低分析设计开发的难度,模块划分是一个比较常见的方式,而模块与模块之间则是通过接口设计将它们整合在一起的。

  实践中,极有可能出现两种状况:接口维护失控或者过严而死板(而影响开发)。接口失控是因为接口的维护太过随意,因为A模块的需要就轻易在B模块中添加一个接口(方法),导致该接口(方法)非独立性(基本上只给模块A的这个功能点使用),或者是接口的控制过严,导致或者工作效率不高,或者接口的易用性不好。

  一种可行的实践是:不轻易为模块设计对外提供的接口(方法),除非是通过重构得来的;模块对外提供两种类:一个是需要外部模块实现的接口(接口设计从本模块需要出发,当然每个接口尽管是为某个功能点服务,但也要注意其在模块内通用性),另一个是其它模块要求本模块实现的接口的实现类。即:A模块拥有一些需要B模块实现的接口(A模块对B模块的要求),而B模块中也有要求A模块实现的接口,因而A有这些接口的实现类。这种实践方式的好处在于:模块的接口就多了一层隔离降低了耦合,把接口的通用性和接口的适应性分离,又明确了模块的边界,使得接口在日后的优化和调整有了缓冲。

  接口设计的关键是能够将系统的每一个模块能够很好的整合在一起,而且能够让系统能够更好的运行。模块接口设计也是实现系统功能实现整体化的手段,而且是有益于系统拆分、整合等手段所必备的。

  接口设计也有一些可查的原则,依据这些原则,我们能将程序完成得更加规范。

  2.3 loose coupling

  在过去常用的程序架构中,多数应用程序之间直接相互通信。当应用程序需要修改或淘汰时,这种依赖便成为一个实际问题。任何修改都可能会按其自身的方式更新每条唯一的通信线路。因此,这种变更可能代价高昂。这种情况被称为应用程序间的紧耦合,也逐渐成为让一些企业头疼的问题。

  另一方面,SOA(面向服务的体系结构) 将松耦合作为成功的企业级应用程序集成的一个主要原则。与紧耦合相反,松耦合是:

  限制请求者应用程序代码和提供者应用程序代码的相互了解。如果耦合的服务任何方面有所变化,那么,请求者或提供者的应用程序代码(更可能是两者同时)必须改变。如果任何一方(请求者、提供者或中介基础架构)对解耦的服务任何方面作出改变,那么其它几方不必随之改变。

  松耦合系统通常是基于消息的系统,此时客户端和远程服务并不知道对方是如何实现的。客户端和服务之间的通讯由消息的架构支配。只要消息符合协商的架构,则客户端或服务的实现就可以根据需要进行更改,而不必担心会破坏对方。松耦合通讯机制提供了紧耦合机制所没有的许多优点,并且它们有助于降低客户端和远程服务之间的依赖性。但是,紧耦合性通常可以提供性能好处,便于在客户端和服务之间进行更为紧密的集成(这在存在安全性和事务处理要求时,可能是必需的)。

  2.4 总结

  信息隐藏、接口设计、松耦合都是面向对象编程的重要原则。在这次的程序设计中,我们也尽可能的规范变量或方法的属性,不让私有变量或方法泄漏,保证良好的封装性。

对原始代码中一些不严谨的细节我们也做了修改,比如一些无故公用的方法。

3 Design by Contract, Code Contract

  契约式设计或者Design by Contract (DbC)是一种设计计算机软件的方法。这种方法要求软件设计者为软件组件定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。这种方法和商业契约的情况有点类似。所谓契约,也就是合约,规定两个交互物件上的权利和责任。雇佣合同规定你的工作时数和你必须遵守的行为规则,作为公司则付你薪水,双双履行义务,双双受益。DbC的核心思想是对软件系统中的元素之间相互合作以及“责任”与“义务”的比喻。  

  DbC六大原则:

  原则1 区分命令和查询。查询返回一个结果,但不改变对象的可见性质。命令改变对象的状态,但不返回结果。(应当是不一定返回结果)

  原则2 将基本查询同派生查询分开。派生查询可以用基本查询来定义。

  原则3 针对每个派生查询,设定一个后验条件,使用一个或多个基本查询的结果来定义它。这样我们只要知道基本查询的值,也就能知道派生查询的值。    

  原则4 对于每个命令都撰写一个后验条件,规定每个基本查询的值。结合“用基本查询定义派生查询”的原则,我们现在已经能够知道每个命令的全部可视效果。

  原则5 对于每个查询和命令,采用一个合适的先验条件。先验条件限定了客户调用查询和命令的时机。

  原则6 撰写不变式来定义对象的恒定特性。类是某种抽象的体现,应当将注意力集中在最重要的属性上,以帮助读者建立关于类抽象的正确概念模型。  

  DbC对于软件工程是一个极大的理论改革,对于C/S模式造成了极大的影响和冲击。对于C/S模式,我们看待两个模块的地位是不平等的,我们往往要求server非常强大,可以处理一切可能的异常,而对client不闻不问,造成了client代码的低劣。
  而在DbC中,使用者和被调用者地位平等,双方必须彼此履行义务,才可以行驶权利。调用者必须提供正确的参数,被调用者必须保证正确的结果和调用者要求的不变性。双方都有必须履行的义务,也有使用的权利,这样就保证了双方代码的质量,提高了软件工程的效率和质量。

点是对于程序语言有一定的要求,契约式编程需要一种机制来验证契约的成立与否。而断言显然是最好的选择,但是并不是所有的程序语言都有断言机制。那么强行
使用语言进行模仿就势必造成代码的冗余和不可读性的提高。比如.NET4.0以前就没有assert的概念,在4.0后全面引入了契约式编程的概念,使得
契约式编程的可用性大大提高了。此外,契约式编程并未被标准化,因此项目之间的定义和修改各不一样,给代码造成很大混乱,这正是很少在实际中看到契约式编
程应用的原因。

  在我们的编程中,函数间的调用基本运用了契约式编程的思想,要求传入的参数必须满足特定的要求。

4 Unit test

运行测试的结果:

代码覆盖率:

  代码覆盖率只有78.67%,原因是在单元测试中需要自己编写出所有可能的取值,才能保证覆盖。出于时间关系,在编写时类似的语句就没有再进行取值覆盖的过程。

5 UML图

6 算法详解

  6.1 算法关键

  总的来说是模拟现实中电梯的调度。

  程序中有一个总调度器NaiveScheduler,它包含了一个请求队列_PassengerQueue以及供它调度的电梯列表_Elevators。在初始化时,将4个电梯的所有信息都加载到电梯列表里;乘客每次产生一个方向请求,就将该请求添加至总调度器的请求队列_PassengerQueue中。

  对于4个电梯而言,每个电梯都有各自的调度器。我们为电梯类SenElevator增加了一个请求列表。每次进去一个乘客,便会产生一个目的地请求,该请求被添加至这个电梯的调度器的请求列表_allReq里。

  在每一个tick,都对总调度器的请求队列进行遍历,把请求添加到最佳电梯里。具体的做法是每次循环都取队头指令,对于当前请求,依次遍历电梯列表,寻找最佳电梯bestElev。最佳电梯的主要判断依据是电梯的当前楼层CurrentFloor与请求的发出楼层DirectionReqSource距离最近。当然还必须满足乘客限制、电梯容量以及可达到楼层等要求。遍历完电梯列表后,如果能够找到最佳电梯,则将当前请求添加至最佳电梯的请求列表_allReq里;否则将当前请求移至请求队列_PassengerQueue的队尾。

  此外,每一个电梯都实时更新target。具体的做法是每一个tick都遍历请求列表_allReq,对每一个请求的类型加以判断:如果是方向请求,则目标为发出请求的楼层DirectionReqSource;如果是目的地请求,则目标为乘客想到达的楼层DestinationReqDest。找出距离电梯的当前楼层最近的目标,即为电梯的target.

  6.2 独到之处

  由每一层都停靠改为有需求才停靠,节省了大量的时间。

  另外,实时地更新每一个电梯的请求列表(具体的思想是让下一目标距离当前楼层最近)保证了可以顺带地带上顺路的乘客,也对效率有一定的提高。

  后来进行优化时,我们想到可以用一个函数CheckRushHour()实现对与上班高峰和下班高峰的判断。具体的做法是统计一段时间内向上的请求和向下的请求的比值,如果比值超过我们设定的阀值RushHourThresholdValue,则认为当前是上/下班高峰。

  如果是上班高峰,我们让所有闲置的电梯都停到它们的最低层LowestFloor;如果是下班高峰,则让所有闲置的电梯停到它们的最高层HighestFloor。

PairWork-电梯调度程序结对编程的更多相关文章

  1. PairProject-电梯调度程序结对编程

    结对编程人员:184/050 1 结对编程 1.1 结对编程的优缺点 优点: ● 与单独开发相比,结对能够使人们在压力之下保持更好的状态.结对编程鼓励双方保持代码的高质量,即使在出现了让人不得不飞快地 ...

  2. PairWork-电梯调度程序结对编程【附加题】

    1 接口改进 1) 之前判断电梯是否闲置的函数不太好理解,重新修改了,如下所示: //是否停顿状态(停止的以及开门间隔>=0) public bool IsIdle { get { return ...

  3. 关于软件工程结对编程作业 PairProject : Elevator Scheduler(电梯调度算法的实现与测试)的总结

    1)结对编程队友 1106xxxx 张扬 1106xxxx 杨军 其中,此项目的编程实现主要由前者完成. 2)关于结对编程 结对编程的优点: 最直接的一点:在结对编程中,由于有另一个人在你身边和你配合 ...

  4. 11061160_11061151_Pair Project: Elevator Scheduler软件工程结对编程作业总结

    软件工程结对编程作业总结 11061160  顾泽鹏 11061151  庞梦劼 一.关于结对编程 这次的软工任务既不是单打独斗的个人任务,也不是集思广益的团队项目,而是人数为两人的结对编程.两个人合 ...

  5. pair work结对编程(张艺 杨伊)

    一.结对编程人员: 张艺(学号后三位:185) 杨伊(学号后三位:151) 二.这是我们工作的样子:(图片) 三.结对编程优缺点:  优点:  1.结对编程时间紧密,在一定程度上可以督促双方学习,提高 ...

  6. 结对编程 学习手记ver1.2

        团队成员: 226 高雅智 164刘浩然: 一 结对编程 辛辛苦苦搞了好久的时间,就是没有人家的快,明明算法都差不多,哎~~~ 结对的优势,在于双方互相督促,对于代码能贡献自己的能力,人多力量 ...

  7. PairProject——结对编程

    成员:12061162  王骜 12061225  钟毅恒 一.合作过程中的照片 . 二.结对编程的优缺点 优点: 1)在编程过程中,任何一段代码都不断地复审,同时避免了将写代码的责任抛给一个人的问题 ...

  8. 结对编程--基于android平台的黄金点游戏

    游戏内容: 阿超的课都是下午两点钟,这时班上不少的同学都昏昏欲睡,为了让大家兴奋起来,阿超让同学玩一个叫“黄金点”的游戏: N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或1 ...

  9. 结对编程-地铁续(有种上个学期OO的既视感)

    我们组比较特殊..三人结对 github:https://github.com/qingchanghan/WPFUI_Metro po一张照片: 石浩然,韩青长.陈彦吉 (台式机真的很高端,分屏贼帅) ...

随机推荐

  1. 皮肤控件IrisSkin4.dll调用样例-vs2010-c#

    http://blog.csdn.net/wy7980/article/details/41933095

  2. Linux运维之如何查看目录被哪些进程所占用,lsof命令、fuser命令

    之前将一块硬盘挂载到某个目录下,但是现在我想卸载掉这块硬盘,无论如何都umount不了,有些同学可能说需要加上 -f 参数强制卸载,理论上是可以的,但是在我这里依然不起作用,比如: [root@:vg ...

  3. nginx limit_rate突然限速失败

    ##问题 nginx限制用户对指定目录的访问: <!-- lang: shell --> location ~ ^/(path001)/ { limit_rate 0k; limit_co ...

  4. Ubuntu sudo apt-get 安装下载更新软件包命令详解

    sudo apt-get install package                    安装软件包sudo apt-get install package - - reinstall 重新安装 ...

  5. Python脱产8期 Day02

    一 语言分类 机器语言,汇编语言,高级语言(编译和解释) 二 环境变量 1.配置环境变量不是必须的2.配置环境变量的目的:为终端提供执行环境 三Python代码执行的方式 1交互式:.控制台直接编写运 ...

  6. 论文列表 for Action recognition

    要读的论文: https://www.cnblogs.com/hizhaolei/p/10565405.html 骨架动作识别论文汇总 https://blog.csdn.net/bianxuewei ...

  7. FreeRTOS创建任务

    创建任务的函数如下: 第一个参数是:任务函数指针,即任务函数名. 敲黑板:创建任务和任务函数是两码事,一定要分清楚: 第二个参数是:这个参数不被FREE RTOS调用,就是辅助调试用的: 第三个参数是 ...

  8. 博客搬家了qwq

    呃,其实也不是搬家了,应该算是逐渐过渡qwq \[\color{skyblue}{Orchid} \color{purple}{any}\] 好的,我在学校里并不可以用Hexo,因为deploy总是挂 ...

  9. springcloud config

    规则: 一.获取文件属性/{label}/{application}-{profile}.properties/yml http://localhost:8080/master/case-dev.pr ...

  10. php计算utf8字符串长度

    strlen()函数计算中文字符不太友好.扩展的mb_strlen()函数可以补充这个.如果没有这个扩展,也可以利用正则匹配分解. 函数如下: // 对utf-8字符的长度 function utf8 ...