第三阶段Blog

题目集7~9的总结性Blog


 

1、前言

  一个月又过去了,又到了写blog的时候,相较于前两次Blog,这一次所要分析的内容从原先的侧重于类设计到了这次的侧重于结构设计。在完成作业的时候,尽管题目内提供的指导书十分详细,但在编写程序的途中还是遇到了不少的问题,比如如何设计各个类之间的联系,六大原则的合理运用,功能实现的设计等。


 

2、设计与分析

  ①题目集7(7-1)、(7-2)两道题目的递进式设计分析总结

    首先看一下这两道题目的具体需求吧

  (7-1):

  (1)卡片大小排序游戏规则 考虑一款适合于小学生的卡片(Card)排序游戏,其规则为随机发放一些卡片给学生,卡片分为 四种形状:圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid),并给出各种 卡片的相应参数,要求学生能够迅速求出各卡片的面积大小然后将卡片按照其面积值从大到小进行排 序,同时求出所有卡片的面积之和。

  (2)Comparable 接口的应用 图形类设计可参考作业 6-1 的类层次结构,本次作业要求对卡片排序时使用 Comparable 接口, 即 Card 类需要实现 Comparable 接口中的 CompareTo()方法。

  (7-2):

  (1)卡片大小排序游戏规则 沿袭作业 7-1,本次作业主要对卡片(Card)进行分组游戏,其规则为随机发放一些卡片给学生, 卡片仍然分为四种形状:圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid), 并给出各种卡片的相应参数,要求学生首先根据卡片类型将所有卡片进行分组(一个类型分为一组, 所以最多四组),然后能够对每组内的卡片根据面积值从大到小进行排序,同时求出该组内所有卡片 的面积之和,最后求出每组卡片面积之和中的最大值。

  (2)Comparable、Comparator 接口的应用 图形类设计可参考作业 7-1 的类层次结构(需要进一步完善),本次作业要求对卡片排序时使用 Comparable 接口或 Comparator 接口。 

  

  可以看到,这两道题目的要求十分的相近,都是通过设计对应的类去实现卡片游戏,并且在游戏运行过程中要求使用到Comparable接口以完成对应卡片面积的排序,但在输出以及排序方式上有所不同,在实际编辑代码的过程中其实并没有遇到过多的困难,唯一耗时的地方在于如何如何建立一个正确的CardList属性,并使其能够正确的运行sort()方法,将Card数组进行正确的排序并输出

 

首先先放我的类图和代码吧

(7-1)

 

 

package PTAhmwk.图形卡片排序游戏;


import java.util.*;

public class Main {
    //在Main类中定义一个静态Scanner对象,这样在其它类中如果想要使用该对象进行输入,则直接
//使用Main.input.next…即可(避免采坑)
    public static Scanner input = new Scanner(System.in);
    public static void main(String[] args){
        ArrayList<Integer> list = new ArrayList<Integer>();
        int num = input.nextInt();
        while(num != 0){
            if(num < 0 || num > 4){
                System.out.println("Wrong Format");
                System.exit(0);
            }
            list.add(num);
            num = input.nextInt();
        }
        DealCardList dealCardList = new DealCardList(list);
        if(!dealCardList.validate()){
            System.out.println("Wrong Format");
            System.exit(0);
        }
        dealCardList.showResult();
        input.close();
    }
}


class DealCardList{
    ArrayList<Card> cardList= new ArrayList<Card>();
    DealCardList(){}
    DealCardList(ArrayList<Integer> list){
        for(Integer integer:list){
            switch (integer) {
                case 1:
                    cardList.add(new Card(new Circle(Main.input.nextDouble())));
                    break;
                case 2:
                    cardList.add(new Card(new Rectangle(Main.input.nextDouble(), Main.input.nextDouble())));
                    break;
                case 3:
                    cardList.add(new Card(new Triangle(Main.input.nextDouble(), Main.input.nextDouble(), Main.input.nextDouble())));
                    break;
                case 4:
                    cardList.add(new Card(new Trapezoid(Main.input.nextDouble(), Main.input.nextDouble(), Main.input.nextDouble())));
                    break;
            }
        }
    }


    public boolean validate(){
        boolean flag = true;
        for (Card card : cardList) {
            if (!card.getShape().validate()) {
                flag = false;
                break;
            }
        }
        return flag;
    }

    public void cardSort(){
        Collections.sort(cardList);
    }

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

    public void showResult(){
        System.out.println("The original list:");
        for (Card card : cardList) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        cardSort();
        System.out.println("\nThe sorted list:");
        for (Card card : cardList) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.printf("\nSum of area:%.2f",getAllArea());
    }


}

class Card implements Comparable<Card>{
    private Shape shape;
    Card(){}
    Card(Shape shape){
        setShape(shape);
    }

    public Shape getShape() {
        return shape;
    }

    public void setShape(Shape shape) {
        this.shape = shape;
    }

    public int compareTo(Card card) {
        if(shape.getArea()>card.getShape().getArea())
            return -1;
        else
            return 1;
    }


}

abstract class Shape{
    private String shapeName;
    Shape(){}
    Shape(String shapeName){
        setShapeName(shapeName);
    }

    abstract double getArea();

    abstract boolean validate();

    public String getShapeName() {
        return shapeName;
    }

    public void setShapeName(String shapeName) {
        this.shapeName = shapeName;
    }
}

class Trapezoid extends Shape{
    private double topSide;
    private double bottomSide;
    private double height;

