Blog作业总结03

一、前言:

(1)题目集7作为本阶段的开篇,通过两道图形卡片游戏编程题目对前一阶段学习到的继承与多态进行了复习运用。以及学习到了ArrayList的使用方法,并通过此方法,对象的添加以及数据处理有了更为高效的运用。新的编程思路的运用在于:“开-闭”原则以及单一职责原则的运用,通过两道题目迭代,同时知识的更新使用,为后续题目集有了更多的编程思路启发。难度而言,通过率较高,属于新知识,易学,并通过老师给的类图,可以较为轻松完成作业。

 (2)题目集8题目量少,仅一道,难度却是不一样的大。因为这一次的需要我们通过ATM机业务背景自己去设计类间关系,题目本身逻辑简单,考察在实体类,业务类的设计,以及为后续迭代拓展,需要遵守编程的“开-闭原则”以及为将后续添加功能,需要做到设计严谨,对于自己拓展的类也需要遵守“单一职责原则”,总体而言是难度较大的一次作业,需要真正去自己动脑设计,而不是单纯的根据他人的类图编程。

(3)题目集9题量同样也为一道。题目形式也为ATM机类机构设计。本次添加了贷记以及透支取款的功能。本次作业是需要在老师提供的源码上进行功能添加以及本身源码的完善。进行了抽象类,多态,继承的运用。虽是之前就运用过的方式,本次需要我们主动去想到在什么方面进行使用。高质量符合题目要求的源码完成,需要对以上知识点有充分的认识与吸收。此题目本身功能性不复杂,需要我们去做到类的关系调用以及设计类功能是难度所在。

二、设计与分析  采坑心得  改进建议 :

(1)题目集7:(7-1)图形卡片排序游戏 (7-2)图形卡片分组游戏  递进式设计分析总结

设计与分析

7-1 图形卡片排序游戏,复杂度分析以及类图

 

只有几处使用了数组遍历,提高了代码的复杂程度,例如:

public boolean validate(){
    for(Card card : cardList)
    {
        if(card.getShape().validate())
            return true;
        else
            return false;
    }
    return true;
}

  此题还有的重点在于排序,排序代码如下:

public void cardSort(){
    for(int i = 0; i < cardList.size(); i++)
    {
        for(int j = i + 1; j < cardList.size(); j++)
        {
            if(cardList.get(i).getShape().getArea() < cardList.get(j).getShape().getArea())
                Collections.swap(cardList,i,j);
        }
    }
}

public double getAllArea(){
    double sumarea = 0;
    for(Card card : cardList)
    {
        sumarea += card.getShape().getArea();
    }
    return sumarea;
}

输出方法:

public void showResult(){
    System.out.println("The original list:");
    for(int i = 0; i < cardList.size(); i++)
    {
        System.out.print(cardList.get(i).getShape().getShapeName()+":"+String.format("%.2f",cardList.get(i).getShape().getArea())+" ");
    }
    System.out.println();
    System.out.println("The sorted list:");
    cardSort();
    for(int i = 0; i < cardList.size(); i++)
    {
        System.out.print(cardList.get(i).getShape().getShapeName()+":"+String.format("%.2f",cardList.get(i).getShape().getArea())+" ");
    }
    ;
    System.out.println();
    System.out.println("Sum of area:"+String.format("%.2f",getAllArea()));
}

   就7-1而言,作业指导中有给出完整的类图和主方法源码,这对我们做题有很大的指导。对于这道题,考察的就是类的继承、多态性使用方法以及接口的应用。题中要求设计圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid)四种卡片类型,四种卡片均继承于Shape类。另有要求对卡片排序时使用Comparable接口,即Card类需要实现Comparable接口中的CompareTo()方法。这是学习java以来第一次使用Comparable接口,所以开始学习的时候费了点时间,学习了以后发现使用起来非常方便。

7-2 图形卡片分组游戏,类图以及复杂度分析图

 

 排序算法如下:

public void cardSort(){
    Collections.sort(circles);
    Collections.sort(rectangles);
    Collections.sort(triangles);
    Collections.sort(trapezoids);
    String s1="",s2="",s3="",s4="";
    System.out.print("[");
    for(int i=circles.size()-1;i>=0;i--)
        s1=s1+circles.get(i).toString()+" ";
    System.out.print(s1);
    System.out.print("]");
    System.out.print("[");
    for(int i=rectangles.size()-1;i>=0;i--)
        s2=s2+rectangles.get(i).toString()+" ";
    System.out.print(s2);
    System.out.print("]");
    System.out.print("[");
    for(int i=triangles.size()-1;i>=0;i--)
        s3=s3+triangles.get(i).toString()+" ";
    System.out.print(s3);
    System.out.print("]");
    System.out.print("[");
    for(int i=trapezoids.size()-1;i>=0;i--)
        s4=s4+trapezoids.get(i).toString()+" ";
    System.out.print(s4);
    System.out.print("]");
}

 

输出代码如下:

public void showResult(){
    System.out.println("The original list:");
    System.out.print("[");
    double[] s=new double[4];
    for (Card card:cardArrayList){
        System.out.print(card.getShape()+" ");
    }
    System.out.print("]");
    System.out.println();
    System.out.println("The Separated List:");
    System.out.print("[");
    for(Circle circle:circles)
    { System.out.printf("Circle:%.2f ",circle.getArea());
        s[0]=s[0]+circle.getArea();}
    System.out.print("]");
    System.out.print("[");
    for(Rectangle rectangle:rectangles)
    { System.out.printf("Rectangle:%.2f ",rectangle.getArea());
        s[1]=s[1]+rectangle.getArea();}
    System.out.print("]");
    System.out.print("[");
    for(Triangle triangle:triangles)
    {System.out.printf("Triangle:%.2f ",triangle.getArea());
        s[2]=s[2]+triangle.getArea();}
    System.out.print("]");
    System.out.print("[");
    for(Trapezoid trapezoid:trapezoids)
    { System.out.printf("Trapezoid:%.2f ",trapezoid.getArea());
        s[3]=s[3]+trapezoid.getArea();}
    System.out.print("]");
    System.out.println();
    System.out.println("The Separated sorted List:");
    cardSort();
    System.out.println();
    double max=s[0];
    for(int i=0;i<4;i++){
        if(s[i]>=max)
            max=s[i];
    }
    System.out.printf("The max area:%.2f",max);
}

 

就7-2而言,是对7-1题目的迭代,添加的功能有:对初始求出的面积数据进行分组;对分组后的数据在组内进行排序;得到全部图形中的最大面积。首先在DealCardList类中添加了几种Boolean型方法,判断语句采用了匹配字符串的equals语句,进行初步的分类校验。通过创建四种方法,将不同的四种图形的输出方式表示为一种长字符串进行输出,每确定一种图形的种类,以及算出对应面积之后,则将新确定的字符串拼接在之前的字符串后一位,以card顺序i作为循环上限,将每次i对应的图形一个个进行校验,以确定在对应输出位置上。

 采坑心得

 7-2主类开始的代码中较7-1不同的地方是需要先进行一次开始输入的n是否是0的判断,在7-2测试点的要求中,需要对第一个n有特殊的判断,若一开始的n就为0,则需要直接结束程序并输出Worry Format。在一开始进行7-2代码编写时,并没有刻意注意这个问题,导致个别测试点无法通过,后通过测试找到了问题,并完成了代码补充。

public String Circle1() {
        String str = "";
        for(Card i:cardList) {
            if(i.getShape().getShapeName().equals("Circle"))
                str+="Circle:"+String.format("%.2f",i.getShape().getArea()) + " ";
        }
        return str;
    }
    public String Rectangle2() {
        String str = "";
        for(Card i:cardList) {
            if(i.getShape().getShapeName().equals("Rectangle"))
                str+="Rectangle:"+String.format("%.2f",i.getShape().getArea()) + " ";
        }
        return str;
    }
    
    public String Triangle3() {
        String str = "";
        for(Card i:cardList) {
            if(i.getShape().getShapeName().equals("Triangle"))
                str+="Triangle:"+String.format("%.2f",i.getShape().getArea()) + " ";
        }
        return str;
    }
    
    
    public String Trapezoid4() {
        String str = "";
        for(Card i:cardList) {
            if(i.getShape().getShapeName().equals("Trapezoid"))
            str+="Trapezoid:"+String.format("%.2f",i.getShape().getArea()) + " ";
        }
        return str;
    }

  该部分的代码是为后续分组的呈现所额外书写的。一开始对于分组的实现想的是通过遍历后对i对应的CardName进行equals检验字符串,再创建四钟List存储得到的分组结果。后发现该种思路的书写过于亢长且逻辑混乱,代码再eclipse中得到了正确结果,在PTA中因代码长度限制,从而更改了思路,直接采用四种方法遍历,去匹配到组别以及位置。

double max = 0;
        double sum = 0;
        for(Card i:cardList) {
            if(i.getShape().getShapeName().equals("Circle"))
            sum+= i.getShape().getArea();
        }
        if(sum > max) {
            max = sum;
        }
        sum = 0;
        for(Card i:cardList) {
            if(i.getShape().getShapeName().equals("Rectangle"))
            sum+= i.getShape().getArea();
        }
        if(sum > max) {
            max = sum;
        }
        sum = 0;
        for(Card i:cardList) {
            if(i.getShape().getShapeName().equals("Triangle"))
            sum+= i.getShape().getArea();
        }
        if(sum > max) {
            max = sum;
        }
        sum = 0;
        for(Card i:cardList) {
            if(i.getShape().getShapeName().equals("Trapezoid"))
            sum+= i.getShape().getArea();
        }
        if(sum > max) {
            max = sum;
        }
        sum = 0;
        System.out.print(String.format("%.2f",max));

  该部分代码为求面积和最大值的功能。初始设计时对于题目理解错误,认为是求单个图形的面积最大值,所写出的for循环更多,遍历的时间更长。后发现无法通过大多数的测试点,通过PTA测试点分析,得到是题目理解出了问题,删减了一部分代码后,添加的if语句找到了图形面积和最大值。并得到了对应的输出。

