PTA题集7~9总结

前言:学习OOP课程的第三阶段已经结束了,本阶段一共有四个习题,这四个习题是在两个相同的环境分别给予不同的要求。锻炼了我们在面对不同的要求时能对代码做出相应的修改的能力,以下是我对本阶段学习总结以及题目分析。

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

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

(3)题目集9题只有一题,该题是题目集8的升级版,如果题集8是按“开-闭原则”写的话,这道题会更容易书写。题目形式也为ATM机类机构设计。本次添加了贷记以及透支取款的功能。本次作业进行了抽象类,多态,继承的运用。虽是之前就运用过的方式,本次需要我们主动去想到在什么方面进行使用。高质量符合题目要求的源码完成,需要对以上知识点有充分的认识与吸收。此题目本身功能性不复杂,需要我们去做到类的关系调用以及设计类功能是难度所在。

各题目 设计与分析 采坑心得 改进建议 :

(1)题目集7:(7-1)图形卡片排序游戏 (7-2)图形卡片分组游戏

设计与分析

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

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

就7-1而言,本次为图形卡片排序游戏,通过设计出一个抽象Shape类,进而对Shape进行拓展出三角形,圆形,矩形,梯形类,其中在主类进行对象合法性的检验以及对应图形数量的添加。在不同的主体类中有着大致相同的方法:求面积,合法性校验,Set,Get方法,在DealCardList业务类中进行对对应具体图形类属性的添加,进而将实体类与业务类联系起来。实体类都继承于Shape类中。而在代码中设计了求面积的接口类,实现了求面积的多态。功能体现在对输入的图形进行求面积处理,其次进行了排序,最后求出面积总和。对于多对象情况,采用存在ArrayList中进行流水线式的处理,使代码更为简洁,不需要一个个判断后再进行添加。设计遵守了单一职责原则以及“开-闭”原则,便于7-2题目的拓展功能添加。

就7-2而言,本次为图形卡片分组游戏,该次作业是对7-1题目的迭代,添加的功能有:对初始求出的面积数据进行分组;对分组后的数据在组内进行排序;得到全部图形中的最大面积。实体类设计与7-1无差别,主要使DealCardList业务类中,需要进行更为细致的分组处理。首先在DealCardList类中添加了几种Boolean型方法,判断语句采用了匹配字符串的equals语句,进行初步的分类校验。通过创建四种方法,将不同的四种图形的输出方式表示为一种长字符串进行输出,每确定一种图形的种类,以及算出对应面积之后,则将新确定的字符串拼接在之前的字符串后一位,以card顺序i作为循环上限,将每次i对应的图形一个个进行校验,以确定在对应输出位置上。排序方法上选择了插入排序,并且代码的循环语句采用的增强for循环。在求最大面积上,将card的i作为循环依据,通过比较得出最后的最大面积的值,本次作业难度不算大,但需要细致的类间关系调用,才会使代码更简洁可观。而对于ArrayList的使用同样也十分重要,对象的处理因此更为高效。

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

public static void main(String[] args) {
	Scanner in = new Scanner(System.in);	
	DealCardList a = new DealCardList();

	String line1 = in.nextLine();
	a.validate1(line1);		
	String line2 = in.nextLine();
	a.inputdate(line2);		
	a.validate2();
	a.show1();
	a.sort();
	a.show2();
	

}

}

