zoukankan      html  css  js  c++  java
  • WordCount-系统分析与设计

    gitee地址

    https://gitee.com/BlankSpace1

    PSP个人流程

     

    PSP2.1

    PSP阶段

    预估耗时

    (分钟)

    实际耗时

    (分钟)

    Planning

    计划

    10

     5

    · Estimate

    · 估计这个任务需要多少时间

     10

     5

    Development

    开发

     235

     

    · Analysis

    · 需求分析 (包括学习新技术)

     60

     30

    · Design Spec

    · 生成设计文档

     30

     0

    · Design Review

    · 设计复审 (和同事审核设计文档)

     30

     0

    · Coding Standard

    · 代码规范 (为目前的开发制定合适的规范)

     10

     10

    · Design

    · 具体设计

     20

     40

    · Coding

    · 具体编码

     60

    300

    · Code Review

    · 代码复审

     15

     0

    · Test

    · 测试(自我测试,修改代码,提交修改)

     10

     30

    Reporting

    报告

     55

     0

    · Test Report

    · 测试报告

     30

     0

    · Size Measurement

    · 计算工作量

     10

     5

    · Postmortem & Process Improvement Plan

    · 事后总结, 并提出过程改进计划

     15

     10

     

    合计

     295

     435

      从表上看,虽然要写文档和报告的没花时间,但是合计的时间任然远大于估计的总时间。主要问题出在了编码,最初快速过了一边需求,我以为写代码要不了多久,的确,写出第一个版本没花多久,但是写出来我不满意,我认为它的扩展性不好,所以又花时间彻底推翻了,重构了一次代码,虽然有了前一次的思路,但是任然话费了大量时间。

     

    基本功能分析

    • 把基本功能在分为几个子功能,他们分别是

    1.  -c 统计字符
    2.  -w 统计单词
    3.  -l  统计行数
    4.  -o 设定输出文件
    5.  参数解析
    • 类图设计 

    设计

    • 算法设计

       1. 字符统计

       

        2. 单词统计

     

        3.统计行数   

          逻辑差不多,与上面类似

     

    代码编写

    • 核心代码  

      考虑到扩展性,利用反射机制和钩子方法实现子类对父类功能的复用和扩展。

    public void printResult(BufferedWriter bw){
             if (countWord) {
                 FIleUtil.writeLine(bw,  outputName+",单词数:"+wordCount+"
    ");
             }
             if (countLine){
                FIleUtil.writeLine(bw,  outputName+",代码行/空行/注释行:"+codeCount+"/"+blankCount+"/"+innoCount+"
    ");
             }
             if (countChar) {
                 FIleUtil.writeLine(bw,  outputName+",字符数:"+charCount+"
    ");
             }
             if (isOverWrited){
                 SonPrint(bw);
             }
        }
    
    public void wordCount(){
        BufferedReader br = null;
        BufferedWriter bw = FIleUtil.getBufWriter(outputName, true);
        Set<String> keys = hashMap.keySet();
        keys.remove("-o");
        try {
            br  = FIleUtil.gerBufReader(inputName);
            String s = br.readLine();
            while (s != null) {
                for (String key : keys) {
                     Field field = this.getClass().getDeclaredField(hashMap.get(key));
                     if ((boolean)field.get(this) == true) {
                         Method method = this.getClass().getDeclaredMethod(hashMap.get(key),String.class);
                         method.invoke(this,s);
                     }
                }
                s = br.readLine();
            }
            printResult(bw);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            FIleUtil.close(br);
            FIleUtil.close(bw);
        }
    }
    
     /**
         * 统计单词
         */
        protected void countWord(String s){
            if (s != null ) {
                String[] split = null;
                split = s.split("\s{1,}|,");
                if (split != null) {
                    for (String word : split) {
                        if (!"".equals(word)) {
                            wordCount++;
                        }
                    }
                }
            }
        }
    
        /**
         *  统计字符数,如果制定文件 则输入到制定文件
         *  没有则输出到    result.txt    路径为当前目录
         */
        public  void countChar(String s){
            if(s != null){
                charCount++;      //回车
                charCount += s.length();
            }
        }
    
        /**
         * 统计行数
         */
        public  void countLine(String s){
            BufferedWriter bw = null;
            BufferedReader bufferedReader = null;
            if (s.contains("//")) {
                innoCount++;
            } else if ("".equals(s)){
                blankCount++;
            } else {
                codeCount++;
            }
        }
    

     测试

    • 设计的测试用例如图
    public class WordCountTest {
    
    
        public static void main(String[] args){
            //不存在的文件   黑盒
           String[] param_noFIle = {"-w", "no.txt", };
           new WordCount().wordCount(param_noFIle);
    
            //不存在的参数  黑盒
           String[] param_no = {"-n", "no.txt", };
           new WordCount().wordCount(param_no);
    
            //黑盒
            String[]  param_nothing = {};
            new WordCount().wordCount(param_nothing);
    
            //黑盒
            String[] params3 = {"-l"};
            new WordCount().wordCount(params3);
    
    
            //白盒测试  -w       bug   多个回车空行导致的空串被统计
           String[] param = {"-w", "aaa.txt", };
           new WordCount().wordCount(param);
    
            //白盒测试  -c
            String[] param_c = {"-c", "bbb.txt", };
            new WordCount().wordCount(param_c);
    
            //白盒测试  -l
            String[] param_l = {"-l","ccc.txt"};
            new WordCount().wordCount(param_l);
    
            //白盒  -c -o
            String[] params = {"-c", "aaa.txt","-o", "bbb.txt"};
            new WordCount().wordCount(params);
    
            //白盒 -c -w -l -o
            String[] params4 = {"-c", "-w","-l","src/cn/blankspace/WordCount.java","-o", "output.txt"};
            new WordCount().wordCount(params4);
        }
    
    }
    

    运行结果展示

     边界测试

     

    白盒测试

     

    总结

      我大部分的时间都花在了写代码上,因为我的方法是先写一个可运行的版本,然后再去重构它。所以编码花的时间要多一些。与以往不同的是,我花了一些时间去设计类图和算法流程图,这是我以前不愿意去干的,先花一些时间去建立模型,理清处编码的编码的思路,反而在一定程度上能加快编码的速度。对于新技术的学习,git是我一直在用的没有花什么学习成本。把jar打包成exe,如果想一口气把教程看完,再来做的确很难。但是通过一步步的跟着做,其实就很简单。

  • 相关阅读:
    mysql in 中使用子查询,会不使用索引而走全表扫描
    java集合之hashMap,初始长度,高并发死锁,java8 hashMap做的性能提升
    简要了解web安全之sql注入
    java之JVM学习--简单了解GC算法
    java之JVM学习--简单理解编译和运行的过程之概览
    java之JVM学习--基本机构
    JDK,JRE,JVM 关系和概念
    SpringAOP源码解析
    数据结构——实现list
    由数据库练习浅析子查询和链接查询
  • 原文地址:https://www.cnblogs.com/mrblankspace/p/9692364.html
Copyright © 2011-2022 走看看