实验二 Java面向对象程序设计

实验内容

  1. 初步掌握单元测试和TDD
  2. 理解并掌握面向对象三要素:封装、继承、多态
  3. 初步掌握UML建模
  4. 熟悉S.O.L.I.D原则
  5. 了解设计模式

实验步骤

单元测试

  • 1.三种代码:伪代码、产品代码、测试代码。我们应该先写伪代码->再用特定编程语言翻译成产品代码->最后写测试代码,验证自己的代码有没有问题。

    (1)伪代码

      百分制转五分制:
    如果成绩小于60,转成“不及格”
    如果成绩在60与70之间,转成“及格”
    如果成绩在70与80之间,转成“中等”
    如果成绩在80与90之间,转成“良好”
    如果成绩在90与100之间,转成“优秀”
    其他,转成“错误”

(2)产品代码

    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)测试代码

  • 用50分测试时:

      public class MyUtilTest {
    public static void main(String[] args) {
    // 百分制成绩是50时应该返回五级制的“不及格”
    if(MyUtil.percentage2fivegrade(50) != "不及格")
    System.out.println("test failed!");
    else
    System.out.println("test passed!");
    }
    }

  • 输入负分或大于100时:

      public class MyUtilTest3 {
    public static void main(String[] args) {
    //测试出错情况
    if(MyUtil2.percentage2fivegrade(-10) != "错误")
    System.out.println("test failed 1!");
    else if(MyUtil2.percentage2fivegrade(115) != "错误")
    System.out.println("test failed 2!");
    else
    System.out.println("test passed!");
    }
    }

  • 测试边界情况:

      public class MyUtilTest4{
    public static void main(String[] args) {
    //测试边界情况
    if(MyUtil2.percentage2fivegrade(0) != "不及格")
    System.out.println("test failed 1!");
    else if(MyUtil2.percentage2fivegrade(60) != "及格")
    System.out.println("test failed 2!");
    else if(MyUtil2.percentage2fivegrade(70) != "中等")
    System.out.println("test failed 3!");
    else if(MyUtil2.percentage2fivegrade(80) != "良好")
    System.out.println("test failed 4!");
    else if(MyUtil2.percentage2fivegrade(90) != "优秀")
    System.out.println("test failed 5!");
    else if(MyUtil3.percentage2fivegrade(100) != "优秀")
    System.out.println("test failed 6!");
    else
    System.out.println("test passed!");
    }
    }
  • 改正错误后最后代码:

      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 "错误";
    }
    }

TDD(Test Driven Devlopment, 测试驱动开发)

  • 概念:先写测试代码,然后再写产品代码的开发方法

    一般步骤如下:

       明确当前要完成的功能,记录成一个测试列表
    快速完成编写针对此功能的测试用例
    测试代码编译不通过(没产品代码呢)
    编写产品代码
    测试通过
    对代码进行重构,并保证测试通过(重构下次实验练习)
    循环完成所有功能的开发
    TDD模式测试代码的编写和调试结果
  • 在Idea中按照老师所给教程点击进入File-Settings,选择Plugins,搜索Junit,下载junit V2.0

  • 建立TDDDemo,建代码Myutil,Alt+Enter打开小灯笼,建立test

  • 测试代码如下(注意@Test)

      import org.junit.Test;
    import junit.framework.TestCase;
    public class MyUtilTest extends TestCase {
    @Test
    public void testNormal() {
    assertEquals("不及格", MyUtil.percentage2fivegrade(55));
    assertEquals("及格", MyUtil.percentage2fivegrade(65));
    assertEquals("中等", MyUtil.percentage2fivegrade(75));
    assertEquals("良好", MyUtil.percentage2fivegrade(85));
    assertEquals("优秀", MyUtil.percentage2fivegrade(95));
    }
    }
  • 结果截图

面向对象三要素

1.抽象:去粗取精、化繁为简、由表及里、异中求同。在抽象的最高层,可以使用问题环境的语言,以概括的方式叙述问题的解;在抽象的较低层,则采用过程化的方式进行描述。

2.面向对象(Object-Oriented)的三要素包括:封装、继承、多态。面向对象的思想涉及到软件开发的各个方面,如面向对象分析(OOA)、面向对象设计(OOD)、面向对象编程实现(OOP)。

