软件工程实践第二次作业-个人实战

这个作业属于哪个课程软件工程实践-2023学年-W班
这个作业要求在哪里软件工程实践第二次作业-个人实战
这个作业的目标完成对世界游泳锦标赛跳水项目相关数据的收集,并实现一个能够对赛事数据进行统计的控制台程序

目录:

  1. Gitcode项目地址
  2. PSP表格
  3. 解题思路描述
  4. 接口设计和实现过程
  5. 关键代码展示
  6. 性能改进
  7. 单元测试
  8. 异常处理
  9. 心得体会

1. Gitcode项目地址

GitCode项目地址

2. PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划2020
• Estimate• 估计这个任务需要多少时间2030
Development开发12401290
• Analysis• 需求分析 (包括学习新技术)300300
• Design Spec• 生成设计文档3030
• Design Review• 设计复审2020
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)2020
• Design• 具体设计3040
• Coding• 具体编码600660
• Code Review• 代码复审6020
• Test• 测试(自我测试,修改代码,提交修改)120150
Reporting报告90120
• Test Repor• 测试报告4060
• Size Measurement• 计算工作量1010
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划3030
合计13901490

3. 解题思路描述

1.收集数据,利用爬虫程序爬取网站数据,并用Gson进行数据的解析。
2.规划代码结构,分为Athletes、Result、ResultDetail三大类功能,io模块的输入输出类,以及数据data。
3.进行各种测试,并修改bug。

4. 实现过程

在这里插入图片描述

如图所示,代码分为三个包data、io、function。其中data用以保存各个比赛项目的json文件;io负责进行对input.txt和output.txt的输入输出;function中则是实现三个功能:输出参赛选手信息、比赛结果、比赛详细结果。

5. 关键代码展示