    Trapezoid(){}
    Trapezoid(double topSide,double bottomSide,double height){
        setTopSide(topSide);
        setBottomSide(bottomSide);
        setHeight(height);
        super.setShapeName("Trapezoid");
    }
    public double getArea(){
        return (topSide+bottomSide)*height/2;
    }

    boolean validate() {
       return  getHeight()>0 && getBottomSide()>0 && getTopSide()>0;
    }


    public void setTopSide(double topSide) {
        this.topSide = topSide;
    }

    public void setBottomSide(double bottomSide) {
        this.bottomSide = bottomSide;
    }


    public void setHeight(double height) {
        this.height = height;
    }

    public double getTopSide() {
        return topSide;
    }

    public double getBottomSide() {
        return bottomSide;
    }

    public double getHeight() {
        return height;
    }
}

class Circle extends Shape{
    private double radius;
    Circle(){}
    Circle(double radius){
        setRadius(radius);
        super.setShapeName("Circle");
    }
    double getArea() {
        return radius*radius*Math.PI;
    }

    boolean validate() {
        return getRadius()>0;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }
}

class Rectangle extends Shape{
    private double width;
    private double length;

    Rectangle(){}
    Rectangle(double width,double length){
        setWidth(width);
        setLength(length);
        super.setShapeName("Rectangle");
    }

    double getArea() {
        return getLength()*getWidth();
    }

    boolean validate() {
        return (getWidth() >0 && getLength()>0);
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public double getWidth() {
        return width;
    }

    public double getLength() {
        return length;
    }
}

class Triangle extends Shape{
    private double side1;
    private double side2;
    private double side3;
    Triangle(){}
    Triangle(double side1,double side2,double side3){
        setSide1(side1);
        setSide2(side2);
        setSide3(side3);
        super.setShapeName("Triangle");
    }
    double getArea() {
        double p=(side1+side2+side3)/2;
        return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3));
    }

    boolean validate() {
        if(side1+side2<=side3||side1+side3<=side2||side2+side3<=side1)
        {
            return false;
        }
        return !(side1 - side2 >= side3) && !(side1 - side3 >= side2) && !(side2 - side3 >= side1);
    }

    public void setSide1(double side1) {
        this.side1 = side1;
    }

    public void setSide2(double side2) {
        this.side2 = side2;
    }

    public void setSide3(double side3) {
        this.side3 = side3;
    }
}
点此查看代码

 

 

 

(7-2)

 

 

 

package PTAhmwk.图形卡片分组游戏;


import java.util.*;

public class Main {
    //在Main类中定义一个静态Scanner对象,这样在其它类中如果想要使用该对象进行输入,则直接
//使用Main.input.next…即可(避免采坑)
    public static Scanner input = new Scanner(System.in);
    public static void main(String[] args){
        ArrayList<Integer> list = new ArrayList<Integer>();
        int num = input.nextInt();
        while(num != 0){
            if(num < 0 || num > 4){
                System.out.println("Wrong Format");
                System.exit(0);
            }
            list.add(num);
            num = input.nextInt();
        }
        if(list.size() == 0){
            System.out.println("Wrong Format");
            System.exit(0);
        }
        DealCardList dealCardList = new DealCardList(list);
        if(!dealCardList.validate()){
            System.out.println("Wrong Format");
            System.exit(0);
        }
        dealCardList.showResult();
        input.close();
    }
}


class DealCardList{
    ArrayList<Card> cardList= new ArrayList<>();

    ArrayList<Card> circle = new ArrayList<>();
    ArrayList<Card> rectangle =new ArrayList<>();
    ArrayList<Card> triangle = new ArrayList<>();
    ArrayList<Card> trapezoid = new ArrayList<>();

    DealCardList(){}
    DealCardList(ArrayList<Integer> list){
        for(Integer integer:list){
            switch (integer) {
                case 1:
                    cardList.add(new Card(new Circle(Main.input.nextDouble())));
                    break;
                case 2:
                    cardList.add(new Card(new Rectangle(Main.input.nextDouble(), Main.input.nextDouble())));
                    break;
                case 3:
                    cardList.add(new Card(new Triangle(Main.input.nextDouble(), Main.input.nextDouble(), Main.input.nextDouble())));
                    break;
                case 4:
                    cardList.add(new Card(new Trapezoid(Main.input.nextDouble(), Main.input.nextDouble(), Main.input.nextDouble())));
                    break;
            }
        }
    }


    public boolean validate(){
        boolean flag = true;
        for (Card card : cardList) {
            if (!card.getShape().validate()) {
                flag = false;
                break;
            }
        }
        return flag;
    }

    public void cardSort(){
        Collections.sort(circle);
        Collections.sort(rectangle);
        Collections.sort(triangle);
        Collections.sort(trapezoid);
    }

    public void cardSeparate(){
        for(Card card:cardList){
            switch (card.getShape().getShapeName()){
                case "Circle":
                    circle.add(card);
                    break;
                case "Rectangle":
                    rectangle.add(card);
                    break;
                case "Triangle":
                    triangle.add(card);
                    break;
                case "Trapezoid":
                    trapezoid.add(card);
                    break;
            }
        }
    }

    public double getAllArea(ArrayList<Card> list){
        double total =0;
        for(Card card:list){
            total += card.getShape().getArea();
        }
        return total;
    }

