个人第3次作业:结对编程

Posted on 2019-10-01 21:51  于丁  阅读(304)  评论(0编辑  收藏  举报

博客要求

内容 地址
Github项目地址 https://github.com/zhibihuayue/PairProgramming/
作业地址 https://edu.cnblogs.com/campus/xnsy/GeographicInformationScience/homework/8658

一、PSP表格估计时间

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

二、项目克隆

  1. 班级仓库
    在这里插入图片描述

2.桌面版GitHub同步至本地

  1. 进入PairProgramming文件夹,新建一个自己使用的文件夹。

  2. 打开VS软件编写

三、代码设计

1.计算模块接口的设计与实现过程

解题思路

骰子游戏注意设置随机数的生成,以及将该随机数与外部输入的数字进行比较,并返回结果

程序实现说明

投骰子游戏,用户先猜取一个骰子数,然后丢骰子,若相同则胜利。
1.用户猜取骰子数板块,不需要用户通过键盘录入,而是通过可视化按钮选猜选骰子数(1-6),同时可在此板块下方实时查看自己选取得数字,并且丢骰子前支持用户重新猜选数字
2.丢骰子游戏主板块,用户在猜选数字后通过“丢骰子”按钮开始游戏,经过丢骰子动画后,显示丢出骰子数与用户游戏胜利情况;
游戏结束后用户可以通过“开始新的游戏”按钮,重置游戏所有窗口开始下一轮。
3.规则说明及结果显示板块,若用户猜对则显示胜利,反之显示失败情况(大或小)
4.若用户未猜取数字,直接丢骰子,将弹出错误提示窗口,引导用户正确游戏。
附加功能
1.游戏局数计数显示
2.操作错误弹窗引导提示
3.一键重置开启新游戏
4.优化操作界面,增加投掷动画,提升游戏趣味性

Design By Contract(契约式设计):

契约式设计就是按照某种规定对一些数据等做出约定,如果超出约定,程序将不再运行,例如要求输入的参数必须满足某种条件。
该程序中
第一个版本A里,若用户输入骰子数不再0-6之间,程序将直接报错提示用户错误,并引导重新输入;
第二个版本B里,若用户未猜测骰子直接丢骰子,程序将弹窗报错并直接return此回游戏,引导用户正确流程“猜选后才可丢骰子”。



即为:设计在正确的输入下,能够得到正确的输出,否则程序将报错。

Information Hiding(信息隐藏):

信息隐藏指在设计和确定模块时,使得一个模块内包含的特定信息(过程或数据),对于不需要这些信息的其他模块来说,是不可访问的

即为:在程序中根据使用情况,合理设置public和Private,准确设置各模块访问权限

Interface Design(接口设计):

对接口的名字,功能,接口与接口间的继承关系进行设计;好的接口设计可以增强代码可读性,易用性,可更改性。
该程序中
我们程序中对骰子1-6模拟建库,封装类库“DataBase”存放骰子数,封装类库“Entity”映射数据,封装类库“DaoLayer”提取所有筛子数据,并在窗体中模拟获取数据源,并构造数据加载。(实际之后窗体程序中未用该数据,仅作练习)


Loose Coupling (松散耦合):

软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及传递的信息。
松散耦合是指使用另一个组件提供服务的一个组件对前者的依赖性不强:它是语言独立的、平台独立的事务。
该程序中仅在最终游戏比对部分(用户预测值与计算机随机值),需要使用到不同模块间数据,总体程序上耦合性不强,各模块间独立性较高。

代码展示(窗体实现核心代码)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using DaoLayer;
using Entity;
namespace Game
{
    public partial class GameFrom : Form
    {
        List<Dice> numList;

        int i = 0;
        public GameFrom()//接口模拟练习
        {
            InitializeComponent();
            DaoDice DiceData = new DaoDice();
            numList = DiceData.getAllDice();//获取骰子数字源

            DataTable dt = new DataTable();
            dt.Columns.Add("Num", Type.GetType("System.String"));//构造数据源


            foreach (Dice stu in numList)
            {
                dt.Rows.Add(stu.Num);
            } //数据加载
        }

        private void Panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void TextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void TextBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void TextBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void Label1_Click(object sender, EventArgs e)
        {

        }

        private void TextBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void Label2_Click(object sender, EventArgs e)
        {

        }

        private void Dice2_TextChanged(object sender, EventArgs e)
        {

        }





        private void Label3_Click(object sender, EventArgs e)
        {


        }

        private void Label4_Click(object sender, EventArgs e)
        {

        }


        private void Label3_Click_1(object sender, EventArgs e)
        {

        }


        private void Button1_Click(object sender, EventArgs e)
        {


            if (i == 0)
            {
                new False().Show();
                return;
            }
            Rollpic.Visible = true;
            Random random = new Random();
            int n = random.Next(1, 6);
            if (n == 1)
            {
                Num.Text = "   1";
            }
            if (n == 2)
            {
                Num.Text = "   2";
            }
            if (n == 3)
            {
                Num.Text = "   3";
            }
            if (n == 4)
            {
                Num.Text = "   4";
            }
            if (n == 5)
            {
                Num.Text = "   5";
            }
            if (n == 6)
            {
                Num.Text = "   6";

            }


            if (n == i)
            {
                Res.Text = "你猜对了";
            }
            if (n > i)
            {
                Res.Text = "你猜小了";
            }
            if (n == i)
            {
                Res.Text = "你猜大了";
            }
        }

        private void Dice1_Click_1(object sender, EventArgs e)
        {
            gues.Text = " 1";
            i = 1;
        }

        private void Dice2_Click(object sender, EventArgs e)
        {
            gues.Text = " 2";
            i = 2;
        }

        private void Dice3_Click(object sender, EventArgs e)
        {
            gues.Text = " 3";
            i = 1;
        }

        private void Dice4_Click(object sender, EventArgs e)
        {
            gues.Text = " 5";
            i = 1;
        }

        private void Dice5_Click(object sender, EventArgs e)
        {
            gues.Text = " 5";
            i = 1;
        }

        private void Dice6_Click(object sender, EventArgs e)
        {
            gues.Text = " 6";
            i = 6;
        }

        public void Rollpic_Click(object sender, EventArgs e)
        {

        }

        private void Button2_Click(object sender, EventArgs e)
        {
            i = 0;

            gues.Text = "预测";
            Res.Text = "游戏结果";
            Num.Text = "";
            Rollpic.Visible = false;
        }

        private void Label4_Click_1(object sender, EventArgs e)
        {

        }
    }
}

2.代码复审

通过自己测试审查自己的代码,以及交换互审对方的代码,最后一起审核阅读版本合并后的代码,说明如下:

1.概要部分

1.代码符合需求和规格说明。对功能的实现非常完善。
2.代码设计有比较周全的考虑。首先,通过将原版本的用户录入读取数据的方式,更改为全窗体按钮式交互。减少输入处理,不需要对输入的格式进行检查,只需数字大小进行判断。
3.代码有较高的可读性。代码根据功能分为了几个不同的类,对功能的划分较为直观,关键部分有详细的注释,但有些部分仍缺少必要的注释,存在一些难以理解的代码。
4.由于代码的分工十分明确,所以易于维护。

2.设计规范部分

1.没有应用常用的设计模式。
2.有较多的硬编码存在,比如在很多的if判断
3.调用已有库的功能较少。
4.尽量删减无用的代码。

3.代码规范部分

1.程序整体代码风格一致。

4.具体代码部分

1.对不同类型的错误进行了处理,在某些地方检查了函数的返回值。
2.没有使用断言。
3.在生成覆盖Num的过程中,没有可导致内存泄漏的地方。

5.效能

1.程序的效能较差,重复50000个词游戏大概要4分钟。
2.程序只有对文件的读写操作,不会超时。没有网络调用。

6.可读性

1.代码的可读性较高,有大量的注释。但仍有个别关键函数缺少必要的注释,读起来难以理解。

7.可测试性

1.代码的单元测试不足。需要增加一些单元测试。
2.没有涉及到数据库、网络、多线程等。

3.模块部分单元测试

总体思路,对窗体程序进行输入显示测试、随机显示测试、输入数据测试、比较正确性测试、错误弹窗测试、结果显示测试等。

输入显示测试

将按钮录入值“i”固定为1,断言测试显示值“gues.text”是否为“1”
第一次测试忘记当初显示为了调整格式对齐,加过一个空格,故测试失败

通过√
将断言测试显示值“gues.text”是否为“ 1”调整后成功

通过√

随机显示测试

提前查看调整格式对齐,使用四个空格,测试成功
将随机骰子值“n”固定为1,断言测试显示值“num.text”是否为“ 1”

通过√

比较正确性测试

正确性1
将猜测值“i”固定为1,随机值“n”固定为1,断言测试显示值“Res.Text”是否为“你猜对了”

通过√
正确性2
将猜测值“i”固定为2,随机值“n”固定为1,断言测试显示值“Res.Text”是否为“你猜大了”

通过√
正确性3
将猜测值“i”固定为1,随机值“n”固定为2,断言测试显示值“Res.Text”是否为“你猜小了”

通过√
错误性1
将猜测值“i”固定为1,随机值“n”固定为1,断言测试显示值“Res.Text”是否为“你猜大了”

通过√
错误性2
将猜测值“i”固定为1,随机值“n”固定为1,断言测试显示值“Res.Text”是否为“你猜小了”

通过√

四、文件上传


五、结对的过程

1.结对成员(姜玖林&于丁)

在这里插入图片描述

2.版本合并

我们组计划做两个不同版本,我根据我队友所做的基础控制台的应用程序版本的基础上,进行对象封装,结构优化,及移植窗体化设计和实现。

3.结果展示

版本A

版本B
游戏界面

错误提示

游戏结果

重置游戏

六、总结

作业过程极好的是我温习了窗体程序设计过程,并且在我与结对队友说明映射接口使用和设计的过程中,使我对接口继承关系的脉络更为清晰,程序总体逻辑不复杂,主要开发时间使用在对界面和功能的优化,以及交互性的提高上。同时结对编程的模式可以很明显的在较短是流程中,互补双方代码和思维设计上的完善度,效率较高,结果较好。