class DealCardList{
//数据域
private ArrayList arrayList = new ArrayList<>();
private int[] shapes ;
//格式化数据
DecimalFormat df = new DecimalFormat("0.00");
//构造方法
public DealCardList() {

}
public DealCardList(String a) {
	super();
						
	
}

//检查第一行数据并存入数组
public void validate1(String line) {

	//判断只有0
	if(line.equals("0")) {
		System.out.println("The original list:");
		System.out.println("\nThe sorted list:");
		System.out.println("\nSum of area:0.00");
		System.exit(0);
	}

	String[] line1 = line.split(" ");
	//依据输入数据初始化数组
	shapes = new int[line1.length];//注意,这里把 0 也存入了

	for(int i = 0; i<line1.length-1; i++) {		
		int num = Integer.parseInt(line1[i]);
		if(num<=0 || num>4) {
			System.out.print("Wrong Format");
			System.exit(0);
		}
		shapes[i] = num;
	}
	
	
}
//把数据存入ArrayList数组
public void inputdate(String line) {
	
	String[] line1 = line.split(" ");
	double[] date = new double[line1.length];
	for(int i=0; i<line1.length; i++) {
		date[i] = Double.parseDouble(line1[i]);
	}
	int flag = 0;
	
	for(int i=0; i<shapes.length; i++) {
			
		switch(shapes[i]) {
		// 1--圆,2--矩形,3--三角形,4--梯形
		 case 1: double radius = date[flag];			 		 
		 		 Shape circle = new Circle(radius);
			 	 arrayList.add(circle);
			 	 flag = flag + 1;
			 break;
		 case 2: double width = date[flag];
			     double length = date[flag+1];
			     Shape Rectangle = new Rectangle(width,length);
			     arrayList.add(Rectangle);
			     flag = flag + 2;
			 break;
		 case 3:double side1 = date[flag];
				double side2 = date[flag+1];
				double side3 = date[flag+2];
				Shape Triangle = new Triangle(side1,side2,side3);
				arrayList.add(Triangle);
			    flag = flag + 3;
			break;
		 case 4:double aboveSide = date[flag];
			 	double bottomSide = date[flag+1];
			 	double heightSide = date[flag+2];
			 	Shape Trapezoid = new Trapezoid(aboveSide,bottomSide,heightSide);
			 	arrayList.add(Trapezoid);
			    flag = flag + 3;
			 break;
		}
			
	}
}
//检验各项数据是否合法
public void validate2() {
	for(int i = 0; i<arrayList.size(); i++) {
		if(!arrayList.get(i).validate()){
			System.out.println("Wrong Format");
			System.exit(0);
		}				
	}
}
//(冒泡)排序
public void sort() {
	int listSize = arrayList.size();
	for(int i = 0; i<listSize; i++) {
		for(int j = 0;j<listSize-1-i; j++) {
			Shape shape1 = arrayList.get(j);
		    Shape shape2 = arrayList.get(j+1);
			if(arrayList.get(j).compareTo(arrayList.get(j+1))<0) {
				arrayList.set(j, shape2);
				arrayList.set(j+1, shape1);
			}				
		}
	}
}
//计算总面积
public String sumArea() {
	double sum = 0;
	for(int i = 0; i<arrayList.size(); i++) {
		sum = sum + arrayList.get(i).getArea();
	}
	
	return df.format(sum);
}
//show
public void show1() {
	System.out.println("The original list:");
	for(int i = 0; i<arrayList.size(); i++) {
		System.out.print(arrayList.get(i).toString()+" ");
	}
}
public void show2() {
	System.out.println("\nThe sorted list:");
	for(int i = 0; i<arrayList.size(); i++) {
		System.out.print(arrayList.get(i).toString()+" ");
	}
	System.out.println("\nSum of area:"+sumArea());
}

}
7-2核心代码如下public class Main {

public static void main(String[] args) {
	Scanner in = new Scanner(System.in);
	DealCardList a = new DealCardList();

	String line1 = in.nextLine();
	a.validate1(line1);
	String line2 = in.nextLine();
	a.inputdate(line2);
	a.validate2();
	System.out.println("The original list:");
	a.show1();
	System.out.println("\nThe Separated List:");
	a.show2();
	a.sort();
	System.out.println("\nThe Separated sorted List:");
	a.show3();
	System.out.println("\nThe max area:" + a.maxArea());
}

}