    public double getMaxArea(){
        double maxArea = 0;
        if(getAllArea(circle)>maxArea)
            maxArea = getAllArea(circle);
        if(getAllArea(rectangle)>maxArea)
            maxArea = getAllArea(rectangle);
        if(getAllArea(triangle)>maxArea)
            maxArea = getAllArea(triangle);
        if(getAllArea(trapezoid)>maxArea)
            maxArea= getAllArea(trapezoid);
        return maxArea;
    }

    public void showResult(){
        System.out.println("The original list:");
        System.out.print("[");
        for (Card card : cardList) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("]");

        System.out.println("\nThe Separated List:");
        cardSeparate();
        System.out.print("[");
        for (Card card : circle) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("][");
        for (Card card : rectangle) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("][");
        for (Card card : triangle) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("][");
        for (Card card : trapezoid) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("]");

        System.out.println("\nThe Separated sorted List:");
        cardSort();
        System.out.print("[");
        for (Card card : circle) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("][");
        for (Card card : rectangle) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("][");
        for (Card card : triangle) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("][");
        for (Card card : trapezoid) {
            System.out.printf("%s:%.2f ", card.getShape().getShapeName(), card.getShape().getArea());
        }
        System.out.print("]");


        System.out.printf("\nThe max area:%.2f",getMaxArea());
    }
}

class Card implements Comparable<Card>{
    private Shape shape;
    Card(){}
    Card(Shape shape){
        setShape(shape);
    }

    public Shape getShape() {
        return shape;
    }

    public void setShape(Shape shape) {
        this.shape = shape;
    }

    public int compareTo(Card card) {
        if(shape.getArea()>card.getShape().getArea())
            return -1;
        else
            return 1;
    }


}

abstract class Shape{
    private String shapeName;
    Shape(){}
    Shape(String shapeName){
        setShapeName(shapeName);
    }

    abstract double getArea();

    abstract boolean validate();

    public String getShapeName() {
        return shapeName;
    }

    public void setShapeName(String shapeName) {
        this.shapeName = shapeName;
    }
}

class Trapezoid extends Shape{
    private double topSide;
    private double bottomSide;
    private double height;

    Trapezoid(){}
    Trapezoid(double topSide,double bottomSide,double height){
        setTopSide(topSide);
        setBottomSide(bottomSide);
        setHeight(height);
        super.setShapeName("Trapezoid");
    }
    public double getArea(){
        return (topSide+bottomSide)*height/2;
    }

    boolean validate() {
        return  getHeight()>0 && getBottomSide()>0 && getTopSide()>0;
    }


    public void setTopSide(double topSide) {
        this.topSide = topSide;
    }

    public void setBottomSide(double bottomSide) {
        this.bottomSide = bottomSide;
    }


    public void setHeight(double height) {
        this.height = height;
    }

    public double getTopSide() {
        return topSide;
    }

    public double getBottomSide() {
        return bottomSide;
    }

    public double getHeight() {
        return height;
    }
}

class Circle extends Shape{
    private double radius;
    Circle(){}
    Circle(double radius){
        setRadius(radius);
        super.setShapeName("Circle");
    }
    double getArea() {
        return radius*radius*Math.PI;
    }

    boolean validate() {
        return getRadius()>0;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }
}

class Rectangle extends Shape{
    private double width;
    private double length;

    Rectangle(){}
    Rectangle(double width,double length){
        setWidth(width);
        setLength(length);
        super.setShapeName("Rectangle");
    }

    double getArea() {
        return getLength()*getWidth();
    }

    boolean validate() {
        return (getWidth() >0 && getLength()>0);
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public double getWidth() {
        return width;
    }

    public double getLength() {
        return length;
    }
}

class Triangle extends Shape{
    private double side1;
    private double side2;
    private double side3;
    Triangle(){}
    Triangle(double side1,double side2,double side3){
        setSide1(side1);
        setSide2(side2);
        setSide3(side3);
        super.setShapeName("Triangle");
    }
    double getArea() {
        double p=(side1+side2+side3)/2;
        return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3));
    }

    boolean validate() {
        if(side1+side2<=side3||side1+side3<=side2||side2+side3<=side1)
        {
            return false;
        }
        return !(side1 - side2 >= side3) && !(side1 - side3 >= side2) && !(side2 - side3 >= side1);
    }

    public void setSide1(double side1) {
        this.side1 = side1;
    }

    public void setSide2(double side2) {
        this.side2 = side2;
    }

    public void setSide3(double side3) {
        this.side3 = side3;
    }
}
点此查看代码

  对这两个题目稍微做一下总结吧,实际上这两道题主要还是考察了对接口的使用以及接口内方法的重写,实际上并不是很困难,所以并没有花费我多少时间。从我的代码及类图中也可以看到,在不考虑后续的代码维护的情况下,我在(7-2)中的DealCardList类中增加了许多对应不同图形的属性(才不是我偷懒),这样虽然并不满足面对对象编程的开闭原则,但对于这类简单的小程序来说还是可以满足对应需求的,但这也说明了在后续实际的工作中,必须得尽可能的减少此类偷懒的做法,以免在后续程序的维护升级过程中对原先存在的代码进行过多的修改。


 

 ②题目集8和题目集9两道ATM机仿真题目的设计思路分析总结

  先看一下这两道题目的要求吧

  编写一个银行 ATM 机的模拟程序,能够完成用户的存款、取款以及查询余额功能。

  怎么说呢,其实在这个学期开始的时候,作业中曾经出现过类似的题目,但对比之下可以发现这一次的题目要求明显细致了许多,要求完成账号的创建存储以及对应的存取操作,并且需要根据题目指导书中所给出的数据为其建立对应的从属关系,即用户-账号-银行卡号结构,这不仅仅是完善了对ATM机的模拟,也为程序的结构设计增添了不小的麻烦,举个很简单的例子,如何在不同的类中访问不同层级的数据,并将输入数据与整个账号结构内的数据进行对比(即如何用银行卡号按用户-账号-银行卡号结构进行查找、对比),并将其按照输入内容进行对应的操作。

 


 

  老规矩,上代码和类图

