课程:Java程序设计 班级:1353 姓名:余佳源 学号:20135321
成绩: 指导教师:娄嘉鹏 实验日期:2015-5-8
实验密级: 预习程度: 实验时间:3:15~6:45
仪器组次: 必修/选修:选修 实验序号:2
实验名称: Java面向对象程序设计
实验目的与要求:
1. 初步掌握单元测试和TDD
2. 理解并掌握面向对象三要素:封装、继承、多态
3. 初步掌握UML建模
4. 熟悉S.O.L.I.D原则编辑器》 课程
5. 了解设计模式
6.没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》课程
7.完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。
8.严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。查找,9.请大家先在实验楼中的~/Code目录中用自己的学号建立一个目录,代码和UML图要放到这个目录中,截图中没有学号的会要求重做,然后跟着下面的步骤练习。
实验仪器:
名称 |
型号 |
数量 |
Laptop |
Acer Aspire V5-473G |
1 |
|
|
|
PS:实在没有足够的网速驾驭实验楼,就在自己电脑做了。
实验内容一
(一)单元测试
(1) 三种代码
编程前要把干什么、如何干想清楚才能把程序写对、写好。想用程序解决问题时,要会写三种码:
伪代码
产品代码
测试代码
需求:我们要在一个MyUtil类中解决一个百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能。
伪代码:
百分制转五分制:
如果成绩小于60,转成“不及格”
如果成绩在60与70之间,转成“及格”
如果成绩在70与80之间,转成“中等”
如果成绩在80与90之间,转成“良好”
如果成绩在90与100之间,转成“优秀”
其他,转成“错误”
产品代码:
我们用java语言翻译一下伪代码,就是可用的产品代码
其用到的测试代码如下
测试一:选取某一合法输入值进行测试
测试结果
测试二:再测试一下-10这错误数据,发现运行-10的结果不对
测试三:边界测试,即0,60,70,80,90,100
测试结果为
仅以60分为例:
(二)TDD(Test Driven Devlopment, 测试驱动开发)
先写测试代码,然后再写产品代码的开发方法叫“测试驱动开发”(TDD)。TDD的一般步骤如下:
l 明确当前要完成的功能,记录成一个测试列表
l 快速完成编写针对此功能的测试用例
l 测试代码编译不通过(没产品代码呢)
l 编写产品代码
l 测试通过
l 对代码进行重构,并保证测试通过(重构下次实验练习)
l 循环完成所有功能的开发
以程序为例
测试结果出现了一个绿条(green bar),说明测试通过了。TDD的目标是"Clean Code That Works",TDD的slogan是"Keep the bar green, to Keep the code clean"。
(三)面向对象三要素
1.抽象
抽象就是抽出事物的本质特征而暂时不考虑他们的细节。对于复杂系统问题人们借助分层次抽象的方法进行问题求解;在抽象的最高层,可以使用问题环境的语言,以概括的方式叙述问题的解。在抽象的较低层,则采用过程化的方式进行描述。在描述问题解时,使用面向问题和面向实现的术语。 程序设计中,抽象包括两个方面,一是过程抽象,二是数据抽象。
2.封装、继承与多态
面向对象(Object-Oriented)的三要素包括:封装、继承、多态。
过程抽象的结果是函数,数据抽象的结果是抽象数据类型。
封装实际上使用方法(method)将类的数据隐藏起来,控制用户对类的修改和访问数据的程度,从而带来模块化(Modularity)和信息隐藏(Information hiding)的好处;接口(interface)是封装的准确描述手段。
范例用的umbrello图
封装为基础,继承可以实现代码复用,需要注意的是,继承更重要的作用是实现多态。 面向对象中允许不同类的对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式,我们称此现象为多态性。Java中,多态是指不同的类对象调用同一个签名的成员方法时将执行不同代码的现象。多态是面向对象程序设计的灵活性和可扩展性的基础。
(四)设计模式初步
(1)S.O.L.I.D原则
SRP(Single Responsibility Principle,单一职责原则)
OCP(Open-Closed Principle,开放-封闭原则)
LSP(Liskov Substitusion Principle,Liskov替换原则)
ISP(Interface Segregation Principle,接口分离原则)
DIP(Dependency Inversion Principle,依赖倒置原则)
OCP是OOD中最重要的一个原则,OCP的内容是:
software entities (class, modules, function, etc.) should open for extension,but closed for modification.
软件实体(类,模块,函数等)应该对扩充开放,对修改封闭。
对扩充开放(Open For Extension )要求软件模块的行为必须是可以扩充的,在应用需求改变或需要满足新的应用需求时,我们要让模块以不同的方式工作; 对修改封闭(Closed for Modification )要求模块的源代码是不可改动的,任何人都不许修改已有模块的源代码。
基于OCP,利用面向对象中的多态性(Polymorphic),更灵活地处理变更拥抱变化,OCP可以用以下手段实现:抽象和继承和面向接口编程。
(2)模式与设计模式
模式是某外在环境(Context) 下﹐对特定问题(Problem)的惯用解决之道。其中最重要的是设计模式。
• GRASP模式
• 分析模式
• 软件体系结构模式
• 设计模式:创建型,结构型,行为型
• 管理模式: The Manager Pool 实现模式
• 界面设计交互模式
(3)设计模式实示例
设计模式四个基本元素
Pattern name:描述模式,便于交流,存档
Problem:描述何处应用该模式
Solution:描述一个设计的组成元素,不针对特例
Consequence:应用该模式的结果和权衡
设计模式提供一个用于细化软件系统的子系统或组件,或它们之间的关系图,它描述通信组件的公共再现结构,通信组件可以解决特定语境中的一个设计问题。
我们通过例子来学习一个设计模式(抽象工厂模式),并了解设计模式可能会存在的过度设计问题以及如何避免它。 我们设计了一个文档系统,如下图UML类
对应的代码如下:
结果如图
客户如果要求系统支持Float类,这是一个合理的要求,要支持Float类,Document类要修改两个地方,这违反了OCP原则,使用多态可以解决部分问题:
要支持Float类,Document类要修改构造方法,这还违反了OCP原则。封装、继承、多态解决不了问题了,这时需要设计模式了:
修改得代码截图
(五)练习
使用TDD的方式设计关实现复数类Complex。
伪代码:
l 复数的实部为0,虚部为0
l 复数的实部为0,虚部为对应数
l 复数的实部为对应数,实部为0
l 两参数分别为实部与虚部
l 实现两复数的加法、减法、乘法。
测试代码
产品代码
测试数据以及运行结果
总结时间:
PSP时间统计
统计有误差,总计3.5小时。
步骤 |
耗时 |
百分比 |
需求分析 |
25mins |
12% |
设计 |
30mins |
14.3% |
代码实现 |
120mins |
57.1% |
测试 |
30mins |
14.3% |
分析总结 |
5mins |
2.3% |
总结单元测试的好处:
1. 在单元测试中,设计的软件的独立单元将在与程序的其他部分相隔离的情况下通过测试代码的测试来查找错误,从而写出更高质量的产品代码,提高编程的水平和技巧。
2. 单元测试代码可以通过简单的程序代码行之间的回滚功能在编译和运行环境上做基于真实数据的测试,而不用担心会产生不必要的数据,破坏到测试结果。
3. 更加明确开发的目的,避免出现重复或者过多冗长的工作,提升开发者的工作效率。
4. 将产品代码和测试代码分开,使程序员将软件模块写得易于测试和调用,从而有利于被测代码的使用,从而实现了一部分功能,更加方便使用者理解。
参考资料
1.《UML精粹》 2.《构建之法 (电子版)》,著者邹欣Blog 3.《深入浅出设计模式》 4.《解析极限编程》 5.《单元测试之道》
1. 《代码大全》
2. 《代码的抽象三原则》
工具
1. JUnit
2. umbrello
3. StarUML