class DealCardList {
// 数据域
private Shape[] figures;
private int[] shapes;
private double[] areaArray = new double[4];

// 格式化数据
DecimalFormat df = new DecimalFormat("0.00");

// 构造方法
public DealCardList() {

}

public DealCardList(String a) {
	super();

}
// 检查第一行数据并去0存入shape数组
public void validate1(String line) {
	// 判断只有0的情况
	if (line.equals("0")) {
		System.out.println("Wrong Format");
		System.exit(0);
	}
	
	String[] line1 = line.split(" ");
	
	// 依据输入数据的长度初始化数组,减一的目的是不读取0
	shapes = new int[line1.length-1];
	for (int i = 0; i < shapes.length; i++) {
		int num = Integer.parseInt(line1[i]);
		if (num <= 0 || num > 4) {
			System.out.println("Wrong Format");
			System.exit(0);
		}
		shapes[i] = num;
	}
}
//把数据存入ArrayList数组
public void inputdate(String line2) {
	//处理第二行数据
	String[] line = line2.split(" ");
	double[] data = new double[line.length];
	for (int i = 0; i < line.length; i++) {
		data[i] = Double.parseDouble(line[i]);
	}
	//初始化Shape对象数组
	figures = new Shape[shapes.length];
	int flag = 0;
	for(int i=0; i<shapes.length; i++) {				
		switch(shapes[i]) {
		// 1--圆,2--矩形,3--三角形,4--梯形
		 case 1: double radius = data[flag];			 		 
		 		 Shape circle = new Circle(radius);
		 		 areaArray[0] += circle.getArea();
		 		 figures[i] = circle;
			 	 flag = flag + 1;
			 	 
			 break;
		 case 2: double width = data[flag];
			     double length = data[flag+1];
			     Shape rectangle = new Rectangle(width,length);
			     areaArray[1] += rectangle.getArea();
			     figures[i] = rectangle;
			     flag = flag + 2;
			 break;
		 case 3:double side1 = data[flag];
				double side2 = data[flag+1];
				double side3 = data[flag+2];
				Shape triangle = new Triangle(side1,side2,side3);
				areaArray[2] += triangle.getArea();
				figures[i] = triangle;
			    flag = flag + 3;
			break;
		 case 4:double aboveSide = data[flag];
			 	double bottomSide = data[flag+1];
			 	double heightSide = data[flag+2];
			 	Shape trapezoid = new Trapezoid(aboveSide,bottomSide,heightSide);
			 	areaArray[3] += trapezoid.getArea();
			 	figures[i] = trapezoid;
			    flag = flag + 3;
			 break;
		}
	}		
}
// 检验各项数据是否合法
public void validate2(){
	for (int i = 0; i < figures.length; i++) {
		if (!figures[i].validate()) {
			System.out.println("Wrong Format");
			System.exit(0);
		}
	}
}

//排序
public void sort(){
	java.util.Arrays.sort(figures);
}

// 找出4组中最大面积总和
public String maxArea() {
	double max = 0;
	for (int i = 0; i < areaArray.length; i++) {
		if(areaArray[i]> max)
			max= areaArray[i];
	}
	return df.format(max);
}
// show输出
public void show1() {
	System.out.print("[");
	for(int i = 0; i<figures.length; i++) {
		System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");
}
public void show2() {
	System.out.print("[");
	for (int i = 0; i< figures.length; i++) {
		if(figures[i] instanceof Circle)
			System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");
	//矩形
	System.out.print("[");
	for (int i = 0; i< figures.length; i++) {
		if(figures[i] instanceof Rectangle)
			System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");
	//三角形
	System.out.print("[");
	for (int i = 0; i< figures.length; i++) {
		if(figures[i] instanceof Triangle)
			System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");
	//梯形
	System.out.print("[");
	for (int i = 0; i< figures.length; i++) {
		if(figures[i] instanceof Trapezoid)
			System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");
	
}
//
public void show3() {
	System.out.print("[");
	for (int i = figures.length-1; i>=0; i--) {
		if(figures[i] instanceof Circle)
			System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");
	//矩形
	System.out.print("[");
	for (int i = figures.length-1; i>=0; i--) {
		if(figures[i] instanceof Rectangle)
			System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");
	//三角形
	System.out.print("[");
	for (int i = figures.length-1; i>=0; i--) {
		if(figures[i] instanceof Triangle)
			System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");
	//梯形
	System.out.print("[");
	for (int i = figures.length-1; i>=0; i--) {
		if(figures[i] instanceof Trapezoid)
			System.out.print(figures[i].toString() + " ");
	}
	System.out.print("]");		
}

}
`

改进建议

1.改进点更多在类中方法的设计以及功能算法设计上。在7-1中,对于排序上采用的依旧是插入排序法,而也尝试过去使用sort排序,这样的代码更加的简洁有效。后发现使用后会无法得到结果,再完成了7-2后发现,我排序的对象的card里的i,而不是i对应的对象。所以若能将全部的排序规则改进为sort排序,则可以将代码更为简洁。

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

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

4.对于面积和最大值的寻找,不需要再进行多次的for循环与if判断,再建议3的基础上,最后进行一次sort排序便能得到最大值,直接进行结果的输出。

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

设计与分析

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


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

就题目集8的7-1而言,该题目用于设计一个简单的ATM机功能,功能作用在:简单的存取款与查询余额。设计的背景为:中国银联,中国银行,银行用户,银行账户,银行卡,ATM机。该背景的各个组成部分,都可以实现为一个实体类。各个实体类之间有一定的关联性,其中例如:各个中国银行组成了中国银联,而中国银行里有着不同的银行用户,银行用户拥有自己独立的银行账户,而银行账户通过银行卡进行操作,ATM机作为银行服务于用户的机器,联系着银行与账户等。需要设计出联系紧密且又实效的类间关系。实体类需要自己去考虑到类间的关系,而业务类则需要根据用户的需求设计不同的功能。例如实现不同输入情况下做到的存取款,以及查询余额的功能。我的代码在Verifcation类中作为业务类,在该类中完成不同的功能。在该类中首先构建了属于自己的数据储存库,保证调用对应账户或者银行卡号不会错乱,以及余额的每次更新都会得到改变。在主类中利用正则表达式对输入的情况进行不同的分支走向,比如通过空格分隔元素得到是存取款还是查询余额。后又会在Verifcation类进行不同的数据的校验:卡号,ATM编号,密码,金额合法,是否跨行。通过合法校验的数据则进行数据处理,通过依次对应的if语句,对输入结果进行完善,存取金额则是简单的加减法,只需要完成了输入内容的其他部分,直接调用存取金额的方法直接填入数据即可。最终输出是通过将一步一步的中间输出作为字符串存储在一个字符串数组之中,在主类的最后同一个for循环全部进行输出。以上是ATM机设计(一)的设计思路。

就题目集9的7-1而言,本次的代码是在老师给的代码的基础上进行功能的添加与优化。考察的依旧是:继承,多态,抽象类,类间关系设计以及对于“开-闭”原则,单一职责原则的掌握。跟题目集8的7-1有所不同的是添加一种信用卡,可以进行贷记操作,以及银联有了超额度的服务费扣取功能,跨行收费。该功能的添加与对本身代码的优化修改是难点。难在不知在哪进行修改,不知如何添加在恰当位置,且易将本来具有简单功能的代码解构,难以保证质量。以下进行代码结果i有分析:首先用户数据的导入通过在主类里分别进行对用户信息,账户信息,银行卡,借记卡信息,以及ATM,银行,银联信息的添加,也就是利用add方法进行对象添加。以及进行双向绑定,将对象与对象之间的联系更为紧密,也方便进行调用。在该代码中,我设计了账户父类与卡父类,以下有借记账户子类,信用账户子类以及借记卡与信用卡的子类。通过构造统一的卡类,其中包含着两种子卡类,账户类同理。主类中依旧是根据正则表达式以及if语句决定功能走向的分支。对于新添加的透支与跨行的功能,分别将跨行利率作为对应银行的属性,将透支服务费收取金额的利率作为银联的属性。当判断需要收取对应费用时,可以直接调用对应的属性即可。例如在某ATM机上跨行取钱,则通ATM机号找到对应的银行,调用该银行的利率属性进行收费的计算。其中在功能计算中,通过instanceof方法对不同类别的账户进行不同的超出额度输出判断。本题需要额外考虑的有:跨行判断后跨行情况的收费处理,以及透支收费,剩余金额的实时更新以及更新后判断是否超出额度。这些都是在通过不同类负责不同的判断依据与功能操作得到的最后结果。最后的输出通过while循环实现。以上是ATM机设计(二)的设计思路。

采坑心得
7-1
本题我还有一个测试点没有过,一开始一直找不到错在哪,后来找同学帮忙,最终恍然大悟,才明白是自己没仔细理解题目要求

这个要求被我也不知是被我忽视还是误解了,我的代码是把这些数据都一次性读取完,存放在一个二维数组里,然后用循环验证,但是按题目要求来讲,这样子是错误的思路,正确的思路应该是在读取一句的同时进行判断,这样子才好终止并且把之前正确分语句的结果输出。还有一个就是一开始我还误解了那个账户余额,我以为是一每张卡为单位,每张卡里都有初始余额1000,所以当书写完代码检验结果时,发现只有余额是不对的,才明白应该以每个账户为突破口,账户才是连接所有信息的一个好切入口,修改这个错误可谓是对我的代码进行大整修。经过这次的教训,我在以后的作业里一定会逐字逐句地理解要求,按要求去思考正确思路后再书写代码。
7-2
这道题写的挺顺畅的,写完代码,没怎么debug就过了测试点,所以没啥踩坑心得可以分享。
7-2的部分代码如下
`//存取款 业务类
class Withdraw {

private UnionPay unionPay;
private String cardNO;
private String cardPassword;
private String ATMID;
private double amount;

public Withdraw() {
	super();

}


public Withdraw(UnionPay unionPay, String cardNO, String cardPassword, String aTMID, double amount) {
	super();
	this.unionPay = unionPay;
	this.cardNO = cardNO;
	this.cardPassword = cardPassword;
	ATMID = aTMID;
	this.amount = amount;
}

public void withdraw() {
	/**
	 * 校验该卡是否存在
	 */		
	if(!ValidateData.cardCheck(unionPay, cardNO)) {
		System.out.println("Sorry,this card does not exist.");
		System.exit(0);
	}
	/**
	 * 校验ATM是否存在
	 */

	if(!ValidateData.checkATMbyATMID(unionPay, ATMID)) {
		System.out.println("Sorry,the ATM's id is wrong.");
		System.exit(0);
	}
	/**
	 * 校验卡密码是否正确
	 */
	if(!ValidateData.checkpassword(unionPay, cardNO, cardPassword)) {
		System.out.println("Sorry,your password is wrong.");
		System.exit(0);
	}
	
	//获取卡对应的账户
	Account account = Get.gatAccountbyCardNO(unionPay, cardNO);
	boolean overbalance = ValidateData.checkbalance(unionPay, cardNO, amount);
	boolean overbank = ValidateData.checkBank(unionPay, cardNO, ATMID);
	boolean jieji = Get.gatAccountbyCardNO(unionPay, cardNO).getAccountType().equals("jieji");
		
	//跨银行 且 超额取款
	if(overbank && overbalance) {
		double charge ;
		if(account.getBalance() < 0) 
			charge = Get.getBankbyATMID(unionPay, ATMID).getRate()*amount + amount*0.05;
		else 
			charge = Get.getBankbyATMID(unionPay, ATMID).getRate()*amount + (amount - account.getBalance())*0.05;
		account.setBalance(account.getBalance() - amount - charge);
	}
	//超额取款
	else if(!overbank && overbalance) {
		double charge ;
		if(account.getBalance() < 0) 
			charge = amount*0.05;
		else 
			charge = (amount - account.getBalance())*0.05;
		account.setBalance(account.getBalance() - amount - charge);
	}
	//跨银行取款
	else if(overbank && !overbalance) {
		double charge = Get.getBankbyATMID(unionPay, ATMID).getRate()*amount;
		account.setBalance(account.getBalance() - amount - charge);
	}
	//普通取款
	else
		account.setBalance(account.getBalance() - amount);
	
	//透支借贷 或 借记卡超额取款
	if(account.getBalance() < -50000 || (jieji&&(account.getBalance()<0))) {
		System.out.println("Sorry,your account balance is insufficient.");
		System.exit(0);
	}
	
	if(amount >= 0) {
		showResult(account,ATMID,1);
	}else {
		showResult(account,ATMID,0);
	}

}
//show
public void showResult(Account account, String ATMID,int flag) {
	String type = "";
	if(flag == 1) {
		type = "取款";			
	}else {
		type = "存款";
		amount *= -1;
	}
	String userName = account.getUser().getName();
	String bankName = Get.getBankbyATMID(unionPay, ATMID).getBankName();
	System.out.println("业务:"+ type +" " +userName + "在" +
			bankName + "的" + ATMID + "号ATM机上" + type + String.format("¥%.2f", amount));
	System.out.println("当前余额为" + String.format("¥%.2f", account.getBalance()));
}

}

class GetBalance {
private UnionPay unionPay;

public GetBalance() {
	super();

}

public GetBalance(UnionPay unionPay) {
	super();
	this.unionPay = unionPay;
}

public double getBalance(String cardNO) {

	return Get.gatAccountbyCardNO(unionPay, cardNO).getBalance();

}

}

class ValidateData {

// 检验卡号是否存在
public static boolean cardCheck(UnionPay unionPay, String cardNO) {
	Card card = null;
	ArrayList<Card> cardList = unionPay.getCardList();
	Iterator<Card> cardItr = cardList.iterator();
	while (cardItr.hasNext()) {
		card = cardItr.next();
		if (card.getCardNO().equals(cardNO)) {
			return true;
		}
	}
	return false;
}

// 检验ATM机是否存在
public static boolean checkATMbyATMID(UnionPay unionPay, String ATMID) {
	ATM aTM = null;
	Iterator<ATM> aTMItr = unionPay.getATMList().iterator();

	while (aTMItr.hasNext()) {
		aTM = aTMItr.next();
		if (aTM.getATMID().equals(ATMID)) {
			return true;
		}
	}
	return false;
}

// 检验是否跨银行存取
public static boolean checkBank(UnionPay unionPay, String cardNO, String ATMID) {

	String bankname1 = Get.gatAccountbyCardNO(unionPay, cardNO).getBank().getBankName();
	String bankname2 = Get.getBankbyATMID(unionPay, ATMID).getBankName();
	if (bankname1.equals(bankname2))
		return false;
	else
		return true;

}

// 检验是否超额取款
public static boolean checkbalance(UnionPay unionPay, String cardNO, double amount) {

	//获取卡对应的账户
	Account account = Get.gatAccountbyCardNO(unionPay, cardNO);
	if(account.getBalance() < amount)
		return true;
	else
		return false;
}

// 检验密码是否输入正确
public static boolean checkpassword(UnionPay unionPay, String cardNO, String password) {
	Iterator<Card> cardItr = unionPay.getCardList().iterator();

	while (cardItr.hasNext()) {		
		if(cardItr.next().getCardNO().equals(cardNO) && cardItr.next().getCardPassword().equals(password))
			return true;
	}
	return false;
}

}

class Get{

//通过卡号获取卡
public static Card getCardbyCardNO(UnionPay unionPay,String cardNO) {
	Card card = null;
	Iterator<Bank> bankItr = unionPay.getBankList().iterator();

	while(bankItr.hasNext()) {
		ArrayList<Account> accountList = bankItr.next().getAccountList();
		Iterator<Account> accountItr = accountList.iterator();
		while(accountItr.hasNext()) {
			ArrayList<Card> cardList = accountItr.next().getList();
			Iterator<Card> cardItr = cardList.iterator();
			while(cardItr.hasNext()) {
				card = cardItr.next();
				if(card.getCardNO().equals(cardNO)) {
					return card;
				}
			}
		}
	}
	return null;
}
//通过卡号获取账户
public static Account gatAccountbyCardNO(UnionPay unionPay,String cardNO) {
	Card card = null;
	Iterator<Bank> bankItr = unionPay.getBankList().iterator();

	while(bankItr.hasNext()) {
		ArrayList<Account> accountList = bankItr.next().getAccountList();
		Iterator<Account> accountItr = accountList.iterator();
		while(accountItr.hasNext()) {
			ArrayList<Card> cardList = accountItr.next().getList();
			Iterator<Card> cardItr = cardList.iterator();
			while(cardItr.hasNext()) {
				card = cardItr.next();
				if(card.getCardNO().equals(cardNO)) {
					return card.getAccount();
				}
			}
		}
	}
	return null;
}

//通过ATM机编号获取银行
public static Bank getBankbyATMID(UnionPay unionPay,String ATMID) {
	Iterator<Bank> bankItr = unionPay.getBankList().iterator();
	Bank bank = null;
	ATM aTM = null;

	while(bankItr.hasNext()) {
		bank = bankItr.next();
		Iterator<ATM> aTMItr = bank.getATMList().iterator();	

		while(aTMItr.hasNext()) {
			aTM = aTMItr.next();
			if(aTM.getATMID().equals(ATMID)) {
				return aTM.getBank();
			}
		}			
	}		
	return null;	
}

}
`
对于类的设计来看,设计中有卡父类以及账户父类,以及往下分支:信用卡类,借记卡类,信用账户类,借记账户类;这样的设计符合继承,且处理起来符合多态,无需在主类刻意区分两种卡类,在数据处理中会在各自类中调用特有的方法进行功能的实现。起初未这样设计,代码亢长且难以对多数据进行处理,不符合继承与多态,更改了类的设计后,更具逻辑性与拓展性。

改进建议

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

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

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

ATM机仿真题目的设计思路分析总结

题目集8的7-1用于设计一个简单的ATM机功能,功能作用在:简单的存取款与查询余额。设计的背景为:中国银联,中国银行,银行用户,银行账户,银行卡,ATM机。该背景的各个组成部分,都可以实现为一个实体类。各个实体类之间有一定的关联性。题目集9的7-1而言,本次的代码是在老师给的代码的基础上进行功能的添加与优化。考察的依旧是:继承,多态,抽象类,类间关系设计以及对于“开-闭”原则,单一职责原则的掌握。跟题目集8的7-1有所不同的是添加一种信用卡,可以进行贷记操作,以及银联有了超额度的服务费扣取功能,跨行收费。主类中都是根据正则表达式以及if语句决定功能走向的分支。不同点在于会在题目集9的代码中不同的银行添加不同的利率属性,在业务类中添加对跨行后的收费处理以及透支判断等。以上都是对特定功能的添加,需要考虑到类设计的“开-闭”原则,单一职责原则。以及迭代到的不仅是相同背景内容的功能添加,更有考虑到类间关系,去充分利用实体类的属性绑定以及方法调用。业务类中集成方法去实现最终输出的效果。本次ATM机迭代编程,本身逻辑层面简单,注重的是严谨的设计思想与正确的面向对象编程思维。

总结

本次阶段的三次作业,更多的是对所学类设计的应用,主要是对两种原则的掌握:“开-闭”原则,单一职责原则。以及对于“封装性,继承,多态,复用等”需要有自己的理解去很好的利用。对于设计的想法,面向对象设计的初衷在于将处理的事情对象化,对象要求什么功能,我们便需要去满足它。在这一阶段的学习中,对于作业难度并不是以往的设计好的算法去实现,前几次阶段的题目更像是套着面向对象的壳去用电脑完成数学题。这一阶段本身题目逻辑并不复杂,考察的是我们对于一个事物去实现,我们该如何去做的一个好的设计,设计围绕着可维护,可拓展,以及后续根据源码去添加功能,都在让我们学习并实际去运用着面向对象编程的设计思想。对于后续需要学习的界面设计,需要掌握JavaFx,为此也在进行相关的学习,不断学习,也在不断回顾学到的内容。并且会进行深度的挖掘,更好的去理解面向对象设计的内涵。

再次感谢这一阶段的学习,即将进入尾声的面向对象设计的课程,学到了以面向对象的思想去进行程序设计,也是作为软件工程专业的入门基础。感谢老师与助教的工作,也要感谢坚持到现在的自己!自信的向下一阶段出发!

posted @ 2021-06-17 09:16  WeirdTong  阅读(169)  评论(0)    收藏  举报