7-3 ATM机类结构设计(一)

 

 

 

 

  1 package PTAhmwk.ATM机类结构设计;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Objects;
  5 import java.util.Scanner;
  6 
  7 public class Main {
  8     public static void main(String[] args) {
  9         Scanner input = new Scanner(System.in);
 10         ArrayList<ATM> atmList = new ArrayList<>();
 11         ChinaUnionPay union = new ChinaUnionPay(atmList);
 12 
 13         String [] nameList ={"杨过","郭靖","张无忌","韦小宝"};
 14 
 15         ArrayList<User> user = new ArrayList<>();//初始化银行数据
 16         for(int i = 0;i<4;i++){
 17             user.add(new User(nameList[i]));
 18         }
 19 
 20 
 21         user.get(0).accountList.add(new Account("3217000010041315709","中国建设银行"));
 22         user.get(0).accountList.add(new Account("3217000010041315715","中国建设银行"));
 23         user.get(1).accountList.add(new Account("3217000010051320007","中国建设银行"));
 24         user.get(2).accountList.add(new Account("3222081502001312389","中国工商银行"));
 25         user.get(2).accountList.add(new Account("3222081502001312390","中国工商银行"));
 26         user.get(2).accountList.add(new Account("3222081502001312399","中国工商银行"));
 27         user.get(3).accountList.add(new Account("3222081502051320785","中国工商银行"));
 28         user.get(3).accountList.add(new Account("3222081502051320786","中国工商银行"));
 29         //创建账户
 30 
 31         user.get(0).accountList.get(0).cardList.add(new Card("6217000010041315709"));
 32         user.get(0).accountList.get(0).cardList.add(new Card("6217000010041315715"));
 33         user.get(0).accountList.get(1).cardList.add(new Card("6217000010041315718"));
 34 
 35         user.get(1).accountList.get(0).cardList.add(new Card("6217000010051320007"));
 36 
 37         user.get(2).accountList.get(0).cardList.add(new Card("6222081502001312389"));
 38         user.get(2).accountList.get(1).cardList.add(new Card("6222081502001312390"));
 39         user.get(2).accountList.get(2).cardList.add(new Card("6222081502001312399"));
 40         user.get(2).accountList.get(2).cardList.add(new Card("6222081502001312400"));
 41 
 42         user.get(3).accountList.get(0).cardList.add(new Card("6222081502051320785"));
 43         user.get(3).accountList.get(1).cardList.add(new Card("6222081502051320786"));
 44         //创建银行卡
 45 
 46 
 47 
 48         String atmIn = input.nextLine();
 49 
 50         while(!atmIn.equals("#")){
 51             String[] inList= atmIn.split("\\s+");
 52 
 53             if(inList.length != 1) {
 54                 if (Check.check(user, atmList, inList[0], inList[1], inList[2], inList[3])) {
 55                     ATM.deal(inList[0], inList[2], Double.parseDouble(inList[3]), user);
 56                     System.out.printf("当前余额为¥%.2f\n",user.get(ATM.getUser(inList[0],user)).accountList.get(ATM.getAccount(inList[0],user)).balance);
 57                 }
 58                 else break;
 59             }
 60 
 61             else {
 62                 ATM.show(inList[0],user);
 63             }
 64 
 65             atmIn = input.nextLine();
 66         }
 67 
 68 
 69 
 70     }
 71 
 72 
 73 }
 74 
 75 class Check{
 76 
 77     public static boolean check(ArrayList<User> userList,ArrayList<ATM> atmList,String cardId,String password,String atmId,String amount){
 78         int flag = -1;
 79 
 80 
 81 
 82 
 83         if(ATM.matchCard(cardId,userList)){
 84             flag = 1;
 85         }
 86         else {
 87             System.out.println("Sorry,this card does not exist.");
 88             return false;
 89         }
 90 
 91         //检查卡号是否正确
 92 
 93         if(flag == 1 && ATM.matchPassword(password)) {
 94             flag = 2;
 95         }
 96         else {
 97             System.out.println("Sorry,your password is wrong.");
 98             return false;
 99         }
100         //检查密码是否正确
101         if(flag == 2 && ATM.matchAtm(atmId,atmList)){
102             flag = 3;
103         }
104         else {
105             System.out.println("Sorry,the ATM's id is wrong.");
106             return false;
107         }
108         //检查ATM机编号是否正确
109         if(flag == 3 && ATM.matchAmount(cardId,Double.parseDouble(amount),userList)){
110             flag =4;
111         }
112         else {
113             System.out.println("Sorry,your account balance is insufficient.");
114             return false;
115         }
116         //检查金额是否正确
117         if(flag == 4 && ATM.matchBank(atmId,cardId,userList,atmList)){
118             return true;
119         }
120         else{
121 
122             System.out.println("Sorry,cross-bank withdrawal is not supported.");
123             return false;
124         }
125         //检查是否跨行
126 
127     }
128 }
129 
130 
131 
132 
133 
134 class ChinaUnionPay{
135     Bank ccb;
136     Bank icbc;
137     ArrayList<ATM> atmList;
138     public ChinaUnionPay(ArrayList<ATM> atmList) {
139         this.atmList = atmList;
140         initBank();
141     }
142     void initBank(){
143         ccb = new Bank("中国建设银行",4,atmList);
144         icbc = new Bank("中国工商银行",2,atmList);
145     }
146 
147 }
148 
149 class Bank {
150     String bankName;
151     int atmNum;
152     public Bank(String bankName,int atmNum,ArrayList<ATM> atmList) {
153         this.bankName = bankName;
154         this.atmNum = atmNum;
155         for(int i = 0;i<atmNum;i++){
156             atmList.add(new ATM(this.bankName,"0"+ (atmList.size()+1)));
157         }
158     }
159 }
160 
161 
162 
163 class User extends ArrayList<User> {
164     String userName;
165     ArrayList<Account> accountList =new ArrayList<>();
166     public User(String userName) {
167         this.userName = userName;
168     }
169 }
170 
171 class Account{
172     String accountNo;
173     String bankName;
174     double balance = 10000;
175 
176 
177     ArrayList<Card> cardList = new ArrayList<>();
178     public Account(String accountNo,String bankName) {
179         this.accountNo = accountNo;
180         this.bankName = bankName;
181     }
182 }
183 
184 class Card {
185     String cardNo;
186     String password = "88888888";
187 
188     public Card(String cardNo) {
189         this.cardNo = cardNo;
190     }
191 }
192 
193 class ATM {
194     String bankName;
195     String ATMNo;
196     public ATM(String bankName,String ATMNo) {
197         this.bankName = bankName;
198         this.ATMNo = ATMNo;
199     }
200 
201     public static void deal(String cardNo,String ATMNo,double amount,ArrayList<User> userList){
202 
203         userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance -= amount;
204 
205         show(userList.get(getUser(cardNo, userList)).userName,userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).bankName,ATMNo,amount);
206     }//处理存取操作
207 
208     public static boolean matchCard(String cardNo, ArrayList<User> userList) {
209         return getCard(cardNo,userList) != -1;
210     }//检查是否存在银行卡
211 
212     public static boolean matchPassword(String password){
213         return Objects.equals(password, "88888888");
214     }//检测密码是否正确
215 
216     public static boolean matchBank(String ATMNo,String cardNo,ArrayList<User> userList,ArrayList<ATM> atmList){
217         return Objects.equals(userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).bankName, atmList.get(getAtm(ATMNo, atmList)).bankName);
218     }//检测银行是否正确
219 
220     public static boolean matchAmount(String cardNo, double amount,ArrayList<User> userList){
221         return userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance > amount;
222     }//检测取出金额是否合法
223 
224     public static boolean matchAtm(String atmNo,ArrayList<ATM> atmList){
225         return getAtm(atmNo, atmList) != -1;
226     }
227 
228     public static void show(String userName,String bankName,String ATMNo,double amount){
229         if(amount > 0)
230             System.out.printf("%s在%s的%s号ATM机上取款¥%.2f\n",userName,bankName,ATMNo,amount);
231         else
232             System.out.printf("%s在%s的%s号ATM机上存款¥%.2f\n",userName,bankName,ATMNo,-amount);
233     }//显示存取结果
234 
235     public static void show(String cardNo,ArrayList<User> userList){
236         System.out.printf("¥%.2f\n",userList.get(getUser(cardNo,userList)).accountList.get(getAccount(cardNo,userList)).balance);
237     }
238 
239     public static int getCard(String cardNo, ArrayList<User> userList){
240         for (int i = 0;i< userList.size();i++){
241             for (int j = 0;j<userList.get(i).accountList.size();j++){
242                 for (int l = 0;l<userList.get(i).accountList.get(j).cardList.size();l++){
243                     if(Objects.equals(userList.get(i).accountList.get(j).cardList.get(l).cardNo, cardNo))
244                         return l;
245                 }
246             }
247 
248         }
249 
250         return -1;
251     }//获取银行卡对应下标
252 
253     public static int getAtm(String ATMNo,ArrayList<ATM> atmList){
254         for(int i = 0;i<atmList.size();i++){
255             if(Objects.equals(atmList.get(i).ATMNo, ATMNo))
256                 return i;
257         }
258         return -1;
259     }//获取ATM对应下标
260 
261     public static int getAccount(String cardNo, ArrayList<User> userList){
262         for (int i = 0;i< userList.size();i++){
263             for (int j = 0;j<userList.get(i).accountList.size();j++){
264                 for (int l = 0;l<userList.get(i).accountList.get(j).cardList.size();l++){
265                     if(Objects.equals(userList.get(i).accountList.get(j).cardList.get(l).cardNo, cardNo))
266                         return j;
267                 }
268             }
269         }
270         return -1;
271     }//获取账户对应下标
272 
273     public static int getUser(String cardNo, ArrayList<User> userList){
274         for (int i = 0;i< userList.size();i++){
275             for (int j = 0;j<userList.get(i).accountList.size();j++){
276                 for (int l = 0;l<userList.get(i).accountList.get(j).cardList.size();l++){
277                     if(Objects.equals(userList.get(i).accountList.get(j).cardList.get(l).cardNo, cardNo))
278                         return i;
279                 }
280             }
281         }
282         return -1;
283     }//获取用户对应下标
284 
285 }
点此查看代码

 

 

