一、Github项目地址:https://github.com/blanche789/wordCount/tree/master/src/main/java/com/blanche
二、PSP表格
PSP2.1 |
任务内容 |
计划完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
45 |
40 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
45 |
40 |
Development |
开发 |
880 |
940 |
Analysis |
需求分析 (包括学习新技术) |
60 |
90 |
Design Spec |
生成设计文档 |
30 |
- |
Design Review |
设计复审 (和同事审核设计文档) |
10 |
- |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
40 |
40 |
Design |
具体设计 |
60 |
80 |
Coding |
具体编码 |
400 |
500 |
Code Review |
代码复审 |
30 |
30 |
est |
测试(自我测试,修改代码,提交修改) |
250 |
200 |
Reporting |
报告 |
450 |
450 |
Test Report |
测试报告 |
360 |
370 |
Size Measurement |
计算工作量 |
30 |
- |
Postmortem & Process Improvement Plan |
事后总结 ,并提出过程改进计划 |
60 |
80 |
Summary |
合计 |
1375 |
1430 |
三、解题思路描述
1、陌生的开发需求:在刚拿到这个题目的时候,总体来说是比较抽象的;因为在以往的开发中,都是以图形界面作为主要交互方式的,但是此次是要以命令行的控制指令进行交互,所以整个开发流程的架构就需要有所改变。在以往,都是先写出图像界面,然后再对相应的界面交互做出相应;而此次面对命令开发的话,需要以main函数为中心,当传入命令时,调用相应的逻辑进行操作
2、架构设计:本项目我还是采用传统的MVC开发模式来进行开发的,只不过此次的view为辅,以main函数为主;本次项目分了大概三层,main函数为一层(代码的入口)、view作为一层(满足-s需求)、service为一层(各种需求逻辑的处理)。其中以service层为主,进行逻辑处理
3、提供接口:由于本次的需求有六个(六条指令),其中有涉及到输出统计结果的有四个需求。因此,我在service层下设计了四个service的实现类(implement),主要来解决四个指令的需求。由于四个实现类的方法都相同,因此我设计了一个接口。采用了Java中多态的思想,方便通过调用接口来调用四个实现类的方法,避免代码的冗余
4、正则表达式的复习:当我看到需求中有代码行、注释行、空行时,我明白肯定需要有正则表达式来对相应的读取到的字符串进行匹配与判断,所以需要学习正则表达式的知识。其次需要判断Java有关String的API中有哪些方法时通过正则表达式来匹配字符串的
5、枚举:由于有多条指令,若一条条指令都需要去判断调用那个实体类,将会增加时间复杂度。所以我先通过枚举存放八条指令,而后通过Map来绑定指令和相应的service,在处理逻辑的时候,通过key-value的方式就可以通过相应的指令来获取相应的service的实体类,减少了遍历
6、文件判断:由于用户输入文件时可能是目录也可能是文件,所以在进行判断时是比较复杂的,需要根据不同的输入来进行不同的处理,除此之外,还要额外考虑是否需要递归,这几层逻辑加起来难度就上升了,在这里需要对用户输入的文件名进行解析,从而来进行文件的操作
四、设计实现过程
1、流程图:
2、流程图解析:当运行程序时,用户输入相应的指令(例:-c [fileName]),从而调用main函数,main首先会判断是否需要调用图形界面和是否需要进行递归,方便后续进行不同的操作。然后会根据文件名判断当前文件是否可读;若可读,则调用read函数,传递文件和指令进入这个函数,然后根据指令调用相对于的service对文件进行读操作,从而来对其进行相应的WordCount;若不可读,则会通过正则表达式判断文件名是否含有通配符,若符合条件,则获取其所在的目录,若可递归,则进行递归操作,若不可递归,则对该目录下的所有文件进行WordCount;
3、类的目录结构
4、测试
4.1测试文件
4.2测试结果
4.3代码覆盖率
4.4代码覆盖率细节
5、图形界面
四、总结
本次的个人项目虽然是一个小型的练手项目,但是于我而言,它不仅仅是一个从0到1的过程
在0到1的这个过程中,我融入了软件工程的思想,严格按照PSP表来对整个项目进行规划、架构,于我而言,这个过程是有些繁琐与陌生的,与以往一拿到需求就开发的过程是截然不同的,在这个过程中,我更加明白了前期进行规划的重要性,规划看似在浪费时间,但其实好的规划会让我们的开发达到事半功倍的结果
除此之外,我在此次开发中,多次运用到测试代码,这减少了我在开发过程中处理异常的时间;每当我书写好一个函数或者遇到瓶颈的时候,我就会通过测试代码,来进行测试,从而解决自己的问题,我认为培养在开发中注重测试实例的能力是非常有效的
其次是代码覆盖率,本次的代码覆盖率在类和方法上覆盖率基本达到了要求。但是在代码line的覆盖率上还是比较小,基于原因,还是因为加入了太多的判断条件,导致在测试的时候,不符合条件的代码未被调用,这也提示我在今后的开发过程中,尽量减少条件的判断来实现自己的需求,提高代码的覆盖率。