Fork仓库的Github项目地址:https://github.com/Wamnario/PairProgramming.git
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) |
---|---|---|
Planning | 计划 | 30 |
Estimate | 估计这个任务需要多少时间 | 30 |
Development | 开发 | 90 |
Analysis | 需求分析 | 60 |
Design Spec | 生成设计文档 | 60 |
Design Review | 设计复审 | 30 |
Coding Standard | 代码规范 | 60 |
Design | 具体设计 | 60 |
Coding | 具体编码 | 90 |
Code Review | 代码复审 | 60 |
Test | 测试 | 30 |
Reporting | 报告 | 60 |
Test Report | 测试报告 | 30 |
Size Measurement | 计算工作量 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 |
Sum | 合计 | 780 |
程序设计
窗体设计
一个好的程序首先从界面的美感开始。创建好 WinForm 之后合理使用 ToolBox 里的工具进行设计。主要有对所有学生姓名、学号的存放,会用到 DataGridView .其次是随机抽取学生功能,只需要一个名为 "随机抽取" 的 Button 即可。抽取到随机学生后,可进行学生事务处理,比如他是否缺勤,故应该有"缺勤"button.以记该学生缺勤。窗体设计这部分交给Partner来设计。
代码设计
刚拿到项目脑子里大概有一些东西,因为以前有当过某科技公司名下的补习机构的助教,有见过他们的点名系统。大概功能我是知道的,而且这次软件还会更简单。老师也有在班群里发布这次作业的相关资料,并且课堂上也有展示,所以实践起来并不困难。
本次代码设计使用三层设计,分别为表现层(用户界面层)、业务逻辑层、数据访问层。还有一个实体类库。总共有五个类,窗体类实现人机交互。本项目共有6个函数,函数与函数之间会存在调用的关系。关键函数可以画出流程图。我的算法的独到关键之处在于使用生成随机数的形式抽取一个同学进行点到,这样会更简单。
Information Hiding 原则
信息隐藏原则是结构化设计与面向对象编程的基础,面向对象的封装便来自于这个原则。为了实现此原则,类与类都是通过接口访问。
Design by Contract 原则
契约式设计,使一个软件中的各个要素基于相互的义务与责任相互合作。如在函数调用中,若参数个数或者类型错误,则绝不调用。若符合要求则可以调用,程序按照步骤进一步进行。像是在完成契约。
Interface Design 原则
接口隔离,客户端不依赖不需要的接口。在代码设计中,类与类的依赖关系都建立在最小的接口上。
Loose Coupling 原则
在这个项目程序中,类与类之间通过接口的锲约实现服务提供者/服务请求者的模式,非常符合典型的松耦合原则。
代码复审
代码规范
:https://gist.github.com/zhuqling/a2700703d088b8746f0c#file-csharp-language-code-standard-style-md
我们采用的是Camel大小写格式。首先检查命名是否符合要求。我们采用了面对面复审的方式进行代码复审。
yz:这个chosedstuin是不是不符合代码规范啊?
yw:是有一点,改成chosedStuInfo比较好。
yz:这个学生姓名显示的字体大小不太合适,不美观。
yw:改改改。
yz:这个记录缺勤按钮在随机点到之前也可以点击啊,点了会怎么样?
yw:你试一试咯?
yz:点了...列表第一个同学被记录了一次缺勤
yw:那他挺惨的...
yz:我点错了,给同学误记录了一次缺勤,怎么办,能撤回吗?
yw:哇,不行欸!
代码复审结果是发现了一个bug和两个不合理之处和一个代码不符合规则的地方。
1.chosedstuin不符合规范。
2.如果不点击随机抽人直接点击缺勤,则学号为1的同学会被记录一次缺勤。
3.只能记缺勤,如果记错了不能改回去。
代码测试
构造代码测试的思路是,在 Unit Test 中,创建Form的实例form1,调用form1的函数。
使 form1 先加载
调用 form1 函数,随机抽取一名学生。
调用 form1 函数,记这名学生缺勤。
断言这名学生的缺勤次数为1.
调用 form1 函数,取消记录该学生的缺勤。
断言这名学生的缺勤次数为0.
部分代码
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Form1 form1 = new Form1();
form1.unitest_formLoad();
form1.unitest_rdChoseStu();
form1.unitest_Absence();
int tmp = form1.preAssert();
Assert.AreEqual(1, tmp);
form1.unitest_cancelAbsence();
tmp = form1.preAssert();
Assert.AreEqual(0, tmp);
}
}
代码覆盖率
代码说明
private void Form1_Load(object sender, EventArgs e)
{
progressName.Step = 1;
progressName.Minimum = 0;
StudentDAO stuDao = new StudentDAO();
stuList = stuDao.getAllStudents();
DataTable dt = new DataTable();
dt.Columns.Add("stuID", Type.GetType("System.String"));
dt.Columns.Add("stuName", Type.GetType("System.String"));
dt.Columns.Add("缺勤此次数");
progressName.Maximum = stuList.Count;
foreach (Student stu in stuList)
{
dt.Rows.Add(stu.Id, stu.Name, stu.TimeAbence);
progressName.PerformStep();
}
dataGridView1.DataSource = dt;
dataGridView1.Columns[2].Width = 120;
}//Load the data of the students while loading the windows form.
//Initialize the progressbar and make it work properly.
private void Rdchose_Click(object sender, EventArgs e)
{
cancelAbsence.Enabled = false;
Random rd = new Random();
tmp = rd.Next(1, 84);
Thread.Sleep(1);
chosedStuInfo.Text = "学号:" + stuList[tmp].Id +" "+"姓名:"+stuList[tmp].Name;
absence.Enabled = true;
}//perform a random roll call.
private void absence_Click(object sender, EventArgs e)
{
stuList[tmp].TimeAbence++;
int TimeAbsenceTmp1 = Convert.ToInt32(this.dataGridView1.Rows[tmp].Cells[2].Value);
this.dataGridView1.Rows[tmp].Cells[2].Value = TimeAbsenceTmp1 + 1;
cancelAbsence.Enabled = true;
absence.Enabled = false;
}//Record an absence for this chosed student.
private void cancelabsence_Click(object sender, EventArgs e)
{
stuList[tmp].TimeAbence--;
int TimeAbsenceTmp2 = Convert.ToInt32(this.dataGridView1.Rows[tmp].Cells[2].Value);
this.dataGridView1.Rows[tmp].Cells[2].Value = TimeAbsenceTmp2 - 1;
absence.Enabled = true;
cancelAbsence.Enabled = false;
}//Cancel the absence record for this chosed student if he was recorded an absence just now.
PSP表格
PSP2.1 | Personal Software Process Stages | 实际耗时(分钟) |
---|---|---|
Planning | 计划 | 15 |
Estimate | 估计这个任务需要多少时间 | 20 |
Development | 开发 | 90 |
Analysis | 需求分析 | 80 |
Design Spec | 生成设计文档 | 50 |
Design Review | 设计复审 | 30 |
Coding Standard | 代码规范 | 70 |
Design | 具体设计 | 60 |
Coding | 具体编码 | 60 |
Code Review | 代码复审 | 50 |
Test | 测试 | 50 |
Reporting | 报告 | 60 |
Test Report | 测试报告 | 40 |
Size Measurement | 计算工作量 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 80 |
Sum | 合计 | 785 |
附加功能
记录学生缺勤,显示学生缺勤次数。
取消该次记录学生缺勤。
个人总结
三层架构需要用心和时间去学习,非常有必要。
其实还有很多附加功能可以实现,比如说登陆、导入学生信息、导出学生信息等。