zoukankan      html  css  js  c++  java
  • 20175221曾祥杰 实验二《Java面向对象程序设计》

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

    实验报告封面

    课程:Java程序设计 班级:1752班 姓名:曾祥杰 学号:20175221

    指导教师:娄嘉鹏 实验日期:2019年4月17日

    实验时间:13:45 - 15:25 实验序号:21

    实验名称:面向对象程序设计

    一.实验内容

    1. 初步掌握单元测试和TDD

    2. 理解并掌握面向对象三要素:封装、继承、多态

    3. 初步掌握UML建模

    4. 熟悉S.O.L.I.D原则

    5. 了解设计模式

    二.实验步骤

    • 第一部分:初步掌握单元测试和TDD

    • 在IDEA中,我们首先创建一个项目 MyUtil.java ,并输入如图代码:
    • 针对 MyUtil 类我们写一个 MyUtilTest.java 的测试模块:
    • 在 IDEA中我们把产品代码放在 src 中,在 IDEA中我们把产品代码放在 test 中 ,右键单击项目,在弹出的菜单中选择 New->Directory 新建一个目录并输入目录名 test 。右键单击test目录,在弹出的菜单中选择 Mark Directory as->Test Sources Root ,随后运行 MyUtilTest.java  
    • 在IDEA中运行结果如上,测试结果符合预期。
    • 然而只有一组输入的测试是不充分的,把一般情况都测试一下,运行结果如图,测试结果符合预期:
    • 我们不能只测试正常情况,下面看看异常情况如何,比如输入为负分或大于100的成绩,测试结果如下:
    • 运行程序发现负分时与期望不一致,终于找到了一个bug,原因是判断不及格时没有要求成绩大于零。我们修改 MyUtil.java ,增加对负分的判断,测试结果如下:
    • 一般代码在边界处最容易出错,我们还没有测试边界情况,我们对输入为“0,60,70,80,90,100”这些边界情况进行测试的代码如下:
    • 我们发现边界情况中输入100时有一个Bug。我们修改 MyUtil.java ,把判断优秀的条件中包含输入为100的情况,测试结果如下:

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

      TDD的一般步骤如下:

    • 明确当前要完成的功能,记录成一个测试列表
    • 快速完成编写针对此功能的测试用例
    • 测试代码编译不通过(没产品代码呢)
    • 编写产品代码
    • 测试通过
    • 对代码进行重构,并保证测试通过(重构下次实验练习)
    • 循环完成所有功能的开发

       随后我们下载并配置Junit,完成后新建一个项目 MyUtil 。单击类名会出现一个灯泡状图标,选择 Create Test 

    • 随后选择创建JUnit3
    • 我们增加测试用例 MyUtilTest ,异常情况的用例 testException ,测试边界情况的用例 testBoundary ,代码如下:
    • 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 "错误";
          }
      }
      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));
          }
          @Test
          public void testExceptions(){
              assertEquals("错误", MyUtil.percentage2fivegrade(-55));
              assertEquals("错误", MyUtil.percentage2fivegrade(105));
          }
          @Test
          public void testBoundary(){
              assertEquals("不及格", MyUtil.percentage2fivegrade(0));
              assertEquals("及格", MyUtil.percentage2fivegrade(60));
              assertEquals("中等", MyUtil.percentage2fivegrade(70));
              assertEquals("良好", MyUtil.percentage2fivegrade(80));
              assertEquals("优秀", MyUtil.percentage2fivegrade(90));
              assertEquals("优秀", MyUtil.percentage2fivegrade(100));
          }
      }


       

    • 运行结果如下:
    • 第二部分:以 TDD的方式研究学习StringBuffer

    • StringBuffer的例子,代码如下:
    • import junit.framework.TestCase;
      import org.junit.Test;
      
      public class StringBufferDemoTest extends TestCase {
          StringBuffer a = new StringBuffer("StringBuffer");
          StringBuffer b = new StringBuffer("StringBufferStringBuffer");
          StringBuffer c = new StringBuffer("StringBufferStringBufferStringBuffer");
          @Test
          public void testcharAt() throws Exception {
              assertEquals('S',a.charAt(0));
              assertEquals('g',a.charAt(5));
              assertEquals('r',a.charAt(11));
          }
          @Test
          public void testcapacity() throws Exception {
              assertEquals(28,a.capacity());
              assertEquals(40,b.capacity());
              assertEquals(52,c.capacity());
          }
          @Test
          public void testlength() throws Exception {
              assertEquals(12,a.length());
              assertEquals(24,b.length());
              assertEquals(36,c.length());
          }
          @Test
          public void testindexOf() throws Exception {
              assertEquals(0,a.indexOf("Str"));
              assertEquals(5,a.indexOf("gBu"));
                  }
      }
    •  运行结果如下

    第三部分:设计模式

    面向对象的三要素

    面向对象(Object-Oriented)的三要素包括:封装、继承、多态。面向对象的思想涉及到软件开发的各个方面,如面向对象分析(OOA)、面向对象设计(OOD)、面向对象编程实现(OOP)。OOA根据抽象关键的问题域来分解系统,关注是什么(what)。OOD是一种提供符号设计系统的面向对象的实现过程,用非常接近问题域术语的方法把系统构造成“现实世界”的对象,关注怎么做(how),通过模型来实现功能规范。OOP则在设计的基础上用编程语言(如Java)编码。贯穿OOA、OOD和OOP的主线正是抽象。

    S.O.L.I.D原则:

    • SRP(Single ResponsibilityPrinciple,单一职责原则)
    • OCP(Open-Closed Principle,开放-封闭原则)
    • LSP(Liskov Substitusion Principle,Liskov替换原则)
    • ISP(Interface Segregation Principle,接口分离原则)
    • DIP(Dependency Inversion Principle,依赖倒置原则

    设计模式四个基本要素:

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

     其他面对对象原则:

    •  "组合替代继承":这是说相对于继承,要更倾向于使用组合
    • "笛米特法则":这是说"你的类对其它类知道的越少越好"
    • "共同封闭原则":这是说"相关类应该打包在一起"
    • "稳定抽象原则":这是说"类越稳定,越应该由抽象类组成"

    题目:对设计模式示例进行扩充,体会OCP原则和DIP原则的应用,初步理解设计模式。让系统支持Long类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印

    代码如下:

    // 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);
        }
    }
    class Long extends Data {
        long value;
        Long(){
            value=20175221;
        }
        public void DisplayValue(){
            System.out.println(value);
        }
    }
    abstract class Factory {
        abstract public Data CreateDataObject();
    }
    class IntFactory extends Factory {
        public Data CreateDataObject(){
            return new Integer();
        }
    }
    class LonFactory extends Factory {
        public Data CreateDataObject(){
            return new Long();
        }
    }
    class Document {
        Data pd;
        Document(Factory pf){
            pd = pf.CreateDataObject();
        }
        public void DisplayData(){
            pd.DisplayValue();
        }
    }
    public class MyDoc {
        static Document zxj;
        public static void main(String[] args) {
            zxj=new Document(new LonFactory());
            zxj.DisplayData();
        }
    }


    运行结果:

    第四部分:以TDD的方式开发一个复数类Complex

    要求如下:

    // 定义属性并生成getter,setter
    double RealPart;
    double ImagePart;
    // 定义构造函数
    public Complex()
    public Complex(double R,double I)
    
    //Override Object
    public boolean equals(Object obj)
    public String toString()
    
    // 定义公有方法:加减乘除
    Complex ComplexAdd(Complex a)
    Complex ComplexSub(Complex a)
    Complex ComplexMulti(Complex a)
    Complex ComplexDiv(Complex a)

    实验代码

    public class Complex{
        private double real;
        private double image;
    
        public Complex(double real, double image) {
            this.real = real;
            this.image = image;
        }
    
        public static double getRealPart(double real) {
            return real;
        }
    
        public static double getImagePart(double image) {
            return image;
        }
    
        public Complex ComplexAdd(Complex c) {
            return new Complex(real + c.real, image + c.image);
        }
        public Complex ComplexSub(Complex c) {
            return new Complex(real - c.real, image - c.image);
        }
        public Complex ComplexMulti(Complex c) {
            return new Complex(real * c.real - image * c.image, real * c.image + image * c.real);
        }
        public Complex ComplexDiv(Complex c) {
            return new Complex((real * c.image + image * c.real)/(c.image * c.image + c.real * c.real), (image * c.image + real * c.real)/(c.image * c.image + c.real * c.real));
        }
    
        public String toString() {
            String s = " ";
            if (image > 0)
                s =  real + "+" + image + "i";
            if (image == 0)
                s =  real + "";
            if (image < 0)
                s = real + " " + image + "i";
            return s;
        }
    }

    测试代码

    import junit.framework.TestCase;
    import org.junit.Test;
    
    public class ComplexTest extends TestCase {
        Complex a = new Complex(0.0, 2.0);
        Complex b = new Complex(-1.0, -1.0);
        Complex c = new Complex(1.0,2.0);
        @Test
        public void testgetRealPart() throws Exception {
            assertEquals(0.0, Complex.getRealPart(0.0));
            assertEquals(-1.0, Complex.getRealPart(-1.0));
            assertEquals(1.0, Complex.getRealPart(1.0));
        }
        @Test
        public void testgetImagePart() throws Exception {
            assertEquals(2.0, Complex.getImagePart(2.0));
            assertEquals(-1.0, Complex.getImagePart(-1.0));
            assertEquals(2.0, Complex.getImagePart(2.0));
        }
        @Test
        public void testComplexAdd() throws Exception {
            assertEquals("-1.0+1.0i", a.ComplexAdd(b).toString());
            assertEquals("1.0+4.0i", a.ComplexAdd(c).toString());
            assertEquals("0.0+1.0i", b.ComplexAdd(c).toString());
        }
        @Test
        public void testComplexSub() throws Exception {
            assertEquals("1.0+3.0i", a.ComplexSub(b).toString());
            assertEquals("-1.0", a.ComplexSub(c).toString());
            assertEquals("-2.0 -3.0i", b.ComplexSub(c).toString());
        }
        @Test
        public void testComplexMulti() throws Exception {
            assertEquals("2.0 -2.0i", a.ComplexMulti(b).toString());
            assertEquals("-4.0+2.0i", a.ComplexMulti(c).toString());
            assertEquals("1.0 -3.0i", b.ComplexMulti(c).toString());
        }
        @Test
        public void testComplexComplexDiv() throws Exception {
            assertEquals("-1.0 -1.0i", a.ComplexDiv(b).toString());
            assertEquals("0.4+0.8i", a.ComplexDiv(c).toString());
            assertEquals("-0.6 -0.6i", b.ComplexDiv(c).toString());
        }
    }

    运行结果

    码云链接(https://gitee.com/zxjacdl/zxj175221/tree/master/shiyan2)

    第五部分:对实验二中的代码进行建模,发类图的截图

    实验中遇到的问题

    问题1:

    在第一次使用TDD的那个实验中,增加MyUtil的测试类之后,TestCase显示红色的,但是不知道junit.jar在哪里

    问题1解决方案:

    上网查了才知道解决方案,步骤如下:

    1.找到电脑中IDEA安装路径

    2.File->Project Structure

    3.点击Dependencies,单击右上角的+,然后选择第一个JARs or directories

    4.复制刚才的路径名,找到junit-4.12 jar、 junit.jar

    IDEA导入Junit4jar包(https://blog.csdn.net/zoozyy/article/details/78485965)

    实验体会:

    • 这次的实验对我来说还是很有难度的。
    • 虽然每一步的教程都有,但期间无论是下载东西还是编写代码,都还是出现了很多难题。
    • 还是在和伙伴讨论合作下完成的。希望以后的实验也可以做好
    步骤耗时百分比
    需求分析 10min 6%
    设计 30min 18%
    代码实现 70min 41%
    测试 20min 12%
    分析总结 40min 23%
  • 相关阅读:
    【网络】【操作系统】select、poll、epoll
    【JMM】java内存模型及volatile关键字底层
    【数据库】连接查询(from 内连接 外连接)
    【数据库】SQL牛客练习关键点复习
    【SpringMVC】文件/图片 的下载与上传
    【SpringMVC】拦截器实现与网页跳转步骤
    什么是hashMap,初始长度,高并发死锁,java8 hashMap做的性能提升
    自己写一个HashMap
    String去除重复字符两个方法
    Solr与Elasticsearch比较
  • 原文地址:https://www.cnblogs.com/zxja/p/10728890.html
Copyright © 2011-2022 走看看