系统分析与设计课程项目 WordCount 结对编程

系统分析与设计课程项目 WordCount 结对编程

作业说明

合作者:

201631084230(只有我一个人,“合作者”这个标题有些不合适了)

代码地址:

https://gitee.com/mxhkkk/Wc/tree/complete/

本次作业的链接地址:

https://edu.cnblogs.com/campus/xnsy/2018Systemanalysisanddesign/homework/2188

为什么只有我一个人

个人项目完成后,我看了很多人的作业博客,也评论了很多,但始终没有发出这样一条评论:“我们的程序设计风格很像,结对编程我们一起吧”,确实是没有发这样的评论。后来才发现,团队项目组队因此简单了,一个人再找一个两人组就可以了。

PSP表格

PSP2.1PSP阶段预估耗时(分钟)实际耗时(分钟)
Planning 计划 30 20
Estimate 估计这个任务需要多少时间 30 20
Development 开发 290 640
Analysis 需求分析 (包括学习新技术) 30 20
Design Spec 生成设计文档 0 0
Design Review 设计复审 (和同事审核设计文档) 0 0
Coding Standard 代码规范 (为目前的开发制定合适的规范) 20 20
Design 具体设计 60 240
Coding 具体编码 60 120
Code Review 代码复审 30 90
Test 测试(自我测试,修改代码,提交修改) 90 30
Reporting 报告 90 120
Test Report 测试报告 0 0
Size Measurement 计算工作量 0 0
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30 30
合计470730

自审

  • 命令行参数解析,不准确,没有错误提示信息。我现在意识到这是一个复杂的过程,决定使用CLI来重构。
  • 根据文件名来生成文件的操作类,这也挺复杂的。有三种不同形式的文件,文件名必须是合法的,文件名中可能带有路径,还有文件通配符的处理,是否支持文件夹操作以及文件夹的递归。
  • 统计过程是低效的,在设计和性能之间无法做到很好地权衡。
  • 结果类似乎没有必要应用组合模式。
  • 不能很好地利用流的思想来做设计。

修复问题及关键代码

删除Command层

发现现在的Command类完全变成了一个委托类,删除这一层次。

Parser返回handler的集合,Invoker直接调用handler执行方法。

添加并行策略

删除GUI的调用策略,改为并行和串行两种调用策略。当处理文件有多个且计算机支持并行时采用并行策略,否则采用串行策略。

下面验证一下并行的效果如何:

并行的效果还是很明显的,我测试用的计算机是双核的,如果是四核、八核的计算机那就更快了,因为我在设计中考虑到了伸缩性。

测试文件的地址:https://gitee.com/mxhkkk/Wc/blob/complete/src/test/java/test.zip

有趣的是,测试文件夹大小有60多MB,而压缩后只有不到1MB,这是因为文件夹中有很多重复的文件,为了方便我直接复制进去的。这个现象引发了我对Wc程序的一个思考,我们也可以像压缩软件那样识别相同的文件,来避免重复计算。

并行任务类代码:

private static class Task implements Callable {
private final List handlers;
private final File file;

public Task(List handlers, File file) {
this.handlers = handlers;
this.file = file;
}

@Override
public ResultItems call() throws Exception {
ResultItems items = new ResultItems();
for (AbstractHandler handler : handlers) {
items.add(handler.execute(file));
}
return items;
}
}

将GUI类界面显示与操作职责分离

为WcFrame添加操作类,分离类的职责

为GUI添加取消操作,并提高GUI界面的响应性

为WcFrame添加一个取消按钮,并将计算操作移到其他线程中,提高GUI的页面响应性

WcFrameOper中计算并设置结果的代码:

public void calculateAndSetResult() {
SwingUtilities.invokeLater(() -> frame.setBusyState());

future = exec.submit(new CalculateTask());

String result = null;
try {
result = future.get();
} catch (InterruptedException e) {
result = "任务失败";
} catch (ExecutionException e) {
result = "任务失败";
} catch (CancellationException e) {
result = "任务取消";
}

final String finalResult = result;

SwingUtilities.invokeLater(() -> {
frame.setResult(finalResult);
frame.setLeisureState();
});
}

借鉴流的思想

有些函数式编程思想会使代码更简单,比如集合排序及toString():

@Override
public String toString() {
return items.stream()
.sorted(Comparator.comparingLong(ResultItem::separatorCount).thenComparing(ResultItem::getFileName)
.thenComparingInt(ResultItem::getId))
.parallel().map(ResultItem::toString).collect(Collectors.joining("\r\n"));
}

在单个文件的处理过程中也可以基于流的思想来实现并行,这要求统一handler类的处理过程,并将字符流在多个handler之间传递,但受现在程序结构的限制,实现这一想法是非常困难的。好在有高层次多个文件处理的并行,程序对CPU的利用率还算可以,但在处理单个超大文件时就不适用了。

部分测试代码(使用JUnit4)

CliParser类的部分测试代码

@Before
public void setup() {
FileName.restore();
}

@Test()
public void testGuiFailHasOtherOption() {
String[] args = new String[] { "-x", "-w" };
try {
new CliParser().parse(args);
fail();
} catch (ParseException e) {
assertEquals(ParseExceptionMess.CLI_SYSTEM_MESS, e.getMessage());
}
}

@Test()
public void testGuiFailHasArg() {
String[] args = new String[] { "-x", "code.txt" };
try {
new CliParser().parse(args);
fail();
} catch (ParseException e) {
assertEquals(ParseExceptionMess.GUI_USE_ALONE, e.getMessage());
}
}

handler包的部分测试代码

@Test
public void testExecute() throws IOException {
File stopFile = new File("D:\eclipse_n_java\Wc\src\test\java\com\mxh\wc\handler\stopWord.txt");
Files.getInstance().setStopWordFile(stopFile);

File file = new File("D:\eclipse_n_java\Wc\src\test\java\com\mxh\wc\handler\testStopWords.txt");

SelectWordCountHandler handler = new SelectWordCountHandler();
assertEquals(new ResultItem(file.getPath(), Args.STOP, 20), handler.execute(file));
}

总结

个人编程过程中,会有很多意外的错误,这些错误大多是由于某个细节的疏忽而造成的,结对编程就可以很好地避免这一问题,两人都犯同一个低级错误的概率很小。不得不说,我浪费了一次结对编程的机会。

posted @ 2018-10-17 19:09  MXHKKK  阅读(287)  评论(0)    收藏  举报