7-1 ATM机类结构设计(二)

 

 

 

  1 import java.util.ArrayList;
  2 import java.util.Objects;
  3 import java.util.Scanner;
  4 
  5 public class Main {
  6     public static void main(String[] args) {
  7         Scanner input = new Scanner(System.in);
  8         ArrayList<ATM> atmList = new ArrayList<>();
  9         ChinaUnionPay union = new ChinaUnionPay(atmList);
 10 
 11         String [] nameList ={"杨过","郭靖","张无忌","韦小宝","张三丰","令狐冲","乔峰","洪七公"};
 12 
 13         ArrayList<User> user = new ArrayList<>();//初始化银行数据
 14         for(int i = 0;i< nameList.length;i++){
 15             user.add(new User(nameList[i]));
 16         }
 17 
 18 
 19 
 20         user.get(0).accountList.add(new Account("3217000010041315709","中国建设银行","借记账号"));
 21         user.get(0).accountList.add(new Account("3217000010041315715","中国建设银行","借记账号"));
 22 
 23         user.get(1).accountList.add(new Account("3217000010051320007","中国建设银行","借记账号"));
 24 
 25         user.get(2).accountList.add(new Account("3222081502001312389","中国工商银行","借记账号"));
 26         user.get(2).accountList.add(new Account("3222081502001312390","中国工商银行","借记账号"));
 27         user.get(2).accountList.add(new Account("3222081502001312399","中国工商银行","借记账号"));
 28 
 29         user.get(3).accountList.add(new Account("3222081502051320785","中国工商银行","借记账号"));
 30         user.get(3).accountList.add(new Account("3222081502051320786","中国工商银行","借记账号"));
 31 
 32         user.get(4).accountList.add(new Account("3640000010045442002","中国建设银行","贷记账号"));
 33 
 34         user.get(5).accountList.add(new Account("3640000010045441009","中国工商银行","贷记账号"));
 35 
 36         user.get(6).accountList.add(new Account("3630000010033431001","中国农业银行","贷记账号"));
 37 
 38         user.get(7).accountList.add(new Account("3630000010033431008","中国农业银行","贷记账号"));
 39         //创建账户
 40 
 41         user.get(0).accountList.get(0).cardList.add(new Card("6217000010041315709"));
 42         user.get(0).accountList.get(0).cardList.add(new Card("6217000010041315715"));
 43         user.get(0).accountList.get(1).cardList.add(new Card("6217000010041315718"));
 44 
 45         user.get(1).accountList.get(0).cardList.add(new Card("6217000010051320007"));
 46 
 47         user.get(2).accountList.get(0).cardList.add(new Card("6222081502001312389"));
 48         user.get(2).accountList.get(1).cardList.add(new Card("6222081502001312390"));
 49         user.get(2).accountList.get(2).cardList.add(new Card("6222081502001312399"));
 50         user.get(2).accountList.get(2).cardList.add(new Card("6222081502001312400"));
 51 
 52         user.get(3).accountList.get(0).cardList.add(new Card("6222081502051320785"));
 53         user.get(3).accountList.get(1).cardList.add(new Card("6222081502051320786"));
 54 
 55         user.get(4).accountList.get(0).cardList.add(new Card("6640000010045442002"));
 56         user.get(4).accountList.get(0).cardList.add(new Card("6640000010045442003"));
 57 
 58         user.get(5).accountList.get(0).cardList.add(new Card("6640000010045441009"));
 59 
 60         user.get(6).accountList.get(0).cardList.add(new Card("6630000010033431001"));
 61 
 62         user.get(7).accountList.get(0).cardList.add(new Card("6630000010033431008"));
 63         //创建银行卡
 64 
 65 
 66 
 67         String atmIn = input.nextLine();
 68 
 69         while(!atmIn.equals("#")){
 70             String[] inList= atmIn.split("\\s+");
 71 
 72             if(inList.length != 1) {
 73                 if (Check.check(user, atmList, inList[0], inList[1], inList[2], inList[3])) {
 74                     ATM.deal(inList[0], inList[2], Double.parseDouble(inList[3]), user,atmList);
 75                     System.out.printf("当前余额为¥%.2f\n",user.get(ATM.getUser(inList[0],user)).accountList.get(ATM.getAccount(inList[0],user)).balance);
 76                 }
 77                 else break;
 78             }
 79 
 80             else {
 81                 ATM.show(inList[0],user);
 82             }
 83 
 84             atmIn = input.nextLine();
 85         }
 86 
 87 
 88 
 89     }
 90 
 91 
 92 }
 93 
 94 class Check{
 95 
 96     public static boolean check(ArrayList<User> userList,ArrayList<ATM> atmList,String cardId,String password,String atmId,String amount){
 97         int flag = -1;
 98 
 99         if(ATM.matchCard(cardId,userList)){
100             flag = 1;
101         }
102         else {
103             System.out.println("Sorry,this card does not exist.");
104             return false;
105         }
106 
107         //检查卡号是否正确
108 
109         if(flag == 1 && ATM.matchPassword(password)) {
110             flag = 2;
111         }
112         else {
113             System.out.println("Sorry,your password is wrong.");
114             return false;
115         }
116         //检查密码是否正确
117         if(flag == 2 && ATM.matchAtm(atmId,atmList)){
118             flag = 3;
119         }
120         else {
121             System.out.println("Sorry,the ATM's id is wrong.");
122             return false;
123         }
124         //检查ATM机编号是否正确
125         if(flag == 3 && ATM.matchAmount(cardId,atmId,Double.parseDouble(amount),userList,atmList)){
126             flag =4;
127         }
128         else {
129             System.out.println("Sorry,your account balance is insufficient.");
130             return false;
131         }
132         //检查金额是否正确
133         if(flag == 4 && ATM.matchBank(atmId,cardId,userList,atmList)){
134             return true;
135         }
136 
137         return true;
138     }
139 }
140 
141 class ChinaUnionPay{
142     Bank ccb;
143     Bank icbc;
144     Bank abc;
145     ArrayList<ATM> atmList;
146     public ChinaUnionPay(ArrayList<ATM> atmList) {
147         this.atmList = atmList;
148         initBank();
149     }
150     void initBank(){
151         ccb = new Bank("中国建设银行",4,atmList,0.02);
152         icbc = new Bank("中国工商银行",2,atmList,0.03);
153         abc = new Bank("中国农业银行",5,atmList,0.04);
154     }
155 
156 }
157 
158 class Bank {
159     String bankName;
160     int atmNum;
161     double crossBankFee;
162     public Bank(String bankName,int atmNum,ArrayList<ATM> atmList,double crossBankFee) {
163         this.bankName = bankName;
164         this.atmNum = atmNum;
165         this.crossBankFee = crossBankFee;
166 
167         for(int i = 0;i<atmNum;i++){
168             if(atmList.size()<9) {
169                 atmList.add(new ATM(this.bankName, "0" + (atmList.size() + 1), this.crossBankFee));
170             }
171             else {
172                 atmList.add(new ATM(this.bankName,Integer.toString((atmList.size() + 1)), this.crossBankFee));
173             }
174         }
175     }
176 }
177 
178 
179 
180 class User  {
181     String userName;
182     ArrayList<Account> accountList =new ArrayList<>();
183     public User(String userName) {
184         this.userName = userName;
185     }
186 }
187 
188 class Account{
189     String accountNo;
190     String bankName;
191     double balance = 10000;
192     String type;
193 
194     ArrayList<Card> cardList = new ArrayList<>();
195     public Account(String accountNo,String bankName,String type) {
196         this.accountNo = accountNo;
197         this.bankName = bankName;
198         this.type = type;
199     }
200 }
201 
202 class Card {
203     String cardNo;
204     String password = "88888888";
205 
206     public Card(String cardNo) {
207         this.cardNo = cardNo;
208     }
209 }
210 
211 class ATM {
212     String bankName;
213     String ATMNo;
214     double crossBankFee;
215 
216     public ATM(String bankName, String ATMNo, double crossBankFee) {
217         this.bankName = bankName;
218         this.ATMNo = ATMNo;
219         this.crossBankFee = crossBankFee;
220     }
221 
222     public static void deal(String cardNo, String ATMNo, double amount, ArrayList<User> userList, ArrayList<ATM> atmList) {
223 
224         userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance -= getRealBankFee(cardNo, ATMNo, amount, userList, atmList);
225 
226         show(userList.get(getUser(cardNo, userList)).userName, atmList.get(getAtm(ATMNo, atmList)).bankName, ATMNo, amount);
227     }//处理存取操作
228 
229     public static boolean matchCard(String cardNo, ArrayList<User> userList) {
230         return getCard(cardNo, userList) != -1;
231     }//检查是否存在银行卡
232 
233     public static boolean matchPassword(String password) {
234         return Objects.equals(password, "88888888");
235     }//检测密码是否正确
236 
237     public static boolean matchBank(String ATMNo, String cardNo, ArrayList<User> userList, ArrayList<ATM> atmList) {
238         return Objects.equals(userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).bankName, atmList.get(getAtm(ATMNo, atmList)).bankName);
239     }//检测银行是否正确
240 
241     public static boolean matchAmount(String cardNo, String ATMNo, double amount, ArrayList<User> userList, ArrayList<ATM> atmList) {
242         if (userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).type == "借记账号") {
243             return userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance > getRealBankFee(cardNo, ATMNo, amount, userList, atmList);
244         } else {
245             return userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance - getRealBankFee(cardNo, ATMNo, amount, userList, atmList) >= -50000;
246         }
247     }//检测取出金额是否合法
248 
249     public static boolean matchAtm(String atmNo, ArrayList<ATM> atmList) {
250         return getAtm(atmNo, atmList) != -1;
251     }
252 
253     public static void show(String userName, String bankName, String ATMNo, double amount) {
254         if (amount > 0)
255             System.out.printf("业务:取款 %s在%s的%s号ATM机上取款¥%.2f\n", userName, bankName, ATMNo, amount);
256         else
257             System.out.printf("业务:存款 %s在%s的%s号ATM机上存款¥%.2f\n", userName, bankName, ATMNo, -amount);
258     }//显示存取结果
259 
260     public static void show(String cardNo, ArrayList<User> userList) {
261         System.out.printf("业务:查询余额 ¥%.2f\n", userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance);
262     }
263 
264     public static int getCard(String cardNo, ArrayList<User> userList) {
265         for (int i = 0; i < userList.size(); i++) {
266             for (int j = 0; j < userList.get(i).accountList.size(); j++) {
267                 for (int l = 0; l < userList.get(i).accountList.get(j).cardList.size(); l++) {
268                     if (Objects.equals(userList.get(i).accountList.get(j).cardList.get(l).cardNo, cardNo))
269                         return l;
270                 }
271             }
272 
273         }
274 
275         return -1;
276     }//获取银行卡对应下标
277 
278     public static int getAtm(String ATMNo, ArrayList<ATM> atmList) {
279         for (int i = 0; i < atmList.size(); i++) {
280             if (Objects.equals(atmList.get(i).ATMNo, ATMNo))
281                 return i;
282         }
283         return -1;
284     }//获取ATM对应下标
285 
286     public static int getAccount(String cardNo, ArrayList<User> userList) {
287         for (int i = 0; i < userList.size(); i++) {
288             for (int j = 0; j < userList.get(i).accountList.size(); j++) {
289                 for (int l = 0; l < userList.get(i).accountList.get(j).cardList.size(); l++) {
290                     if (Objects.equals(userList.get(i).accountList.get(j).cardList.get(l).cardNo, cardNo))
291                         return j;
292                 }
293             }
294         }
295         return -1;
296     }//获取账户对应下标
297 
298     public static int getUser(String cardNo, ArrayList<User> userList) {
299         for (int i = 0; i < userList.size(); i++) {
300             for (int j = 0; j < userList.get(i).accountList.size(); j++) {
301                 for (int l = 0; l < userList.get(i).accountList.get(j).cardList.size(); l++) {
302                     if (Objects.equals(userList.get(i).accountList.get(j).cardList.get(l).cardNo, cardNo))
303                         return i;
304                 }
305             }
306         }
307         return -1;
308     }//获取用户对应下标
309 
310     public static double getRealBankFee(String cardNo, String AtmNo, double amount, ArrayList<User> userList, ArrayList<ATM> atmList) {
311         if (matchBank(AtmNo, cardNo, userList, atmList)) {
312             if (userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).type == "借记账号") {
313                 return amount;
314             }//借记卡
315 
316             else {
317                 if (userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance > amount && userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance > 0) {
318                     return amount;
319                 } else if (userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance < amount && userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance > 0) {
320                     return amount + (amount - userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance) * 0.05;
321                 } else   {
322                     return amount * 1.05;
323                 }
324 
325             }//贷记卡
326         }//同银行操作
327         else {
328             if (userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).type == "借记账号") {
329                 return amount + atmList.get(getAtm(AtmNo, atmList)).crossBankFee * amount;
330             }//借记卡
331 
332             else {
333                 if (userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance > amount && userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance > 0) {
334                     return amount + atmList.get(getAtm(AtmNo, atmList)).crossBankFee * amount;
335                 } else if (userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance < amount && userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance > 0) {
336                     return amount + (amount - userList.get(getUser(cardNo, userList)).accountList.get(getAccount(cardNo, userList)).balance) * 0.05 + atmList.get(getAtm(AtmNo, atmList)).crossBankFee * amount;
337                 } else   {
338                     return amount * 1.05 + atmList.get(getAtm(AtmNo, atmList)).crossBankFee * amount;
339 
340                 }//贷记卡
341 
342             }//跨行操作
343         }//获取实际取款费用
344 
345     }
346 }
点此查看代码

  从这两次作业的代码和类图可以看出来呀,我这代码写的可真是纯纯的一坨,所有乱七八糟的功能都塞到了ATM类里面,这明显严重违背了单一职责原则以及迪米特法则,让ATM类过多的与程序中其他的类产生了联系与耦合,不仅仅导致了代码的设计过于糟糕,也导致了在编程过程中由于思路混乱导致找不着北,平添了一大堆奇奇怪怪的静态方法(其实在ATM中这一大堆方法中有很大一部分是为了获取对应卡号在CardList中的下标),这些方法明显有更好的实现方式或设计模式,并不需要增加如此之多的静态方法。实际在设计该类的时候也是如此,为了将deal方法放在ATM类中,需要传入存储在另外一个类中的列表,正因为如此,为了操作到对应的数据,平白无故的在完成单一职责的类中增加了一大堆获取下标的方法,导致面多加水,水多加面,使本就不怎么简洁的ATM类雪上加霜。