3.继承

以封装为基础,一个类的定义可以基于另外一个已经存在的类,即子类基于父类,从而实现父类代码的重用。其更为广泛而重要的作用是实现多态。

示例:Dog类和Cat类都有Color属性和相应的setter和getter方法,可以通过继承使其精炼化,把Color属性和相应的setter和getter方法放到父类Animal中。

  • 代码如下

      public abstract class Animal {
    private String color;
    public String getColor() {
    return color;
    }
    public void setColor(String color) {
    this.color = color;
    }
    public abstract String shout();
    }
    class Dog extends Animal{
    public String shout(){
    return "汪汪";
    }
    public String toString(){
    return "The Dog's color is " + this.getColor() +", and it shouts "+ this.shout() + "!";
    }
    }
    class Cat extends Animal{
    public String shout(){
    return "喵喵";
    }
    public String toString(){
    return "The Cat's color is " + this.getColor() +", and it shouts "+ this.shout() + "!";
    }
    }
  • 根据TDD建AnimalTest,测试代码为

      public class AnimalTest {
    public static void main(String[] args){
    Animal[] arr = {new Dog(),new Cat(),new Cat(),new Dog()};
    for(int i=0; i<arr.length;i++)
    getInfo(arr[i]);
    } public static void getInfo(Animal a){
    System.out.println(a.toString());
    }
    }

UML类图建模

  • UML是一种通用的建模语言
  • 打开WhiteStarUML

  • Tools-java1.5-Reverse Engineer,并add所要建模UML的java文件。

  • run后结果,UML建模图(至少两个类)

一般规则

  • +表示public
  • -表示 private
  • 如果类A中a()方法是抽象方法,那么a()是斜体的,类A是抽象类,所以也是斜体的
  • UML类图要展示类之间的静态关系,UML中依赖用带箭头的直线表示,例如上例中的Animal类依赖Cat类和Dog类
  • UML类图中继承的表示法,是用一个带三角的直线指向父类,例如上例中Cat类和Dog类继承Animal类,消除了Dog类和Cat类中的重复代码,符合DRY的要求

设计模式初步

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,依赖倒置原则)

2.模式与设计模式:模式是某外在环境(Context) 下﹐对特定问题(Problem)的惯用解决之道(Solution)。计算机科学中有很多模式:

    GRASP模式
分析模式
软件体系结构模式
设计模式:创建型,结构型,行为型
管理模式: The Manager Pool 实现模式
界面设计交互模式

3.设计模式实示例:设计模式(design pattern)提供一个用于细化软件系统的子系统或组件,或它们之间的关系图,它描述通信组件的公共再现结构,通信组件可以解决特定语境中的一个设计问题。设计模式有四个基本要素:

    Pattern name:描述模式,便于交流,存档
Problem:描述何处应用该模式
Solution:描述一个设计的组成元素,不针对特例
Consequence:应用该模式的结果和权衡(trade-offs)
  • 示例:

      class Integer {
    int value;
    public Integer(){
    value=100;
    }
    public void DisplayValue(){
    System.out.println(value);
    }
    }
    class Document {
    Integer pi;
    public Document(){
    pi = new Integer();
    }
    public void DisplayData(){
    pi.DisplayValue();
    }
    }
    public class MyDoc{
    static Document d;
    public static void main(String [] args) {
    Double.parseDouble("100.0");
    d = new Document();
    d.DisplayData();
    }
    }
  • 运行结果

练习

使用TDD的方式设计关实现复数类Complex

  • 一开始审题不清,没有用TDD方式



