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

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

这个作业属于哪个课程软件工程实践-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. 心得体会

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

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我们开始微信小程序实战篇-个人中心、订单制作的教程。 ## 1. 创建个人中心页面 首先,我们需要在小程序中创建一个个人中心页面。可以在 app.json 中添加一个 tab 标签,在 pages 数组中添加个人中心页面的路径: ```json { "tabBar": { "list": [ { "pagePath": "pages/index/index", "text": "首页" }, { "pagePath": "pages/personal/personal", "text": "个人中心" } ] }, "pages": [ "pages/index/index", "pages/personal/personal" ] } ``` 接下来,在 pages 文件夹中创建 personal 文件夹,并创建 personal.wxml、personal.wxss、personal.js、personal.json 四个文件。在 personal.wxml 文件中添加以下代码: ```html <view class="personal"> <view class="avatar"> <image class="avatar-img" src="{{avatarUrl}}"></image> <text class="nickname">{{nickname}}</text> </view> <view class="order"> <view class="order-item" bindtap="goToOrder"> <image class="order-icon" src="/images/personal/order.png"></image> <text class="order-text">我的订单</text> <image class="order-arrow" src="/images/personal/arrow.png"></image> </view> </view> </view> ``` 这里我们创建了一个包含头像、昵称、我的订单等模块的页面。其中,头像和昵称是从后端接口获取的数据。 ```javascript // personal.js Page({ data: { avatarUrl: '', nickname: '' }, onLoad: function () { // 从后端接口获取用户信息 wx.request({ url: 'https://example.com/userinfo', success: (res) => { this.setData({ avatarUrl: res.data.avatarUrl, nickname: res.data.nickname }) } }) }, goToOrder: function () { // 跳转到订单页面 wx.navigateTo({ url: '/pages/order/order' }) } }) ``` 在 personal.js 文件中,我们编写了 onLoad 和 goToOrder 两个函数。onLoad 函数用于从后端接口获取用户信息并在页面上显示,goToOrder 函数用于跳转到订单页面。 ## 2. 创建订单页面 接下来,我们需要创建一个订单页面。在 pages 文件夹中创建 order 文件夹,并创建 order.wxml、order.wxss、order.js、order.json 四个文件。在 order.wxml 文件中添加以下代码: ```html <view class="order"> <view class="order-header"> <text class="order-title">我的订单</text> <text class="order-more">查看更多</text> </view> <view class="order-list"> <view class="order-item" wx:for="{{orders}}" wx:key="index"> <image class="order-img" src="{{item.imgUrl}}"></image> <view class="order-info"> <text class="order-name">{{item.name}}</text> <text class="order-price">¥{{item.price}}</text> </view> </view> </view> </view> ``` 这里我们创建了一个包含订单标题、订单列表等模块的页面。其中,订单列表是从后端接口获取的数据。 ```javascript // order.js Page({ data: { orders: [] }, onLoad: function () { // 从后端接口获取订单列表 wx.request({ url: 'https://example.com/orders', success: (res) => { this.setData({ orders: res.data }) } }) } }) ``` 在 order.js 文件中,我们编写了 onLoad 函数用于从后端接口获取订单列表并在页面上显示。 ## 3. 页面样式 最后,我们需要编写页面的样式。在 app.wxss 中添加以下代码: ```css .tab-bar { position: fixed; bottom: 0; left: 0; width: 100%; height: 50rpx; background-color: #fff; border-top: 1rpx solid #e5e5e5; box-shadow: 0 -2rpx 6rpx rgba(0, 0, 0, 0.05); } .tab-bar-item { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; font-size: 20rpx; color: #8a8a8a; } .tab-bar-item.active { color: #007aff; } .personal { display: flex; flex-direction: column; align-items: center; justify-content: center; margin-top: 20rpx; } .avatar { display: flex; flex-direction: column; align-items: center; justify-content: center; } .avatar-img { width: 80rpx; height: 80rpx; border-radius: 50%; } .nickname { margin-top: 10rpx; font-size: 24rpx; font-weight: bold; } .order { margin-top: 20rpx; } .order-item { display: flex; flex-direction: row; align-items: center; justify-content: space-between; width: 90%; height: 80rpx; background-color: #fff; border-radius: 10rpx; box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.05); padding: 20rpx; margin-bottom: 20rpx; } .order-icon { width: 40rpx; height: 40rpx; } .order-text { font-size: 28rpx; font-weight: bold; } .order-arrow { width: 20rpx; height: 20rpx; } ``` 在 order.wxss 中添加以下代码: ```css .order { margin-top: 20rpx; } .order-header { display: flex; flex-direction: row; align-items: center; justify-content: space-between; padding: 20rpx; background-color: #fff; border-radius: 10rpx; box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.05); margin-bottom: 20rpx; } .order-title { font-size: 32rpx; font-weight: bold; } .order-more { font-size: 24rpx; color: #007aff; } .order-list { display: flex; flex-direction: column; align-items: center; justify-content: center; } .order-item { display: flex; flex-direction: row; align-items: center; justify-content: space-between; width: 90%; height: 120rpx; background-color: #fff; border-radius: 10rpx; box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.05); padding: 20rpx; margin-bottom: 20rpx; } .order-img { width: 80rpx; height: 80rpx; border-radius: 10rpx; } .order-info { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; margin-left: 20rpx; } .order-name { font-size: 28rpx; font-weight: bold; } .order-price { margin-top: 10rpx; font-size: 24rpx; color: #007aff; } ``` 至此,我们完成了微信小程序实战篇-个人中心、订单制作的教程。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值