[现代程序设计]homework-03
Homework-03
队员: 11061193 薛亚杰 11061192 周敏轩 11061190 李孟
材料阅读
我们三个人将以下材料仔细阅读,觉得十分受益。下面是我们的总结和分享:
1)代码规范与代码复审
代码规范:一句话,我们的代码是要让其他人轻易看懂。
这就要求什么?
当我们拿汉语来作类比的时候,我们就能理解这个问题。为什么我们能交流无障碍?因为所有中国人都看得懂中文字!为什么?因为有一本字典(其实就是规范)告诉我们哪个字是什么意思,组成一个词又是什么意思?这个词怎么读?有些方言没有字典怎么办?不成文的约定!虽然没写在纸上,但是大家都知道这是什么意思。而历史流传保留下来的这些语言,之所以还能保留,自有它的道理(不是语言学家,只能这么搪塞,估计是它的易记易理解吧)。代码就是人使用编程语言写出来的一段话,别人一看就能理解。就像别人一听你说话就知道你在说什么,你在这个群体中才能无障碍生存一样,你所写的代码才能被大家所接受。规范,不就是有点科学道理的习惯吗?这样做好,大家都这样做去,都接受了不就是规范了吗?
下面我们来列举几个被推荐的代码规范:
缩进:4个空格
括号:在逻辑复杂的地方用括号清楚地区分优先级
分行:不要把不同的变量定义在一行上
命名:匈牙利法
具体还是参见伟大的邹老师博客 吧。。
代码复审:
看代码是否在“代码规范”的框架内正确地解决了问题。
查查代码再调bug,也许bug已经少了很多了。还有,一般人对于自己写的代码“喜爱有加”,找小伙伴帮你看看吧~
2)结对编程
结对编程,可以说是一个新颖又熟悉的概念。新颖,在于我们这学期才开始接触到这样一个说法;熟悉,在于我们已经在《软件工程》课上实践了这样一种方法。结对编程是极限编程的其中一种具体方法。所谓极限编程,就是将所有有效的好的方法发挥到极致!而所谓结对编程,从形式上理解就是,一对程序员肩并肩地、平等地、互补地进行开发工作。两个程序员并排坐在一台电脑前,面对同一个显示器,使用同一个键盘,同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起单元测试,一起集成测试,一起写文档等。对,合二为一!我们可以看到生活中很多例子:
越野赛车(驾驶,领航员)
驾驶飞机(驾驶,副驾驶)
战斗机的编组(长机,僚机)
这些工作都极具挑战性和危险性,不容闪失。领航员发出准确指令告诉驾驶员方位、速度,驾驶员马上反应并精确操作,这是他们成功的关键。在比赛的时候他们是将两个人的两个脑子,两个人的两双眼睛,两个人的双手合并成:一个人的两个脑子,一个人的四只眼睛,一个人的四双手!(说的有点恐怖了。。。但是这不就是特异功能吗?不就是强大的外星人吗。。?)而当我们从具体工作上去理解结对编程的时候,我们发现结对编程可能主要在于这样几点优势:
a)工作热情。相信我们每个人都有这样的经验,当有一个人和你并肩作战的时候,你能工作得更久更有热情!这个激情贯穿在我们三个人本次结对编程作业的始终!(虽然是三个人,只要践行结对编程的理念就该算是结对编程)。
b)代码错误率低。当自己一个人码代码,即便是写文档,你总会有疏忽大意的地方。你也许着急把它写完,但当这时有个人在你背后仔细看着你屏幕上被敲出来的符号,不说大的,小的毛病比如大小写、标点符号,这种在后期也许可能让你调了3天最后吐血的错误就很大可能在被输入的2s内被删除!总之,两个人盯着,比一个人瞎打好多了!
c)难题解决率高。结对编程有利于解决难题,原因在于一方面是两个脑子在思考,碰撞还能出火花。一方面是意志的相互鼓舞、激励!
当然,好方法要用在好地方。当一个人是计算机系大牛的,一个人练vs都不知道怎么打开,怎么结对?配对还行。。
3)给人提意见的方式-送一个汉堡包
说道汉堡包,实在是老生常谈了。“三明治”,“汉堡包”,或许。。。“肉夹馍”,都一个意思。就是告诉你说话要委婉。先扬后抑再扬,先找出可夸赞的点,先表扬下。以让暴风雨来得不那么难以承受。接下来把真正要说的话说出来,说的时候还不能太直接。最后说两句好听的,给个台阶下。同是程序猿,相煎何太急啊。
例如:(小X在办公室里开小差)
领导:今天开会之前呢,我首先要表扬下小X,他每天都在办公室待到很晚才回家。这种精神是非常值得表扬啊。不过小X啊,可能你这个效率还有待提升啊。如果在办公室里能够更加专心地做工作,不用太多,加一点点(做手势,右手食指与大拇指捏拢,表情到位)就好,我是说你已经很棒了,只需要再加一点点,你的工作会更加的出色。这样你可以早点下班,回家休息。也有助于你身体健康啊。工作重要,也不能亏待身体啊!
当然,还可以以关心的口吻表达你的意见。
例如:(小x工作不上心,拖团队进度)
领导:小x啊,你最近工作进度有点落后了,这段时间是不是家里有什么事儿?看你心情也不是特别开朗?没事,我虽然是你领导,但是我更是你朋友。有什么情况直接跟我说,我能帮你的我肯定做到。你看呢,咱们这进度也一直比较赶。大家都在拼命干活。你赶紧把你的问题处理了,平复下心情,抓紧回到队伍中来啊。如果有特殊情况,不要藏在心里,咱们这么多人呢。大家是一个团队,就是一家人。
你现在使用的代码规范是什么, 和上课前有什么改进?
我们从homework-2中选出了较为优秀的作业(verybigman),该作业用的是c++,然后我们现在用的代码是c#,因为对于UI的设计,基于c++的MFC我们不会用。好多声音说微软已经基本放弃MFC这边了。这次使用的语言是c#,虽然c#这门语言我们几个都是第一次接触,但是因为java的基础,对于用winform来跑UI还是,熟悉起来还是挺快的。
现在使用的代码规范,除了UI部分的设计,算法方面基本上是面向过程的思想,UI方面不可避免的要用的Form类和各种控件类,我们只好一一学习并掌握。
后来根据老师的提示,我们采用了将maxsum逻辑封装成类库,在form中单纯调用的方式,这样可以保证maxsum这部分逻辑在其他代码中也可以使用,也在一定程度上体现了一点点面向对象的思想
你的同伴有哪些优点 (列出至少三点), 和那些需要改进的地方 (列出至少三点)
薛亚杰同学:
优点:写代码能力出众,学习能力出众,检查代码时很耐心
需要改进的地方:实现代码有时过于急躁,真找不出其他地方了。。。
李孟同学:
优点:善于查资料,分析资料能力强,逻辑好
需要改进的地方:太忙了,算法实现能力有待提升。。
你的代码从 作业2 到 作业3 经历了哪些变化? 哪些代码需要重构 (看关于代码重构的资料), 哪些需要重写, 为什么?
因为作业3中要求将选取的最大子数组标注出来,所以算法部分就必须要记录最大子数组的位置。在这一部分我们就做了一些改变:
c++->c#关于数组的定义需要有改变;c++->c#对于输入文件错误的处理也简单了一点,因为c#只有readline,所以这里我们采用了string的split方法处理输入
需要重构的部分;另外每个计算最大子数组的地方都需要稍微改进记录最大子数组位置的地方
还有需要将maxsum部分封装成类库,重写的部分就是关于输入的处理。同时我们需要用一个标记数组mark[,]来记录需要标注的地方
你的设计是如何保证不同的 maxsum.exe 命令行最后在一个GUI 的界面显示的? (C++ 的设计模式中有 singleton 的概念, 说明一个类的实例如何在一个进程中保持单例, 我们这里谈的是软件如何在操作系统中保持 singleton)
”单例模式”是第一次知道,也是第一次实践.
相比较而言如果在程序启动之后,单纯的添加tabpage会简单许多,但这里的要求多次启动程序只会有一个程序在运行,每次程序运行的结果以新的tabpage的方式呈现,就是一个比较大的难点了。
查阅了许多资料,也实践了很多方法,去csdn求助过,在图书馆看了大量的书,失败过好多次,最后针对这一问题我才用了c#的消息处理机制来实现
首先,
Process current = Process.GetCurrentProcess();
var runningProcess = Process.GetProcessesByName(current.ProcessName).FirstOrDefault(p => p.Id != current.Id);
利用runningProcess是否为null来判断是不是首次执行该程序,如果是首次执行,那么直接new 一个Form类的实例就好;如果不是首次执行,那么就需要sendMessage,然后在Form1.cs中对于Message进行相应处理就好.这里遇到的一个大的问题是需要将Main函数的命令行参数传入,而Message的LParam本身比较特殊,搜了很多资料之后查到,这里我们需要新定义一个结构体然后传递这个结构体的指针;我们曾经尝试过在结构体中定义stirng[]数组来传args[],但是失败了,最后决定将args[]用space分隔拼接成一个string传入,然后在Form1.cs中进行相应的字符串处理,结果成功!
在Form1.cs中定义一个全局的TabControl,在Form的构造函数和消息处理WndProc中分别构建一个新的tabpage然后跑算法画图,这样就成功的实现了c#中的单例模式!
当然, 请继续记录时间的估计和你实际的用时:
Personal Software Process Stages | 时间百分比(%) | 实际花费的时间 (分钟) | 原来估计的时间 (分钟) | |
Planning | 计划 | 2.0 | 45 | 60 |
· Estimate | · 估计这个任务需要多少时间,把工作细化并大致排序 | 2.0 | 45 | 60 |
Development | 开发 | 88.7 | 2000 | 1500 |
· Analysis | · 需求分析 (包括学习新技术) | 2.7 | 60 | 60 |
· Design Spec | · 生成设计文档 | 0 | 0 | 0 |
· Design Review | · 设计复审 (和同事审核设计文档) | 0 | 0 | 0 |
· Coding Standard | · 代码规范 (制定合适的规范) | 5.3 | 120 | 60 |
· Design | · 具体设计 | 5.3 | 120 | 60 |
· Coding | · 具体编码 | 62.1 | 1400 | 1200 |
· Code Review | · 代码复审 | 10.6 | 240 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 2.7 | 60 | 60 |
Reporting | 总结报告 | 9.3 | 210 | 60 |
· Test Report | · 测试报告 | 5.3 | 120 | 0 |
· Size Measurement | · 计算工作量 | 1.3 | 30 | 0 |
· Postmortem & Improvement Plan | · 事后总结, 并提出改进 | 2.7 | 60 | 60 |
Total | 总计 | 100% | 总用时 | 总估计的用时 |
2255 | 1260 |
以下是这次开发的总结:
这次的homework-03我们忙了三天左右,分头开始学习。第一天将Homework-02的代码从c++移植到c#上,第二天架构了整个UI的设计,并实现了单例模式除外的基本功能,第三天费劲曲折实现单例模式并调试完全,最终看到成果跑出来之后真的是非常激动.
这次的UI设计我们一开始尝试查找有没有现成的表格控件,貌似没有找到?那个datagrid貌似是连数据库的?而我们还没数据库。后来想到干脆用画笔pen画线然后用绝对定位填label,后来发现label无法解决互相遮盖的问题,最后决定用Button,并且发现如果用Button完全可以省略画线过程,于是最后的UI就像图示这样,TabControl中的Tabpage上面动态添加button和状态栏,用户体验完美升级!
关于选做题:选做题部分要求建立一个3D模型,通过鼠标操作实现对游泳圈模型的旋转移动等操作.
由于之前没有3D建模的基础,我们搜集了好多资料,最后决定使用WPF来进行3D设计
现在的进度是理解了light和camera模型,能够处理简单立方体的旋转操作
但对于单单构建一个单纯的游泳圈,还是没有什么思路...
后来我们学会了用ZAM 3D构建圆环模型,就像这样
但是还是不会将数组数据与3D模型结合。。。