后经过再三审题,重新编写代码

  • 伪代码

      1)复数类ComplexNumber的属性
    realPart: 实部,代表复数的实数部分
    imaginPart: 虚部,代表复数的虚数部分
    2)复数类ComplexNumber的方法
    ComplexNumber() 构造函数,将实部,虚部都置为0
    ComplexNumber(double realPart, double imaginPart) 构造函数,创建复数对象的同时完成复数的实部,虚部的初始化
    getRealPart() 获取实部
    getImaginaryPart() 获取虚部
    getRealPart(double realPart) 设置实部
    getImaginaryPart(double imaginPart) 设置虚部
    ComplexAdd(ComplexNumber c)  复数相加
    ComplexAdd(double realPart2)  复数相加
    ComplexMinus(ComplexNumber c)  复数相减
    ComplexMinus(double realPart2) 复数相减
    ComplexMulti(ComplexNumber c)  复数相乘
    ComplexMulti(double realPart2) 复数相乘
    toString() 把当前复数对象的实部,虚部组合成a+bi的字符串形式
  • 测试代码

      import static junit.framework.Assert.*;
    import junit.framework.TestCase;
    import org.junit.Test; public class ComplexNumberTest extends TestCase {
    ComplexNumber c1 = new ComplexNumber(3,5);
    ComplexNumber c2 = new ComplexNumber(3,5);
    double a = 5;
    @Test
    public void testAdd1() throws Exception {
    c1.ComplexAdd(c2);
    assertEquals(6.0, c1.getRealPart());
    assertEquals(10.0, c1.getImaginPart());
    }
    @Test
    public void testAdd2() throws Exception {
    c1.ComplexAdd(a);
    assertEquals(8.0, c1.getRealPart());
    assertEquals(5.0, c1.getImaginPart());
    }
    @Test
    public void testMinus1() throws Exception {
    c1.ComplexMinus(c2);
    assertEquals(0.0, c1.getRealPart());
    assertEquals(0.0, c1.getImaginPart());
    }
    public void testMinus2() throws Exception {
    c1.ComplexMinus(a);
    assertEquals(-2.0, c1.getRealPart());
    assertEquals(5.0, c1.getImaginPart());
    }
    @Test
    public void testMulti1() throws Exception {
    c1.ComplexMulti(c2);
    assertEquals(9.0, c1.getRealPart());
    assertEquals(25.0, c1.getImaginPart());
    }
    public void testMulti2() throws Exception {
    c1.ComplexMulti(a);
    assertEquals(15.0, c1.getRealPart());
    assertEquals(5.0, c1.getImaginPart());
    }
    }
  • 产品代码

      public class ComplexNumber {
    private double realPart;
    private double imaginPart;
    public ComplexNumber(){
    this.realPart = 0.0.;
    this.imaginPart = 0.0;
    }
    public ComplexNumber(double r, double i){
    this.realPart = r;
    this.imaginPart = i;
    }
    public double getRealPart(){
    return realPart;
    }
    public double getImaginPart(){
    return imaginPart;
    }
    public void setRealPart(double d){
    this.realPart = d;
    }
    public void setImaginPart(double d){
    this.imaginPart = d;
    }
    public void ComplexAdd(ComplexNumber c){
    this.realPart += c.realPart;
    this.imaginPart += c.imaginPart;
    }
    public void ComplexAdd(double c){
    this.realPart += c;
    }
    public void ComplexMinus(ComplexNumber c){
    this.realPart -= c.realPart;
    this.imaginPart -= c.imaginPart;
    }
    public void ComplexMinus(double c){
    this.realPart -= c;
    }
    public void ComplexMulti(ComplexNumber c){
    this.realPart *= c.realPart;
    this.imaginPart *= c.imaginPart;
    }
    public void ComplexMulti(double c){
    this.realPart *= c;
    }
    @Override
    public String toString(){
    return String.format("%f + %fi", this.getRealPart(),this.getImaginPart());
    }
    }
  • 结果截图

  • PSP(Personal Software Process)时间
步骤 耗时 百分比
需求分析 10min 8.3%
设计 20min 16.7%
代码实现 30min 25.0%
测试 45min 37.5%
分析总结 15min 12.5%
  • 总结单元测试的好处

    (1)对于整个项目来说,有了完整的测试,保证项目最后交付测试有了可靠依据,减少后期维护的精力和费用

    (2)对于开发人员来说大大减少调试工作的时间,同时也规范了对于代码安全管理

    (3)能够有效优化代码的设计

    (4)测试本身是被测代码的用法说明,替代了一部分代码功能,迫使自己要将被测代码设计得更加独立地去完成某个或某几个功能