解析并获取players信息:通过getAthletes()方法解析players.json文件,并将courtryName、fullName、gender赋值给Athletes对象,然后将对象装入Athletes队列中进行输出。

  public static  Queue<Athletes> getAthletes() {
        String CountryName = null;
        Queue<Athletes> athletes = new LinkedList<Athletes>();
        try {
            // 创建Gson对象
            Gson gson = new Gson();
            // 读取json文件
            Reader reader = new FileReader("src/data/players.json");
            JsonElement jsonElement = JsonParser.parseReader(reader);
            JsonArray jsonArray = jsonElement.getAsJsonArray();
            for (JsonElement element : jsonArray) {
                JsonObject jsonObject = element.getAsJsonObject();
                if (jsonObject.has("CountryName")) {
                    CountryName = jsonObject.get("CountryName").getAsString();
                }
                if (jsonObject.has("Participations")) {
                    JsonArray participationsArray = jsonObject.get("Participations").getAsJsonArray();
                    for (JsonElement childElement : participationsArray) {
                        JsonObject childObject = childElement.getAsJsonObject();
                        String fullName = childObject.get("PreferredLastName").getAsString() + " " +
                                childObject.get("PreferredFirstName").getAsString();
                        String Gender;
                        if (childObject.get("Gender").getAsInt() == 0) Gender = "Male";
                        else Gender = "Female";
                        Athletes a=new Athletes();
                        a.setCountry(CountryName);
                        a.setGender(Gender);
                        a.setFullName(fullName);
                        athletes.offer(a);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return athletes;
    }

解析并获取result信息::通过getResult()方法解析相应的json文件,并将相应的姓名、排名、分数信息赋值给Result对象,然后将对象装入Result队列中进行输出。

  public static Queue<Result> getResult(String file){
        try {
            // 创建Gson对象
            Gson gson = new Gson();
            // 读取json文件
            Reader reader = new FileReader("src/data/"+file+".json");
            JsonElement jsonElement = JsonParser.parseReader(reader);
            JsonObject jsonObject = jsonElement.getAsJsonObject();
            Queue<Result> result = new LinkedList<Result>();
            if (jsonObject.has("Heats")) {   //获取比赛信息
                JsonArray HeatsArray = jsonObject.get("Heats").getAsJsonArray();
                for (JsonElement element : HeatsArray) {
                    JsonObject obj = element.getAsJsonObject();
                    if (obj.get("Name").getAsString().equals("Final")) {   //判断是否为决赛

                        if (obj.has("Results")) {
                            JsonArray resultsArray = obj.get("Results").getAsJsonArray();
                            for (JsonElement results : resultsArray) {
                                Result r1=new Result();
                                JsonObject resultObj = results.getAsJsonObject();
                                r1.setFullName(resultObj.get("FullName").getAsString().replace("/","&"));
                                r1.setRank(resultObj.get("Rank").getAsString());
                                JsonArray divesArray = resultObj.get("Dives").getAsJsonArray();
                                String score ="";
                                for (JsonElement dives : divesArray) {
                                    JsonObject diveObj = dives.getAsJsonObject();
                                    score = score + diveObj.get("DivePoints").getAsString() + " + ";
                                }
                                score = score.substring(0,score.length()-3) + " = " +resultObj.get("TotalPoints").getAsString();
                                r1.setScore(score);
                                result.offer(r1);
                            }
                        }
                        break;
                    }
                }
            }
            return result;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

解析并获取ResultDetail信息:通过getResultDetail()方法解析相应的json文件,并将相应的姓名、排名、分数信息赋值给ResultDetail对象,然后将对象装入ResultDetail队列中进行输出。其中应判断是否有初赛、半决赛、决赛信息,若没有相应信息用 * 表示。

   public static Queue<ResultDetail> getResultDetail(String fileName) {
        try {
            // 创建Gson对象
            Gson gson = new Gson();
            // 读取json文件
            Queue<ResultDetail> resultDetails = new LinkedList<ResultDetail>();
            Queue<Result> preliminary = new LinkedList<Result>();
            Queue<Result> semifinal = new LinkedList<Result>();
            Queue<Result> fin = new LinkedList<Result>();
            Reader reader = new FileReader("src/data/"+fileName+".json");
            JsonElement jsonElement = JsonParser.parseReader(reader);
            JsonObject jsonObject = jsonElement.getAsJsonObject();

            if (jsonObject.has("Heats")) {
                JsonArray HeatsArray = jsonObject.get("Heats").getAsJsonArray();
                for (JsonElement element : HeatsArray) {
                    JsonObject obj = element.getAsJsonObject();
                    if (obj.get("Name").getAsString().equals("Preliminary")) {
                        getInfo(obj,preliminary);
                    }
                    else if (obj.get("Name").getAsString().equals("Semifinal")) {
                        getInfo(obj,semifinal);
                    }
                    else {
                        getInfo(obj,fin);
                    }
                }
            }

            if (!preliminary.isEmpty()) {
                Result[] sr=toList(semifinal);
                Result[] fr=toList(fin);
                while (!preliminary.isEmpty()) {
                    ResultDetail rd = new ResultDetail();
                    Result r = preliminary.poll();
                    String fullName =r.getFullName();
                    rd.setFullName( fullName);
                    String rank = r.getRank();
                    rd.setPreliminaryScore(r.getScore());
                    if (sr.length > 0){
                        int i;
                        for (i = 0;i<sr.length;i++) {
                            if(sr[i].getFullName().equals(fullName)) break;
                        }
                        if (i == sr.length) {
                            rank = rank + " | *";
                            rd.setSemifinalScore("*");
                        }
                        else {
                            rank = rank + " | " + sr[i].getRank();
                            rd.setSemifinalScore(sr[i].getScore());
                        }
                    }
                    else {
                        rank = rank + " | *";
                        rd.setSemifinalScore("*");
                    }
                    if (fr.length != 0) {
                        int i;
                        for (i = 0;i<fr.length;i++) {
                            if (fr[i].getFullName().equals(fullName)) break;
                        }
                        if(i == fr.length) {
                            rank = rank + " | *";
                            rd.setFinalScore("*");
                        } else {
                            rank = rank + " | " + fr[i].getRank();
                           rd.setFinalScore(fr[i].getScore());
                        }
                    }
                    else {
                        rank = rank + " | *";
                        rd.setFinalScore("*");
                    }
                    rd.setRank(rank);
                    resultDetails.offer(rd);
                }
            }
            else if (!semifinal.isEmpty()) {
                Result[] fr=toList(fin);
                while (!semifinal.isEmpty()){
                    ResultDetail rd= new ResultDetail();
                    Result sr = semifinal.poll();
                    String fullName = sr.getFullName();
                    rd.setFullName(fullName);
                    String rank = "* | "+sr.getRank();
                    rd.setPreliminaryScore("*");
                    rd.setSemifinalScore(sr.getScore());
                    if (fr.length != 0) {
                        int i;
                        for (i = 0;i<fr.length;i++) {
                            if (fr[i].getFullName().equals(fullName)) break;
                        }
                        if (i == fr.length) {
                            rank = rank + " | *";
                            rd.setFinalScore("*");
                        }
                        else {
                            rank = rank + " | " + fr[i].getRank();
                            rd.setFinalScore(fr[i].getScore());
                        }
                    }
                    else{
                        rank = rank + " | *";
                        rd.setFinalScore("*");
                    }
                    rd.setRank(rank);
                    resultDetails.offer(rd);
                }
            }
            else {
                while (!fin.isEmpty()) {
                    ResultDetail rd = new ResultDetail();
                    Result fr = fin.poll();
                    String fullName = fr.getFullName();
                    rd.setFullName(fullName);
                    String rank = "* | * | "+fr.getRank();
                    rd.setPreliminaryScore("*");
                    rd.setSemifinalScore("*");
                    rd.setFinalScore(fr.getScore());
                    rd.setRank(rank);
                    resultDetails.offer(rd);
                }
            }
            return resultDetails;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

6. 性能改进

1、尽量重用对象,特别是String对象的使用,由于Java虚拟机不仅要花时间生成对象,以后可能还需要花时间对这些对象进行垃圾回收和处理,因此,生成过多的对象将会给程序的性能带来很大的影响。

2、及时关闭流,进行I/O流操作时,要小心谨慎,在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销。还有对应的异常处理也要注意,防止资源泄露。

3、使用带缓冲的输入输出流进行IO操作。带缓冲的输入输出流,即BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,这可以极大地提升IO效率。

4、使用缓存来存放固定的2的数据,以方便在大数据读入时能够更快地输出,提高效率。

5.尽可能进行代码复用,将经常使用的方法、类独立出来进行代码复用以减小系统开销。
在这里插入图片描述

7. 单元测试

7.1测试用例:

Players
player
players
result 123m
result detail
resultwomen 3m springboard
result men 10msynchronised
result women 10m synchronised details
result women 1m springboard
result men 3m springboard
result men 10m platform details
result women 3m springboard
result women 10m platform
result women 3m synchronised details
result women 10m synchronised
result men 1m springboard
result men 3m synchronised
result men 10m synchronised details

7.2单元测试
在这里插入图片描述

8. 异常处理

对IO流的输入输出以及获取比赛信息等都进行了catch捕获处理

   //读取文件
    public Queue<String>  readFile() {
        Queue<String> input = new LinkedList<String>();
        try (FileReader reader = new FileReader(this.pathname);
             BufferedReader br = new BufferedReader(reader)
        ) {
            String line;
            while ((line = br.readLine()) != null) {
                // 一次读入一行数据
            //    System.out.println(line);
                input.offer(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return input;
    }

    //写入文件
    public  void writeFile( Queue<String> output) {
        try {
            String Path=System.getProperty("user.dir");
            File f = new File(Path+"/output.txt");
            BufferedWriter out = new BufferedWriter(new FileWriter(f));
            String str;
            while(!output.isEmpty()){
                str=output.peek();
                output.poll();
                out.write(str+"\n");
                out.flush(); // 把缓存区内容压入文件
            }
            out.close(); // 最后记得关闭文件

        } catch (Exception e) {
              e.printStackTrace();
        }


    }

9. 心得体会

本次作业在入手时会觉得较为困难,获取数据、解析和使用数据、单元测试等内容是让我觉得较为陌生的内容。但在查阅相关的资料和与同学讨论后,问题也就迎刃而解。这次的作业让我学到了很多东西,也让我更加体会到一个成功的项目是来之不易的,在平时的生活中,我们要始终保持学习的态度,学无止境。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