改进建议

1.7-2中提出了新的要求:分组,分组后排序,组面积和最大值寻找。在7-2中对于新功能的添加,更多是通过if语句与for语句进行识别,再通过添加新的方法去实现。后通过进行题目集9中ATM机设计中认识拓展性并不是通过一昧的if与for循环进行添加功能,可以对每个实体类进行充分的利用,拓展。本次题目中的分组问题可以通过在每个实体类中便设定一种“标签”方法,标签方法有统一的接口,在分组的过程中,通过图形对象调用该方法去确定属于哪一类并只和同一种图形标签的对象输出在一个[]之中。

2.求组面积和的功能上,不需要如上述写的在分组之后,再重复遍历去求和,再进行组与组之间的比较。可以在分组的时候,便同时进行面积的加合,待全部的图形面积完成了对应的分组,也同时完成了面积和的运算。

(2)题目集8:(7-1)ATM机类结构设计(一) 题目集9:(7-1)ATM机类结构设计(二)  ATM机仿真题目的设计思路分析总结

设计与分析

7-1 类图以及复杂度分析

 

 

7-2类图以及复杂度分析:

  说实话,刚做这道题的时候,根本没有思路,完全写不出来,题目有些晦涩难懂,可能是因为太多的类设计非常复杂,一环套一环,思路很乱,不知从何下手。题目给的信息还算比较全面的,但其实有一些在最后运行中可能用不上,但如果在实际生活中,是有必要的。例如账户,其实在输入输出中未曾出现过,但其实在类间套中还是发挥了很大的作用,在最初的代码中,由于发现很多类其实用不太到,所以没有在代码中并没有加入相应类。类间关系设计又问题,另外,ArrayList用得不对,未能很好的弄清楚ArrayList是做什么的,导致代码没有扩展性和维护性。主类写的过于复杂,非常不整洁。主类内用的都是for循环内的if-else语句,所以说代码没有扩展性和维护性,没有实现面向对象的思维。

  就题目集9的7-1而言,跟题目集8的7-1有所不同的是添加一种信用卡,可以进行贷记操作,以及银联有了超额度的服务费扣取功能,跨行收费。该功能的添加与对本身代码的优化修改是难点。难在不知在哪进行修改,不知如何添加在恰当位置,且易将本来具有简单功能的代码解构,难以保证质量。在该代码中,我设计了账户父类与卡父类,以下有借记账户子类,信用账户子类以及借记卡与信用卡的子类。通过构造统一的卡类,其中包含着两种子卡类,账户类同理。其中在功能计算中,通过instanceof方法对不同类别的账户进行不同的超出额度输出判断。

 采坑心得

   该部分为判断取款金额是否大于余额的判断,以及对判断结果对应的数据处理。其中容易掉入的陷阱是,若金额已经达到了透支,则不适用money = amount的数据处理。一开始设计单纯的采用单一的数据处理,后测试点部分无法通过,进行了透支测试后发现了问题

  该部分代码进行对账户的类型判断,进而对对应账户进行不同的账户余额检验,例如借记账户仅用考虑10000的上限,而信用账户拥有贷记的功能,有50000的透支上限,两类不同的余额检验需要分开进行判断。

 1.在判断是否是贷记账户类还是借记账户类上,这一步如可以不用进行类的判断,设计一个统一的接口进行同名方法处理,则更可体现出多态性。也延续了代码的可拓展性以及可维护性。

 2.业务类过于繁重,可以通过设计两个业务类,一是数据校验判断业务类,而是数据处理业务类,这样更可以体现出程序设计的单一职责原则。

 3.在账户之间设定可联系的类,可为后续设计转款功能作为基础,或是在数据处理类中添加方法去完成转款功能。

三、总结

   本次阶段的三次作业,更多的是对所学类设计的应用,主要是对两种原则的掌握:“开-闭”原则,单一职责原则。以及对于“封装性,继承,多态,复用等”需要有自己的理解去很好的利用。从题目集1到现在的题目集9,难度真的跨越度还蛮大的,但是一次次的题目集的练习,写代码的技巧,算法能力,速度都有所提升了。但是说是否每一次题目我都很好的理解透彻彻了,这肯定是没有的,我还有很多不懂的地方,比如说正则表达式还是用的一般般,只能一些简单的用法,每次使用还要借助网页的正则表达式测试工具;再者,类设计这个大问题希望在日后的学习中能相应改进,能设计得规范、逻辑性强。对于设计的想法,面向对象设计的初衷在于将处理的事情对象化,对象要求什么功能,我们便需要去满足它。在这一阶段本身题目逻辑并不复杂,考察的是我们对于一个事物去实现,我们该如何去做的一个好的设计,设计围绕着可维护,可拓展,以及后续根据源码去添加功能,都在让我们学习并实际去运用着面向对象编程的设计思想。

posted @ 2021-12-18 19:56  azaz+  阅读(112)  评论(0)    收藏  举报