1.照片
1.1 结对编程参与者:李文涛、黎柏文
1.2 展示照片
2.结对编程的优点&缺点
2.1 优点
1)提高编码的质量
2)可以促进两个人的相互交流,使得每个人的编程经验得到共享
3)相互监督,效率更高,可以更快的完成项目
2.2 缺点
1)因为结对编程的模式是“一个人在写,另外一个人在看”,相比较于两人分工写不同的模块来说耗费的时间可能会更长一点
2)如果两人的代码风格不一致,写出来的代码可读性会比较差
3)对于一些逻辑、算法方面的观点不一致的话,若引起了争执,会影响到两个人的合作水平进而影响项目进度
2.3 自己的优缺点
1)优点:喜欢钻研,有耐心,有上进心
2)缺点:比较粗心,有些时候急于求成
2.4 对方的优点
1)优点:热爱技术,编码能力强,善于分析问题
2)缺点:太宅
3.怎样利用好的设计方法,如Information Hiding, Interface Design, Loose Coupling
3.1 Information Hidding(信息隐藏)
代码模块应该采用定义良好的接口来封装,这些模块的内部结构应该是程序员的私有财产,外部是不可见的,因此要做到以下的原则:
1) 多层设计中的层与层之间加入接口层
2)所有类与类之间都通过接口类访问
3)类的所有数据成员都是private,所有访问都是通过访问函数实现的
3.2 Interface Design (接口设计)
接口设计的六大原则
1)SRP(Single Responsibility Principle)单一职责原则:每个接口尽量只负责一个单一的功能,防止混乱,避免不必要的麻烦
2)LSP(Liskov Substitution Principle)里氏替换原则(为良好的继承定义了规范):子类必须完全实现父类的方法,子类可以有自己的个性(属性和方法),覆盖或实现父类的
方法时输入参数可以被放大,覆写或实现父类的方法时输出结果可以被缩小
3)DIP(Dependence Inversion Principle)依赖倒置原则:高层模块不应该依赖低层模块,抽象不应该依赖细节,细节应该依赖抽象
4)接口隔离原则:不要建立臃肿庞大的原则,要建立单一的接口,接口应该尽量细化,同时接口中的方法要尽量少
5)LKP(Least Knowledge Principle)最少知识原则:一个类应该对自己需要耦合或调用的类知道得最少
6)开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭
3.3 Loose Coupling (松耦合)
准确的说应该是“强内聚,松耦合”,即程序要模块化,模块的内部各成分之间相关联程度要尽可能高(强内聚),模块与模块之间要是可拆分的,少依赖的(松耦合),耦
合度依赖于:
1)一个模块对另一个模块的调用
2)一个模块向另一个模块传递的数据量
3)一个模块施加到另一个模块的控制的多少
4)模块之间接口的复杂程度
4.Design by Contract, Code Contract (契约式设计,契约编程)
4.1 它们的优点
1)良好的规格有利于实现的时候进行自我检查,防止“跑偏”
2)提高了编码的效率
3)规格以注释的形式呈现,始终保存在代码里面,有利于将来的维护和迭代开发
4.2 它们的缺点
1)如果每个函数都要写规格,会显得十分地繁杂
2)如果一味地追求与规格保持一致,或者说把提前定制好的规格当做《圣经》,容易使得在实现规格的时候缚手缚脚,所以规格应该是动态的,在编码的过程中,必要的
时候应该改变规格
4.3 我是如何将他们融入我的作业
1)在确认好我们的接口中需要实现哪些方法之后,我们没有马上开始写代码,而是花了一晚上的时间完善规格
2)在写代码的时候,经常会有这种情况:在实现函数fun_a的时候,需要一个函数fun_b,然而之前没有写fun_b的规格,所以这个时候就先暂停,把fun_b的规格补上,
然后再实现fun_b
3) 在CodeReview阶段,检查每个函数是否实现了规格,主要检查的是Modifies是否满足,是否有额外的Modifies,Effects是否正确实现了等等
5.单元测试
5.1 截图(对于SPath和LTPath针对不同的情形做了5对测试)
5.2 覆盖率
6.UML图
7.算法的实现
7.1 SPath算法
直接使用的Dijkstra算法,用二维矩阵存的图,显然地铁图是稀疏图,应该使用邻接链表比较合算一点,下一次迭代会考虑优化
7.2 LTpath算法
自己摸索出的一个算法,大概流程如下(如果没有说明跳到哪一步,则表示执行下一步):
需要的局部变量:队列q1,记录站点是否被遍历的数组st_flag(初始化为false),记录距离的数组dist,记录换乘次数的数组change;记录路径的方式与Dijkstra算法是一
样的
1)若起始站和终点站共线,则换乘次数为0 ,可以直接输出,否则跳到2)
2)找出起始站的所在的所有路线,把这些路线上的所有换乘点都加入队列q1,记录其换乘次数为1
3)从q1的头部取出一个点,记st_flag[q1.front] = true,判断其是否与终点站共线,若是跳到4),否则跳到5)
4)计算其dist,change值,
5)找出该站的所在的所有路线,把这些路线上的所有换乘点并且st_flag为false的都加入队列q1,记录其换乘次数为该站的换乘次数
+1
6)若q1为空,跳到7),否则跳到3)
7)找出换乘次数change中最小的次数least_change,找出change[i]=least_change且dist最小的那个站,得到其路径
7.3 GUI的实现
1)使用的GUI库:Qt
2)效果图
7.4 源码地址
Github:
8.附加题
详见:
9.引用资料
9.1 参考的博客、文章链接
1)绘制UML图:
2)怎么解释Design By Contract:
3)强内聚与松耦合:
4)接口设计的六大原则:
9.2 原创性声明
本文部分参考了8.1中所罗列的网络资料,其余部分皆为本人原创,欢迎转载和交流,转载请注明出处,请隐去文章中的个人信息