20155233 《Java程序设计》 实验二 Java面向对象程序设计
实验内容
- 初步掌握单元测试和TDD
- 理解并掌握面向对象三要素:封装、继承、多态
- 初步掌握UML建模
- 熟悉S.O.L.I.D原则
- 了解设计模式
实验步骤与内容
(一)单元测试
1.Junit的使用
1.新建文件夹:
打开Linux下的终端控制(Ctrl+Alt+T
) → 输入./idea/bin/idea.sh
命令进入IDEA程序 → 建立~/20155233/20155233/exp2
下的Project
2.新建一个MyUtil
类的产品代码,输入以下:
public class MyUtil{
public static String percentage2fivegrade(int grade){
//如果成绩小于60,转成“不及格”
if (grade < 60)
return "不及格";
//如果成绩在60与70之间,转成“及格”
else if (grade < 70)
return "及格";
//如果成绩在70与80之间,转成“中等”
else if (grade < 80)
return "中等";
//如果成绩在80与90之间,转成“良好”
else if (grade < 90)
return "良好";
//如果成绩在90与100之间,转成“优秀”
else if (grade < 100)
return "优秀";
//其他,转成“错误”
else
return "错误";
}
}
3.针对MyUtil
写一个测试模块MyUtilTest
,根据Intellj IDEA简易教程的单元测试中提到的那样,我们New->Directory
输入test``````test
目录中放的也是Java代码,但IDEA不知道test中放的是源代码。在命令行中我们知道要设置SOURCEPATH环境变量,在IDEA中我们右键单击test目录,在弹出的菜单中选择Mark Directory as->Test Sources Root
就可以了。
import junit.framework.TestCase;
import org.junit.Test;
/**
* Created by liugaole on 17-4-20.
*/
public class MyUtilTest extends TestCase {
@Test
public void testExceptions() {
// 百分制成绩是50时应该返回五级制的“不及格”
if(MyUtil.percentage2fivegrade(50) != "不及格")
System.out.println("test failed!");
else
System.out.println("test passed!");
}
@Test
public void testMore() {
//测试正常情况
if(MyUtil.percentage2fivegrade(55) != "不及格")
System.out.println("test failed!");
else if(MyUtil.percentage2fivegrade(65) != "及格")
System.out.println("test failed!");
else if(MyUtil.percentage2fivegrade(75) != "中等")
System.out.println("test failed!");
else if(MyUtil.percentage2fivegrade(85) != "良好")
System.out.println("test failed!");
else if(MyUtil.percentage2fivegrade(95) != "优秀")
System.out.println("test failed!");
else
System.out.println("test passed!");
}
@Test
public void testRead() {
//测试出错情况
if(MyUtil.percentage2fivegrade(-10) != "错误")
System.out.println("test failed 1!");
else if(MyUtil.percentage2fivegrade(115) != "错误")
System.out.println("test failed 2!");
else
System.out.println("test passed!");
}
@Test
public void testBj() {
//测试边界情况
if(MyUtil.percentage2fivegrade(0) != "不及格")
System.out.println("test failed 1!");
else if(MyUtil.percentage2fivegrade(60) != "及格")
System.out.println("test failed 2!");
else if(MyUtil.percentage2fivegrade(70) != "中等")
System.out.println("test failed 3!");
else if(MyUtil.percentage2fivegrade(80) != "良好")
System.out.println("test failed 4!");
else if(MyUtil.percentage2fivegrade(90) != "优秀")
System.out.println("test failed 5!");
else if(MyUtil.percentage2fivegrade(100) != "优秀")
System.out.println("test failed 6!");
else
System.out.println("test passed!");
}
}
4.在IDEA中一一测试可能出现的情况,截图如下:
5.最终MyUtil
代码如下:
public class MyUtil{
public static String percentage2fivegrade(int grade){
//如果成绩小于0,转成“错误”
if ((grade < 0))
return "错误";
//如果成绩小于60,转成“不及格”
else if (grade < 60)
return "不及格";
//如果成绩在60与70之间,转成“及格”
else if (grade < 70)
return "及格";
//如果成绩在70与80之间,转成“中等”
else if (grade < 80)
return "中等";
//如果成绩在80与90之间,转成“良好”
else if (grade < 90)
return "良好";
//如果成绩在90与100之间,转成“优秀”
else if (grade <= 100)
return "优秀";
//如果成绩大于100,转成“错误”
else
return "错误";
}
}
2.以TDD的方式研究StringBuffer
1.打开IDEA,新建一个名为TDDDemo
的project,新建StringBufferDemo
类,输入以下代码:
/**
* Created by liugaole on 17-4-20.
*/
public class StringBufferDemo{
StringBuffer buffer = new StringBuffer();
public StringBufferDemo(StringBuffer buffer){
this.buffer = buffer;
}
public Character charAt(int i){
return buffer.charAt(i);
}
public int capacity(){
return buffer.capacity();
}
public int length(){
return buffer.length();
}
public int indexOf(String buf) {
return buffer.indexOf(buf);
}
}
2.编辑运行Junit测试用例StringBufferDemoTest
:
import junit.framework.TestCase;
import org.junit.Test;
/**
* Created by liugaole on 17-4-20.
*/
public class StringBufferDemoTest extends TestCase {
StringBuffer a = new StringBuffer("StringBuffer");//测试12个字符(<=16)
StringBuffer b = new StringBuffer("StringBufferStringBuffer");//测试24个字符(>16&&<=34)
StringBuffer c = new StringBuffer("StringBufferStringBufferStringBuffer");//测试36个字符(>=34)
@Test
public void testA() throws Exception{
assertEquals('S',a.charAt(0));
assertEquals('g',a.charAt(5));
assertEquals('r',a.charAt(11));
}
@Test
public void testB() throws Exception{
assertEquals(28,a.capacity());
assertEquals(40,b.capacity());
assertEquals(52,c.capacity());
}
@Test
public void testC() throws Exception{
assertEquals(12,a.length());
assertEquals(24,b.length());
assertEquals(36,c.length());
}
@Test
public void testD() throws Exception{
assertEquals(0,a.indexOf("Str"));
assertEquals(5,a.indexOf("gBu"));
assertEquals(10,a.indexOf("er"));
}
}
3.运行结果如下图所示:
(二)体会OCP原则和DIP原则的应用
让系统支持Long类,并在MyDoc类中添加测试代码表明添加正确
1.新建MyDoc
的project,编写MyDoc
类改写试例程序为:
/**
* Created by liugaole on 17-4-20.
*/
/**
* // Server Classes
abstract class Data {
abstract public void DisplayValue();
}
class Integer extends Data {
int value;
Integer() {
value=100;
}
public void DisplayValue(){
System.out.println (value);
}
}
// Pattern Classes
abstract class Factory {
abstract public Data CreateDataObject();
}
class IntFactory extends Factory {
public Data CreateDataObject(){
return new Integer();
}
}
//Client classes
class Document {
Data pd;
Document(Factory pf){
pd = pf.CreateDataObject();
}
public void DisplayData(){
pd.DisplayValue();
}
}
//Test class
public class MyDoc {
static Document d;
public static void main(String[] args) {
d = new Document(new IntFactory());
d.DisplayData();
}
}
*/
abstract class Data {
abstract public void DisplayValue();
}
class Integer extends Data {
int value;
Integer() {
value=100;
}
public void DisplayValue(){
System.out.println (value);
}
}
class Long extends Data {
long value;
Long() {
value=1234567890;
}
public void DisplayValue(){
System.out.println (value);
}
}
// Pattern Classes
abstract class Factory {
abstract public Data CreateDataObject();
}
class IntFactory extends Factory {
public Data CreateDataObject(){
return new Integer();
}
}
class LongFactory extends Factory {
public Data CreateDataObject(){
return new Long();
}
}
//Client classes
class Document {
Data pd;
Document(Factory pf){
pd = pf.CreateDataObject();
}
public void DisplayData(){
pd.DisplayValue();
}
}
//Test class
public class MyDoc {
static Document d;
public static void main(String[] args) {
d = new Document(new LongFactory());
d.DisplayData();
}
}
2.运行结果如下图:
(三)以TDD的方式开发一个复数类Complex
1.新建Complex
project,编写Complex
类,程序如下:
public class Complex {
double a, b;
Complex() {
this.a = 0;
this.b = 0;
}
Complex(double a) {
this.a = a;
this.b = 0;
}
Complex(double a, double b) {
this.a = a;
this.b = b;
}
Complex jia(Complex p1, Complex p2) {
Complex p = new Complex(p1.a + p2.a, p1.b + p2.b);
return p;
}
Complex jian(Complex p1, Complex p2) {
Complex p = new Complex(p1.a - p2.a, p1.b - p2.b);
return p;
}
Complex cheng(Complex p1, Complex p2) {
Complex p = new Complex(p1.a * p2.a - p1.b * p2.b, p1.b * p2.a + p1.a * p2.a);
return p;
}
Complex chu(Complex p1, Complex p2) {
Complex p = new Complex(p1.a / p2.a - p1.b / p2.b, p1.b / p2.a + p1.a / p2.a);
return p;
}
void Print() {
System.out.println("复数的值为:");
if (this.b != 0)
System.out.println(this.a + "+" + this.b + "i");
else System.out.println(this.a);
}
}
2.对产品代码进行Junit测试,测试代码如下:
import junit.framework.TestCase;
import org.junit.Test;
/**
* 20155233 23:29
*/
public class ComplexTest extends TestCase {
@Test
public void testNormal() throws Exception{
Complex c=new Complex();
Complex c1=new Complex(4,5);
Complex c2=new Complex(6,7);
c1.Print();
c2.Print();
System.out.println("这两复数和为:");
System.out.println((c.jia(c1, c2).a+"+"+c.jia(c1, c2).b+"i").toString());
System.out.println("这两复数差为:");
System.out.println(c.jian(c1, c2).a+"+"+c.jian(c1, c2).b+"i");
System.out.println("这两复数乘积为:");
System.out.println(c.cheng(c1, c2).a+"+"+c.cheng(c1,c2).b+"i");
System.out.println("这两复数相除为:");
System.out.println(c.chu(c1, c2).a+"+"+c.chu(c1,c2).b+"i");
}
}
3.通过测试,测试结果如下图:
(四)使用StarUML对实验中的代码进行建模
类图中只少两个类
1.根据实验指导,下载并安装StarUML;
2.新建一个Animal
class类,并添加构成元素;
3.新建名为Dog
,Cat
的class类,并让其继承父类Animal
;
4.所建UML图如下:
实验感想
本次实验涉及知识内容广,对IDEA的进一步了解进行了充分的尝试,其中JUnit测试方法的使用将起到事半功倍的效果,StarUML图将对我们以后梳理知识结构起到很大的帮助效果。
OCP原则和DIP原则,会让Java代码变得更加条理化,便于更改、可读性也会大大提高。
虽然本次实验的难点很多,但根据老师实验指导书的步骤一步一步来走,我们不难作出实验,很容易将新的知识消化。
PSP(Personal Software Process)时间:
步骤 | 耗时 | 百分比 |
---|---|---|
需求分析 | 10min | 3.6% |
设计 | 20min | 7.1% |
代码实现 | 180min | 64.3% |
测试 | 40min | 14.3% |
分析总结 | 30min | 10.7% |