zoukankan      html  css  js  c++  java
  • 20172319 实验二《Java面向对象程序设计》实验报告

    20172319 2018.04.17-30

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

    课程名称:《程序设计与数据结构》  
    学生班级:1723班  
    学生姓名:唐才铭  
    学生学号:20172319 
    实验教师:王志强老师
    课程助教:刘伟康、张旭升学长
    实验时间:2018年4月17日——2018年4月30日
    必修/选修:必修
    

    目录


    实验内容

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

    返回目录


    实验要求

    1. 没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》课程
    2. 完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导
    3. 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。
    4. 请大家先在实验楼中的~/Code目录中用自己的学号建立一个目录,代码和UML图要放到这个目录中,截图中没有学号的会要求重做,然后跟着下面的步骤练习。

    返回目录


    实验步骤

    前期准备:

    1. 预先安装好IDEA

    2. 在IDEA中安装JUnitGenerator V2.0插件

    3. 下载安装WhiteStarUML;并学习如何画UML类图

    需求分析:

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

    返回目录


    代码实现及解释

    本次实验一共分为五个提交点:

    • 1.自主学习单元测试(考查JUnit的使用):

    • 在编程前要学会写三种代码:伪代码、产品代码、测试代码
      举例:新建MyUtil类,在其中解决一个百分制成绩转成“优、良、中、及格、不及格”五级制成绩的功能。

    • 我们先来写一下伪代码(汉英皆可):

        百分制转五分制:
        如果成绩小于60,转成“不及格”
        如果成绩在60与70之间,转成“及格”
        如果成绩在70与80之间,转成“中等”
        如果成绩在80与90之间,转成“良好”
        如果成绩在90与100之间,转成“优秀”
        其他,转成“错误”
    
    • 产品代码(即用编程语言翻译"伪代码",以下是最终代码)
    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 "错误";
        }
    
    }
    
    • 测试代码 (正常测试、异常测试、边界测试)
    //Created by tangcaiming on 2018/4/18
    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(105));
            assertEquals("错误", MyUtil.percentage2fivegrade(-55));
        }
    
        @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));
        }
    }
    
    
    • 结果:出现绿条。

    • 初始产品代码可能会有不足,测试的目的就是找出漏洞,然后对所编写的产品代码进行修改、完善,直到出现绿条为止。

    • 2.以TDD的方式研究学习StringBuffer(考查是否会写测试用例)

    • TDD的方式:先写测试代码,然后再写产品代码的开发方法;在测试代码中增加测试代码(尽可能考虑多种情况),测试出现红条,修改产品代码,直至出现绿条为止。

    • StringBufferDemo代码:

    public class StringBufferDemo
    {
        public static void main(String [] args)
        {
            StringBuffer buffer = new StringBuffer(20);
            buffer.append('S');
            buffer.append("tringBuffer");
            System.out.println(buffer.charAt(1));
            System.out.println(buffer.capacity());
            System.out.println(buffer.indexOf("tring12345"));
            System.out.println("buffer = " + buffer.toString());
            System.out.println(buffer.length());
        }
    }
    
    • StringBufferDemoTest代码:
    //  Created by tangcaiming on 2018/4/18
    import junit.framework.TestCase;
    public class StringBufferDemoTest extends TestCase {
        StringBuffer a = new StringBuffer("RollerBaller"); // 测试12个字符(<=16)
        StringBuffer b = new StringBuffer("RollerBallerRollerBaller"); // 测试24个字符(>16&&<=34)
        StringBuffer c = new StringBuffer("RollerBallerRollerBallerRollerBaller"); // 测试36个字符(=>34)
    
        @Test
        public void testcharAt() throws Exception {
            assertEquals('l', a.charAt(3));
            assertEquals('B', a.charAt(6));
            assertEquals('l', a.charAt(9));
        }
    
        @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("Rol"));
            assertEquals(3, b.indexOf("ler"));
            assertEquals(11, c.indexOf("rRo"));
        }
    }
    
    • 结果:出现绿条。

    • 3.对设计模式示例进行扩充,体会OCP原则和DIP原则的应用,初步理解设计模式

    • 用自己的学号%6进行取余运算,根据结果进行代码扩充:
      0:让系统支持Byte类,并在MyDoc类中添加测试代码表明添加正确;
      1:让系统支持Short类,并在MyDoc类中添加测试代码表明添加正确;
      2:让系统支持Boolean类,并在MyDoc类中添加测试代码表明添加正确;
      3:让系统支持Long类,并在MyDoc类中添加测试代码表明添加正确;
      4:让系统支持Float类,并在MyDoc类中添加测试代码表明添加正确;
      5:让系统支持Double类,并在MyDoc类中添加测试代码表明添加正确。

    • MyDoc代码:

    // Server Classes
    abstract class Data {
        abstract public void DisplayValue();
    }
    
    class Integer extends  Data {
        int value;
        Integer() {
            value=20172319%6;
        }
        public void DisplayValue(){
            System.out.println ("学号取余后的余数为:" + value);
        }
    }
    
    class Short extends Data{
        short value;
    
        Short(){value = 12313;}
        public void DisplayValue(){
            System.out.println("支持的类型为Short:" + value);
        }
    }
    
    // Pattern Classes
    abstract class Factory {
        abstract public Data CreateDataObject();
    }
    
    class IntFactory extends Factory{
        public Data CreateDataObject(){
            return new Integer();
        }
    }
    class ShortFactory extends Factory {
        public Data CreateDataObject(){
            return new Short();
        }
    }
    
    //Client classes
    class Document {
        Data pd;
        Document(Factory pf){
            pd = pf.CreateDataObject();
        }
        public void DisplayData(){
            pd.DisplayValue();
        }
    }
    
    //Test class
    public class MyDoc {
        static Document c,d;
        public static void main(String[] args) {
            c = new Document(new IntFactory());
            c.DisplayData();
            d = new Document(new ShortFactory());
            d.DisplayData();
        }
    }
    
    • 结果:
    学号取余后的余数为:1
    支持的类型为Short:12313
    
    • 4.以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)
    
    
    • Complex类代码:
    public class Complex {
        // 定义属性
        private double RealPart;
        private double ImagePart;
    
        // 定义构造函数
        public Complex(){}
        public Complex(double R,double I)
        {
            this.RealPart = R;
            this.ImagePart = I;
        }
    
        // getter,setter
        public void setRealPart(double r)
        {
            this.RealPart = r;
        }
    
        public double getRealPart()
        {
            return this.RealPart;
        }
    
        public void setImagePart(double i)
        {
            this.ImagePart = i;
        }
    
        public double getImagePart()
        {
            return this.ImagePart;
        }
    
        // 定义公有方法:加减乘除
        public Complex ComplexAdd(Complex a)
        {
            return new Complex(RealPart + a.getRealPart(),ImagePart + a.ImagePart);
        }
    
        public Complex ComplexSub(Complex a)
        {
            return new Complex(RealPart - a.getRealPart(),ImagePart - a.ImagePart);
        }
    
        public Complex ComplexMulti(Complex a)
        {
            return new Complex(RealPart * a.getRealPart() - ImagePart * a.getImagePart(),
                    RealPart * a.getImagePart() + ImagePart * a.getRealPart());
        }
    
        public Complex ComplexDiv(Complex a)
        {
            return new Complex((RealPart * a.getRealPart() + ImagePart * a.getImagePart()) / (a.getRealPart() * a.getRealPart() + a.getImagePart() * a.getImagePart()),
                    ((ImagePart * a.getRealPart())-(RealPart *   a.getImagePart())) / (a.getRealPart() * a.getRealPart() + a.getImagePart() * a.getImagePart()));
        }
    
        // Override Object
        public boolean equals(Complex obj)
        {
            if (RealPart == obj.getRealPart() && ImagePart == obj.getImagePart() )
                return true;
            else
                return false;
        }
    
        @Override
        public String toString()
        {
            String result;
            if (ImagePart > 0)
                result = "(" + RealPart + "+" + ImagePart +"i" + ")";
            else
                if (ImagePart < 0)
                    result = "(" + RealPart + "" + ImagePart +"i" + ")";
                else
                    result = RealPart + "" ;
    
            return result;
        }
    }
    
    • ComplexTest代码:
    import junit.framework.TestCase;
    
    public class ComplexTest extends TestCase {
    
        Complex a = new Complex(1,3);
        Complex b = new Complex(0,3);
        Complex c = new Complex(1,6);
        Complex d = new Complex(-9,3);
        Complex e = new Complex(1,1);
        Complex f = new Complex(1,1);
        Complex g = new Complex(1,0);
    
        @Test
        public void testComplexAdd() throws Exception{
            assertEquals(a.ComplexAdd(b).toString(),c.toString());
        }
    
        @Test
        public void testComplexSub() throws Exception{
            assertEquals(c.ComplexSub(b).toString(),a.toString());
        }
    
        @Test
        public void testComplexMulti() throws Exception{
            assertEquals(a.ComplexMulti(b).toString(),d.toString());
        }
    
        @Test
        public void testComplexDiv() throws Exception{
            assertEquals(e.ComplexDiv(f).toString(),g.toString());
        }
    }
    
    • 结果:出现绿条

    • 5.对实验二中的代码进行建模

    • 要求:
      类图中只少两个类;
      类,继承,接口实现,组合在UML中表达;


    返回目录


    测试过程及遇到的问题

    • 问题1:Complex类的编写

    • 解决:实验1、2、3;哐哐哐,地就测试完了,虽然任务完成了,然而对其了解只是知之甚少,兄得,这能叫学习??,似乎实验的存在只是为了复制粘贴,纯属浪费时间,跟个傻子一样什么都不懂。幸好实验4的存在让我看到、也才真正明白了测试的意义。这是第一次,在自己编写的东西里出现了红条,当时写好了测试代码,在除法的测试里结果是期望值与实际值不符合,一经检查,是两个复数之间get的是实部还是虚部的问题。后面,不断针对测试显示的结果对类进行修改,试了好久都没能成功,最后,去重新学了下复数的除法,依据上面的定义再针对自己除法里的代码进行修改,终于出现了绿条。

    • 问题2:UML图的画法

    • 解决:当时学UML图的时候,并没有实践过,所以对上面的东西也仅仅了解皮毛罢了,看到例题有+号、自己也照搬,结果在自己的父类图里private了一些成员,还傻傻地在子类中引用、重新定义。最后仔细查了下关于UML的画法,才真正搞懂了那些字符后面代表的含义。

    返回目录


    分析总结

    • 虚假的繁荣。
    • 虽然有着不爽,但总归学到了点东西:
      1.UML图的构画,能为自己在编程时指引方向;
      2.测试代码的存在和编写,更有利于去完善自己所编写的东西。

    返回目录


    参考资料

    Intellj IDEA 简易教程
    积极主动敲代码,使用JUnit学习Java
    实验二《Java面向对象程序设计》的一点说明

    返回目录

  • 相关阅读:
    KVCKVO
    音频
    静态库
    百度地图API
    CALayer
    触摸事件
    iOS中打电话、打开网址、发邮件、发短信等
    NSURLSession网络接口
    Quartz2D常见图形的绘制:线条、多边形、圆
    通知中心(NSNotificationCenter)
  • 原文地址:https://www.cnblogs.com/Tangcaiming/p/8934797.html
Copyright © 2011-2022 走看看