3、采坑心得

  在第8次的作业及第9次作业中,我算是明白了提前进行结构设计的重要性,但凡我在开始动手之前对整个程序的结构进行过规划,都不会在如何在ATM类中进行其他类中进行数据查询这里耗费如此长的时间(说白了我还是个菜逼),在提交作业之后,无论哪次再点开自己曾今写出的代码,我都会想这样一个问题:“是什么让我写出这样的一坨SHIT,怎么会有如此弱智的结构设计。”其实事后想想,只要对数据结构的设计稍加修改就可以避免这样的情况,比如在用户-账号-银行卡号结构对应的各个类中加入对应的下标(实际ATM系统并不可能会有这样的设计,但在不考虑数据库的情况下确实会是更好的选择),在程序设计方面我果然还是差点火候呀。


 

4、总结

  时间过得真快,一下子一个学期就这样过去了,回想第一次Blog作业,那不仅仅是我第一次写OOP相关的内容,同样也是我第一次编写Blog。现在再回去翻看自己曾经编写的代码,不得不感叹在这门课堂上学习到了许多的东西,不仅仅是单纯的Java这门编程语言和面向对象的编程技术,同样也学会了用另一种编程思想去思考对应的需求,同样也学会了通过这种方式去完成实际的应用。在一次次的PTA作业中通过坚持不懈的努力去攻克一个个测试点(这好像不太符合面向对象思想吧),看着一个个绿字变红所带来的成就感是真的使人感到心情愉悦。希望自己能够在将来能够将这门课程中所学到的知识运用到实际的工作中,使自己更加具有想象力,以此克服一个个困难。

posted @ 2021-12-18 21:19  A_Piii  阅读(43)  评论(0编辑  收藏  举报