20155305 2016-2017-2 《Java程序设计》实验二 Java面向对象程序设计的更多相关文章

  1. 20155202 《Java程序设计》实验二(面向对象程序设计)实验报告

    20155202 <Java程序设计>实验二(面向对象程序设计)实验报告 代码托管 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...

  2. Java程序设计 实验二 Java面向对象程序设计

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计 班级:1353  姓名:李海空  学号:20135329 成绩:             指导教师:娄嘉鹏 ...

  3. 20155239《Java程序设计》实验二(面向对象程序设计)实验报告

    实验内容 初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验步骤 单元测试 1.三种代码: 伪代码 ...

  4. 20165308 实验二 Java面向对象程序设计

    20165308 实验二 Java面向对象程序设计 实验二 Java面向对象程序设计 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:张士洋 学号:20165308 指导教师:娄嘉鹏 ...

  5. 实验二Java面向对象程序设计实验报告(2)

    实验二 Java面向对象程序设计 实验概述: 课程:程序设计与数据结构 班级:1623班 姓名: 邢天岳 学号:2309 指导老师:娄老师 王老师 实验日期:2017.4.16 实验名称: Java面 ...

  6. 20155317 实验二 Java面向对象程序设计

    20155317 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验步 ...

  7. 20155319 实验二 Java面向对象程序设计

    20155319 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 (一) ...

  8. 20169219 实验二 Java面向对象程序设计

    实验二 Java面向对象程序设计 一.程序设计中临时变量的使用 任务: //定义一个数组 int arr[] = {1,2,3,4,5,6,7,8}; //打印原始数组的值 for(int i:arr ...

  9. 实验二 Java面向对象程序设计

    实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...

随机推荐

  1. [BZOJ 1124][POI 2008] 枪战 Maf

    1124: [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 659  Solved: 259[Submit][Status ...

  2. [Python 多线程] RLock可重入锁 (九)

    RLock 可重复锁,是线程相关的锁.同样是线程相关的还有threading.local. 线程A获得可重用锁,并可以多次成功获取,不会阻塞.最后要再线程A中和acquire次数相同的release. ...

  3. Emgu学习之(三)——操作图像数据

    Visual Studio Community 2015 工程和代码:http://pan.baidu.com/s/1jHmlQeE 内容 在这篇文章中将提到以下内容: 修改像素值 图像ROI 图像加 ...

  4. spring boot容器加载完后执行特定操作

    有时候我们需要在spring boot容器启动并加载完后,开一些线程或者一些程序来干某些事情.这时候我们需要配置ContextRefreshedEvent事件来实现我们要做的事情 1.Applicat ...

  5. [转]墨卡托投影坐标系(Mercator Projection)原理及实现C代码

    墨卡托投影是一种“等角正切圆柱投影”,荷兰地图学家墨卡托(Mercator)在1569年拟定:假设地球被围在一个中空的圆柱里,其赤道与圆柱相接触,然后再假想地球中心有一盏灯,把球面上的图形投影到圆柱体 ...

  6. 新闻cms管理系统(一) ---- thinkphp框架准备

    1.thinkphp介绍 一个快速.简单的基于MVC和面向对象的轻量级PHP开发框架 MVC:M数据层. V视图层 . C控制层 优点: (1)入手非常快 (2)thinkpjp提供核心内库.文件.函 ...

  7. linux下搭建LAMP

    PHP命令找不到:  export PATH=$PATH:/usr/local/php/bin https://www.centos.bz/forum/thread-69-1-1.html 步骤: w ...

  8. python codecs模块 ---处理数据写入文件时会有编码不统一的问题

    我们用open方法打开文件有时候会有一些问题,因为open打开文件只能写入str类型,而不会管字符串是什么编码方式. 示例: >>> fr = open('test.txt','a' ...

  9. myeclipse安装SVN插件方法

    http://www.cnblogs.com/xdp-gacl/p/3497016.html myeclipse安装SVN插件方法 SVM China 源代码托管中心 http://www.svnch ...

  10. 维度属性的KeyColumns如果是Integer类型,那么维度表中该列的值不能有为null的

    如果维度属性的 KeyColumns的DataType设置为了Integer类型,那么要注意该维度属性列在数据库中不能有为null的值. 例如下图中我们有维度DIM_Vehcile,其中有个维度属性叫 ...