• 2015526 《Java程序设计》实验二实验报告


    2015526 《Java程序设计》实验二实验报告

    一、单元测试和TDD

    • 用程序解决问题时,要学会写以下三种代码:

      • 伪代码

      • 产品代码

      • 测试代码

      • 正确的顺序应为:伪代码(思路)→ 测试代码(产品预期功能)→ 产品代码(实现预期功能),这种开发方法叫“测试驱动开发”(TDD)。

      • TDD的一般步骤如下:

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

    基于TDD,可以有效避免过度开发的现象,因为我们只需要让测试通过即可。

    任务一:实现百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能

    1. 首先设计伪代码。
    百分制转五分制:
    如果成绩小于60,转成“不及格”
    如果成绩在60与70之间,转成“及格”
    如果成绩在70与80之间,转成“中等”
    如果成绩在80与90之间,转成“良好”
    如果成绩在90与100之间,转成“优秀”
    其他,转成“错误”
    
    1. 其次,选择一种语言把伪代码实现,也就成了产品代码
    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 "错误";
        }
    }
    
    1. 这是我们就需要写测试代码。根据我们现在的理解,测试代码不就是不断调用System.out.println():
    public class MyUtilTest {
        public static void main(String[] args) {
            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!");
        }
    }
    
    实验结果

    任务二:以TDD的方式研究学习StringBuffer

    1.这个任务主要锻炼我们自己写JUnit测试用例的能力。老师在教程里给出的程序如下:

    public static void main(String [] args){
           StringBuffer buffer = new StringBuffer();
           buffer.append('S');
           buffer.append("tringBuffer");
           System.out.println(buffer.charAt(1));
           System.out.println(buffer.capacity());
           System.out.println(buffer.length());
           System.out.println(buffer.indexOf("tring"));
           System.out.println("buffer = " + buffer.toString());
           
           
    
    1. 对于这个程序,设计测试代码
    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 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"));
            assertEquals(10,a.indexOf("er"));
        }
    }
    
    
    实验结果

    任务三:对MyDoc类进行扩充,让其支持Boolean类,初步理解设计模式

    1. OCP是OOD中最重要的一个原则,要求软件实体(类,模块,函数等)应该对扩充开放,对修改封闭。也就是说,软件模块的行为必须是可以扩充的,在应用需求改变或需要满足新的应用需求时,我们要让模块以不同的方式工作;同时,模块的源代码是不可改动的,任何人都不许修改已有模块的源代码。OCP可以用以下手段实现:(1)抽象和继承,(2)面向接口编程。

    以这道题为例,已有的支持Int型的代码如下:

    abstract class Data{
        public abstract void DisplayValue(); 
    } 
    class Integer extends Data { 
      int value; 
       Integer(){
          value=100;  
       }  
       public void DisplayValue(){
           System.out.println(value); 
       }  
    }
    class Document { 
         Data pd; 
         Document() { 
            pd=new Integer(); 
         } 
         public void DisplayData(){
            pd.DisplayValue(); 
         }     
    } 
    public class MyDoc {
        static Document d;    
        public static void main(String[] args) {
            d = new Document(); 
            d.DisplayData();      
        }   
    }
    

    2.如果要求支持Boolean类,更改。

    // 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 Boolean extends Data { //Boolean类
        boolean value;
        Boolean() {
            value=false;
        }
        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 BooleanFactory extends Factory { //抽象出Boolean工厂
        public Data CreateDataObject() {
            return new Boolean();
        }
    }
    //Client classes
    class Document {
        Data pd;
        Document(Factory pf){
            pd = pf.CreateDataObject();
        }
        public void DisplayData(){
            pd.DisplayValue();
        }
    }
    //Test class
    public class MyDoc20155314 {
        static Document d;
        static Document b;
        public static void main(String[] args) {
            d = new Document(new IntFactory());
            b = new Document(new BooleanFactory());  //实例化Boolean型变量b
            d.DisplayData();
            b.DisplayData();
        }
    }
    

    任务四:以TDD的方式开发一个复数类Complex

    1. 经过以上的学习,我们已经可以基本熟练地应用TDD方法,并跟随TDD方法的节奏设计出伪代码、产品代码和测试代码了,这个任务算是对以上学习内容的回顾。
    • TDD的编码节奏是:

      • 增加测试代码,JUnit出现红条
      • 修改产品代码
      • JUnit出现绿条,任务完成。
    1. 测试代码:
    public class ComplexTest extends TestCase {
        Complex c1 = new Complex(0, 3);
        Complex c2 = new Complex(-1, -1);
        Complex c3 = new Complex(2,1);
        @Test
        public void testgetRealPart() throws Exception {
            assertEquals(-1.0, Complex.getRealPart(-1.0));
            assertEquals(5.0, Complex.getRealPart(5.0));
            assertEquals(0.0, Complex.getRealPart(0.0));
        }
        @Test
        public void testgetImagePart() throws Exception {
            assertEquals(-1.0, Complex.getImagePart(-1.0));
            assertEquals(5.0, Complex.getImagePart(5.0));
            assertEquals(0.0, Complex.getImagePart(0.0));
        }
        @Test
        public void testComplexAdd() throws Exception {
            assertEquals("-1.0+2.0i", c1.ComplexAdd(c2).toString());
            assertEquals("2.0+4.0i", c1.ComplexAdd(c3).toString());
            assertEquals("1.0", c2.ComplexAdd(c3).toString());
        }
        @Test
        public void testComplexSub() throws Exception {
            assertEquals("1.0+4.0i", c1.ComplexSub(c2).toString());
            assertEquals("-2.0+2.0i", c1.ComplexSub(c3).toString());
            assertEquals("-3.0 -2.0i", c2.ComplexSub(c3).toString());
        }
        @Test
        public void testComplexMulti() throws Exception {
            assertEquals("3.0 -3.0i", c1.ComplexMulti(c2).toString());
            assertEquals("-3.0+6.0i", c1.ComplexMulti(c3).toString());
            assertEquals("-1.0 -3.0i", c2.ComplexMulti(c3).toString());
        }
        @Test
        public void testComplexComplexDiv() throws Exception {
            assertEquals("-1.5 -1.5i", c1.ComplexDiv(c2).toString());
            assertEquals("1.2+0.6i", c1.ComplexDiv(c3).toString());
            assertEquals("-0.6 -0.6i", c2.ComplexDiv(c3).toString());
        }
    }
    
    1. 产品代码如下:
    public class Complex{
        private double r;
        private double i;
        public Complex(double r, double i) {
            this.r = r;
            this.i = i;
        }
    
        public static double getRealPart(double r) {
            return r;
        }
    
        public static double getImagePart(double i) {
            return i;
        }
    
        public Complex ComplexAdd(Complex c) {
            return new Complex(r + c.r, i + c.i);
        }
        public Complex ComplexSub(Complex c) {
            return new Complex(r - c.r, i - c.i);
        }
        public Complex ComplexMulti(Complex c) {
            return new Complex(r * c.r - i * c.i, r * c.i + i * c.r);
        }
        public Complex ComplexDiv(Complex c) {
            return new Complex((r * c.i + i * c.r)/(c.i * c.i + c.r * c.r), (i * c.i + r * c.r)/(c.i * c.i + c.r * c.r));
        }
    
        public String toString() {
            String s = " ";
            if (i > 0)
                s =  r + "+" + i + "i";
            if (i == 0)
                s =  r + "";
            if (i < 0)
                s = r + " " + i + "i";
            return s;
        }
    }
    

    任务五:使用StarUML对实验二中的代码进行建模

    • UML是一种通用的建模语言,可以非常直观地表现出各个结构之间的关系。
    实验结果

  • 相关阅读:
    Java ConcurrentModificationException 异常分析与解决方案
    Kafka剖析(一):Kafka背景及架构介绍
    Linux下更改oracle客户端字符集和服务端字符集
    storm-kafka源码走读之KafkaSpout
    kafka系列之(3)——Coordinator与offset管理和Consumer Rebalance
    Kafka源码深度解析-序列7 -Consumer -coordinator协议与heartbeat实现原理
    apache kafka系列之在zookeeper中存储结构
    Java transient关键字使用小记
    Kafka设计解析(一)- Kafka背景及架构介绍
    JavaScript-如何获取页面元素对象,元素id
  • 原文地址:https://www.cnblogs.com/20155226thy/p/6752781.html
Copyright © 2020-2023  润新知