题目集7~9的总结性Blog
前言:
这个月的java学习,依旧是让我们学会了很多东西,这次的作业很有意思.
第七周的第一个题是让我们学会使用java自带的排序接口,仅仅只需要完善排序接口的一个方法既可以排序你想要排序的类,可谓十分的方便,这次的作业依照老师的类图进行编写可以达到较易的难度,而第二道题则是充分体现了类与类的"不和陌生人说话"理念的优势,根据老师的类图去实现可以得到很高独立性的代码,在第一题与第二题的迭代中,其实相对功能没有改变,只是输出的语句变化了,在原代码基础下,便使得该题很简单的实现了.第八周的话,相对于第七周以及之前的全部作业,可谓变化较大.
第八周次的作业没有用类图来说明,这种完全需要靠我们自己来实现,来设计的方式可谓让我一时无法习惯,这也是很好的锻炼我们的面向对象的思维.
第九周则是在第八周的代码上进行迭代,或许是老师为了让我们更加了解"不和陌生人说话"的好处,仅仅需要更改中介类即可实现较大改动,对其他类仅需要修改部分方法,实现整体框架时大部分框架也已经构建好,对于迭代更新有很好的维护效率.
这几周的练习难度相对于之前的作业,可谓难度中等偏上,主要是要我们自己完成设计,要靠自己对面向对象的了解完成,脱离了原来那种按类图来完成老师设计好的框架,体现了需求方和设计方的关系,较为真实和贴切现实,是很好的锻炼方式.
(2)设计与分析:
①题目集7(7-1)、(7-2)两道题目的递进式设计分析总结
7-1:
是对 Comparable 接口的了解和使用,这是一个专用于排序的类,仅仅只需要实现其内置方法 CompareTo() ,既可以实现排序自己想要排序的类,实现非数字之间的排序.
完成 CompareTo() 该方法的代码部分:
public int compareTo(Card card) {
// TODO 自动生成的方法存根// TODO 自动生成的方法存根
if(card.getShape().getArea() > this.shape.getArea())
return 1;
else if(card.getShape().getArea() == this.shape.getArea())
return 0;
else
return -1;
}
这个接口一定要实现的方法即如上,需要用自己指定的规则实现排序规则,分别实现 返回值 1 交换位置, 0 保持位置, -1 结束排序. 主要的实现如上.实现该方法后,可以调用接口中的方法,sort方法, 调用方法为 Collections.sort(Object a);
其中Object类为自己在接口 Comparable 接入时指定的类, 在这道题中 需要完成排序方法的为 Card 类 ,即接入接口 Comparable 时,应当写为:
class Card implements Comparable<Card>
更改泛型为Card类,在实现接口方法 CompareTo() 即完成该接口的基础实现.
对于7-1的整体框架如下,使用聚合来实现.有较好的可拓展性以及维护性.

7-2:
7-2的整体同7-1的框架并没有发生太大改变.
类图如下
分析:与上7-1的类图进行比较可以发现,类与类之间的关系没有发生改变,但类之间的方法发生了改变或者增加了新的方法, 这也是充分的发挥了聚合,"不和陌生人说话"原则和单一职责原则的优势性,在上7-1 的分析已经指出,7-1的代码具有较强的维护性和扩展性,维护性在于仅仅需要更改局部既可以实现新的模式或展现,扩展性即在于可以在原类之间创建新的方法实现新的功能,各个类之间相对独立,是具有一定面向对象思维的构成方法.
深层次解析: 在7-1 ------> 7-2迭代的过程中,由于7-1框架(面向对象框架)的优越性,仅仅在该基础上更改一部分代码或添加一部分代码既可以实现7-2的内容.7-1与7-2的要求很像,似乎只需要更改一下输出方式以及添加一部分分组的功能既可以实现,为什么说 7-1 的整体框架具有很高的优越性呢,因为主体的对象类都是可以单独孤立出来的类,例如圆,三角形,矩形,梯形等都是具象的个体单位,而7-1中有一个 DealCardList 类 则是无法单独拿出来单独立为一个个体的类,因为该类与其他类的关联十分紧密,导致其无法被孤立出来,但在实现功能的过程中却无法缺少这样的类用于联系各个类,所以使用这样的类是该框架体系必不可少的一种个体.
这种中介的框架各个类之间的联系很少,如果单个类出了毛病也可以仅仅造成局部的错误,仅需要修改该类的部分内容既可以完善,如果是该"中介"出现了毛病也不会影响其他类导致整体框架的崩塌,对于拓展性这一种框架也是十分的优秀的,这种框架可以让各个类的功能独立("不和陌生人说话"原则),同样的,如果需要添加单个类的功能即仅需要在该类中添加需要的功能即可,如果是多个类之间的配合关系即可以在"中介"中添加需要的方法来实现,隔绝了与无关类的联系,可以减少错误带来的连锁反应和蝴蝶效应.
相对于7-1做出的改变:
前面已经阐述过,对于7-1至7-2的改变,仅仅是添加了方法和修改了方法,大致的修改如下


可以看出,为了实现可以完成7-2的输出模式,添加了多个List的属性来存放,便于用来实现输出.而且添加了较多新的方法,分别为toString(ArrayList list)是用于对分组的消息进行输出, getALLArea(ArrayList list)则是负责输出每个类(分组的区块)总的面积,而getALLArea(),则是输出所有面积的总和,getMax()便是用于返回最大面积的方法,这些板块也是相对于其他方法是独立的,同样是符合面向对象的思维方式的.整体发生改变的大概就是新写的函数和原函数发生的改变.
//7-1负责输出的代码的代码
public void showResult() { // TODO 自动生成的方法存根 System.out.println("The original list:"); for(Card i : cardList) System.out.printf(i.shape.toString() + " "); System.out.println(); this.cardSort(); System.out.println("The sorted list:"); for(Card i : cardList) System.out.printf(i.shape.toString() + " "); System.out.printf("\nSum of area:%.2f",this.getAllArea()); }
//7-2负责输出的代码
public void showResult() { // TODO 自动生成的方法存根 System.out.println("The original list:"); this.toString(cardList); System.out.println(); System.out.println("The Separated List:"); this.toString(this.circleList); this.toString(this.rectangleist); this.toString(this.triangleList); this.toString(this.trapezoidList); System.out.println(); this.cardSort(circleList); this.cardSort(rectangleist); this.cardSort(triangleList); this.cardSort(trapezoidList); System.out.println("The Separated sorted List:"); this.toString(this.circleList); this.toString(this.rectangleist); this.toString(this.triangleList); this.toString(this.trapezoidList); System.out.println(); double num1,num2,num3,num4,max =0; num1 = this.getAllArea(this.circleList); num2 = this.getAllArea(this.rectangleist); num3 = this.getAllArea(this.trapezoidList); num4 = this.getAllArea(this.triangleList); max = (max >num1)?max:num1; max = (max >num2)?max:num2; max = (max >num3)?max:num3; max = (max >num4)?max:num4; System.out.printf("The max area:%.2f",max); }
//输出分组的函数,在上面的函数中被使用
public void toString(ArrayList<Card> list) {
System.out.printf("[");
for(Card i : list) {
System.out.printf( i.shape.toString());
}
System.out.printf("]");
}
题目集7迭代情况的主要的的变化皆在以上.
②题目集8和题目集9两道ATM机仿真题目的设计思路分析总结
ATM机第一次编写:
第一次的ATM机类是对自己构造类框架的能力的锻炼以及对面向对象框架的了解,还有双向链表的使用,这也是对我们能力的考验,这也是第一次使用双向链表,当然也使用了迭代器,第一次实战使用到的知识点,,用于迭代数据,有较快的迭代速度.
整体性能分析:
类图如下:

由类图可知:这次的代码依旧使用的是中介的方法来聚合多个独立的个体,这种方式就不多赘述了.总体的代码依旧是中介类最为精彩,接下来会展示关于中介类的代码,并且会指出其中的错误.
public class Agent {
/**
* 管理类
*/
StringBuilder str;
public Agent(StringBuilder str) {
super();
this.str = str;
}
final ChinaUnionPay chinaUnionPay = new ChinaUnionPay();
final ATM atm[] = {
new ATM("01", chinaUnionPay.CCB, chinaUnionPay),
new ATM("02", chinaUnionPay.CCB, chinaUnionPay),
new ATM("03", chinaUnionPay.CCB, chinaUnionPay),
new ATM("04", chinaUnionPay.CCB, chinaUnionPay),
new ATM("05", chinaUnionPay.ICBC, chinaUnionPay),
new ATM("06", chinaUnionPay.ICBC, chinaUnionPay)
};
final User user[] = {
new User("杨过"),
new User("郭靖"),
new User("张无忌"),
new User("韦小宝")
};
final Account account[] = {
new Account(user[0],chinaUnionPay.CCB,"3217000010041315709",10000.00),
new Account(user[0],chinaUnionPay.CCB,"3217000010041315715",10000.00),
new Account(user[1],chinaUnionPay.CCB,"3217000010051320007",10000.00),
new Account(user[1],chinaUnionPay.ICBC,"3222081502001312389",10000.00),
new Account(user[2],chinaUnionPay.ICBC,"3222081502001312390",10000.00),
new Account(user[2],chinaUnionPay.ICBC,"3222081502001312399",10000.00),
new Account(user[2],chinaUnionPay.ICBC,"3222081502051320785",10000.00),
new Account(user[3],chinaUnionPay.ICBC,"3222081502051320786",10000.00),
};
final Card card[] = {
new Card("6217000010041315709",account[0]),
new Card("6217000010041315715",account[0]),
new Card("6217000010041315718",account[1]),
new Card("6217000010051320007",account[3]),
new Card("6222081502001312389",account[4]),
new Card("6222081502001312390",account[5]),
new Card("6222081502001312399",account[6]),
new Card("6222081502001312400",account[6]),
new Card("6222081502051320785",account[7]),
new Card("6222081502051320786",account[7]),
};
public void getDealDateResult() {
//消息处理类
String s = str.toString();
String[] s_1 = s.split("\n");
for(String i :s_1) {
String[] str = i.split("\s+");
if(str.length == 1) {
if(chinaUnionPay.Checkdata(str[0]))
System.out.println("¥" +
chinaUnionPay.getCard(str[0])
.getAccount().getMoney());
return ;
}
if(!chinaUnionPay.Checkdata(str[0])) {
//校验该卡是否存在
return ;
}
else {
switch(str[2].charAt(1)) {
case '1':
if(atm[0].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[0].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[0].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}break;
case '2':
if(atm[1].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[1].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[1].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
case '3':
if(atm[2].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[2].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[2].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
case '4':
if(atm[3].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[3].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[3].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
case '5':
if(atm[4].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[4].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[4].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
case '6':
if(atm[5].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[5].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[5].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
}
}
}
}
}
中介类存在问题:在ATM的查询并未做出可以扩展的查询类型,仅仅可以使用原来写的6个ATM.查询卡号时也没有使用对象去接收,使得该代码的执行速度十分之慢.
优点:使用到了迭代器,迭代数据的速度快了很多,且利用 了双向链表,可以两方相互寻找数据,速度较快.
双向绑定的双向链表实现(以Card类为例):
public Card(String ID, Account account) {
// TODO 自动生成的构造函数存根
this.ID = ID;
this.account = account;
this.account.getCardList().add(this);//把该卡加入其Card类的链表存储,实现双向绑定.
}
迭代器的使用:
1.(Iterator迭代器的使用)
public boolean Checkdata(String str) {//校验用户卡ID
Iterator<Card> cardltr = CardList.iterator();
//利用迭代器迭代器CardList
while(cardltr.hasNext()) {//判断有无下一元素
if(cardltr.next().getID().equals(str)) {
return true;
}
}
return false;
}
2.(增强的for循环)
public Card getCard(String str) {
for(Account i : accountList) {
if(i.getCard(str) != null)
return i.getCard(str);
}
return null;
}
对于双向绑定的理解和实现:可以看到,在该构造方法中把需要存储的另一方对象传入存储,并且调用另一方对象的链表的add()方法将自己传入,使得在另一方对象也有自己这个对象,从而实现双向绑定实现双向 链表的实现.
ATM第二次编写:
第二次的代码编写,相对于编写难度来说,没有第一次那么难,因为是由老师第一次代码进行迭代既可以实现,且老师的第一次的代码也是面向对象,中介模式的的框架,且在这次的代码编写中,整体的难度只要集中在理解老师的代码,由于老师的代码也是按照双向链表的结构来编写模式,所以对于我来说,我的第一次代码与老师的第一次代码较为相似,对于理解老师的整体框架也是比较简单,只需要在老师的代码上更改部分既可以实现借贷和利息的功能.
先上类图:

整体性能分析如下:

这是在老师原代码上更改后的代码结构,很明显可以看出,这次的代码依旧是中介模式,相对于之前第一次的代码,变化也是相当多的,单从两次的代码性能分析图就可以得知,代码的性能相对于之前的多次线性查找是快很多的,且这次的代码的各框架也得到了加强,不单单只是一个中介类那么简单,其更加的体现了"不和陌生人说话"的原则,代码也是相对于之前的代码更加蕴含面向对象思维.
以下三个方法分别为 校验,取款,输出.
public boolean verify() {
/**
* 校验该卡是否存在
*/
Card card = ValidateData.getCardbyCardNO(unionPay, cardNO);
if(card == null) {
System.out.println("Sorry,this card does not exist.");
return false;
}
/**
* 校验ATM是否存在
*/
ATM aTM = ValidateData.getATMbyATMID(unionPay, ATMID);
if(aTM == null) {
System.out.println("Sorry,the ATM's id is wrong.");
return false;
}
Account account = Account.getAmountbyCardNO(cardNO);
double balance = account.getBalance();
/**
* 校验卡密码是否正确
*/
if(!card.getCardPassword().equals(cardPassword)) {
System.out.println("Sorry,your password is wrong.");
return false;
}
/**
* 校验取款金额是否大于余额
*/if(account.maxwithdrawal(amount, aTM.getBank())){
}else {
return false;
}
return true;
}
public void withdraw() {
if(!verify()) {
return ;
}
Card card = ValidateData.getCardbyCardNO(unionPay, cardNO);
ATM aTM = ValidateData.getATMbyATMID(unionPay, ATMID);
Account account = Account.getAmountbyCardNO(cardNO);
card.access(amount,aTM.getBank());
if(amount >= 0) {
showResult(account,1, aTM);
}else {
showResult(account,0, aTM);
}
}
public void showResult(Account account,int flag, ATM aTM) {
String type = "";
if(flag == 1) {
type = "取款";
}else {
type = "存款";
amount *= -1;
}
String userName = account.getUser().getName();
String bankName = aTM.getBank().getBankName();
System.out.printf("业务:%s ",type);
System.out.println(userName + "在" +
bankName + "的" + ATMID + "号ATM机上" + type + String.format("¥%.2f", amount));
System.out.println("当前余额为" + String.format("¥%.2f", account.getBalance()));
}
存在问题:对于Card类时没有必要使用两个类去存储Card类,其本质是因为卡的账户为借贷账户与否.
优点:使用到了迭代器,迭代数据的速度快了很多,且利用 了双向链表,可以两方相互寻找数据,速度较快.
第二次相对于第一次的改变:
1.查询的速度变快,虽然两方都是使用的迭代器进行迭代,但由于编写第一次时没有理解到每一个对象都是一个指针.使得在进行处理时需要每次都进行查询一次.
第一次:
public void getDealDateResult() {
//消息处理类
String s = str.toString();
String[] s_1 = s.split("\n");
for(String i :s_1) {
String[] str = i.split("\s+");
if(str.length == 1) {
if(chinaUnionPay.Checkdata(str[0]))
System.out.println("¥" +
chinaUnionPay.getCard(str[0])
.getAccount().getMoney());
return ;
}
if(!chinaUnionPay.Checkdata(str[0])) {
//校验该卡是否存在
return ;
}
else {
switch(str[2].charAt(1)) {
case '1':
if(atm[0].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[0].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[0].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}break;
case '2':
if(atm[1].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[1].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[1].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
case '3':
if(atm[2].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[2].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[2].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
case '4':
if(atm[3].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[3].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[3].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
case '5':
if(atm[4].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[4].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[4].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
case '6':
if(atm[5].Checkpassword(chinaUnionPay.getCard(str[0]), str[1])) {
atm[5].depositordrawmoney(chinaUnionPay.getCard(str[0]),
str[1], Double.valueOf(str[3]));
this.atm[5].printf(chinaUnionPay.getCard(str[0]), Double.valueOf(str[3]));
}
break;
}
}
}
}
第二次:
public void withdraw() {
if(!verify()) {
return ;
}
Card card = ValidateData.getCardbyCardNO(unionPay, cardNO);
ATM aTM = ValidateData.getATMbyATMID(unionPay, ATMID);
Account account = Account.getAmountbyCardNO(cardNO);
card.access(amount,aTM.getBank());
if(amount >= 0) {
showResult(account,1, aTM);
}else {
showResult(account,0, aTM);
}
}
2.面向对象的思维增强:单从类图既可以看出来,第二次的代码更加符合面向对象的思维方式,分类更加的清晰,对各个方法的改进也是更加的符合面向对象的思维方式.
public class Withdraw {
private UnionPay unionPay;
private String cardNO;
private String cardPassword;
private String ATMID;
private double amount;
public Withdraw() {
super();
// TODO Auto-generated constructor stub
}
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 Withdraw(String cardNO, String cardPassword, String aTMID, double amount) {
super();
this.cardNO = cardNO;
this.cardPassword = cardPassword;
ATMID = aTMID;
this.amount = amount;
}
public boolean verify() {
/**
* 校验该卡是否存在
*/
Card card = ValidateData.getCardbyCardNO(unionPay, cardNO);
if(card == null) {
System.out.println("Sorry,this card does not exist.");
return false;
}
/**
* 校验ATM是否存在
*/
ATM aTM = ValidateData.getATMbyATMID(unionPay, ATMID);
if(aTM == null) {
System.out.println("Sorry,the ATM's id is wrong.");
return false;
}
Account account = Account.getAmountbyCardNO(cardNO);
double balance = account.getBalance();
/**
* 校验卡密码是否正确
*/
if(!card.getCardPassword().equals(cardPassword)) {
System.out.println("Sorry,your password is wrong.");
return false;
}
/**
* 校验取款金额是否大于余额
*/if(account.maxwithdrawal(amount, aTM.getBank())){
}else {
return false;
}
return true;
}
public void withdraw() {
if(!verify()) {
return ;
}
Card card = ValidateData.getCardbyCardNO(unionPay, cardNO);
ATM aTM = ValidateData.getATMbyATMID(unionPay, ATMID);
Account account = Account.getAmountbyCardNO(cardNO);
card.access(amount,aTM.getBank());
if(amount >= 0) {
showResult(account,1, aTM);
}else {
showResult(account,0, aTM);
}
}
public void showResult(Account account,int flag, ATM aTM) {
String type = "";
if(flag == 1) {
type = "取款";
}else {
type = "存款";
amount *= -1;
}
String userName = account.getUser().getName();
String bankName = aTM.getBank().getBankName();
System.out.printf("业务:%s ",type);
System.out.println(userName + "在" +
bankName + "的" + ATMID + "号ATM机上" + type + String.format("¥%.2f", amount));
System.out.println("当前余额为" + String.format("¥%.2f", account.getBalance()));
}
}
class ValidateData {
/**
* 校验卡号是否存在
* @param unionPay
* @param cardNO
* @return
*/
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;
}
/**
* 校验ATM ID是否存在
* @param unionPay
* @param ATMID
* @return
*/
public static ATM getATMbyATMID(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;
}
}
}
return null;
}
}
3.多态的使用:这也是第一次中较少使用的,但是在第二次的ATM机模拟代码中却是家常便饭,ATM机第二次的代码中,卡,账户都应当使用多态去处理难的问题,因为取款本质都是一个同样的问题,使用卡通过ATM去操作间接改变账户.所以说多态也是第二次代码改进 的范围中,且是第二次代码相对于第一次代码的特色部分.
对于ATM机代码总结:由于这次的代码没有类图,仅仅知道需要创建些什么类,使得大家的思维一时间跟不上来,需要完全靠自己思考来编写代码和代码的框架,是大家第一次写这样难度的代码遇见的情况,当然,这或许就是这次题目的最难点,需要完全靠自己来设计进行编写.但是这次的编写也是有老师提示的,就是双向链表,双向链表也是这次的代码最精彩的部分,其次是该次代码的面向对象的框架,由于是我们自己就行编写的,想要编写出拥有面向对象思维的代码也是需要进行很多的思考.总之这次代码是同时锻炼了我们面向对象的思维方式和自己进行框架设计的能力.
(3)采坑心得:
1.判断三角形是否合法是,没有完全考虑三边的情况.
public boolean validate() {
// TODO Auto-generated method stub
if(side1 < 0 || side2 < 0 || side3 < 0 || (side1 + side2 <= side3) || (side2 + side3 <= side1) || (side1 + side3 <= side2))
return false;
else
return true;
}
2.ATM机的数据进行存储时,存储错误:
3.题目集9,算法错误。
原算法:
public boolean maxwithdrawal(double money,Bank bank) {
if(bank.getBankName().equals(getBank().getBankName())) {
if(money > super.getBalance()) {
if((money - super.getBalance()) * 0.05 + money * (1 + bank.getServicecharge()) > credit + super.getBalance()) {
System.out.println("Sorry,your account balance is insufficient.");
return false;
}else {
return true;
}
}else {
return true;
}
}else {
if(money > super.getBalance()) {
if((money - super.getBalance()) * 0.05 + money > credit + super.getBalance()) {
System.out.println("Sorry,your account balance is insufficient.");
return false;
}else {
return true;
}
}else {
return true;
}
}
}
现算法:
public boolean maxwithdrawal(double money,Bank bank) {
double money_1 = super.getBalance();
if(bank.getBankName().equals(getBank().getBankName())) {
if(money > money_1) {
if(credit - (money - money_1) * 1.05 < 0) {
return false;
}
}
else {
if(money_1 - money < 0) {
return false;
}
}
}else {
double sum = 0;
if(money > money_1) {
sum = money + (money - money_1)*0.05 + money * bank.getServicecharge();
if(credit - (sum - money_1) < 0)
return false;
}else {
sum = money + money * bank.getServicecharge();
if(sum > money_1) {
if(credit - (sum - money_1) < 0)
return false;
}else {
if((money_1 - sum) < 0){
return false;
}
}
}
}
return true;
// if(bank.getBankName().equals(getBank().getBankName())) {
// if(money > super.getBalance()) {
// if((money - super.getBalance()) * 0.05 + money * (1 + bank.getServicecharge()) > credit + super.getBalance()) {
// System.out.println("Sorry,your account balance is insufficient.");
// return false;
// }else {
// return true;
// }
// }else {
// return true;
// }
// }else {
// if(money > super.getBalance()) {
// if((money - super.getBalance()) * 0.05 + money > credit + super.getBalance()) {
// System.out.println("Sorry,your account balance is insufficient.");
// return false;
// }else {
// return true;
// }
// }else {
// return true;
// }
// }
}
4.计算金额部分,把该减去的金额与金额总数的位置写反了.
(4)改进建议:
1.题目集7-2,我的代码太冗长,一些用来for循环的地方可以将它改成ArrayList,在对面积排序时,可以将冒泡排序法改成Compare To方法,更加简洁
2.对于题目集8,希望能多给些测试点,数据存储错误让我误以为是我的算法出错了,耽误了好多时间。
3.对于题目集7的接口在阐述时并没有给足够的提示,很多同学都是靠自己编写的接口,没有发现老师是为了让我们理解并且使用这个djk自带的接口.
4.业务类过于繁重,可以通过设计两个业务类,一是数据校验判断业务类,而是数据处理业务类,这样更可以体现出程序设计的单一职责原则。
5.在账户之间设定可联系的类,可为后续设计转款功能作为基础,或是在数据处理类中添加方法去完成转款功能。
6.题目集7的难度较低,且老师给的主函数几乎决定了自己代码的构造走向,使得大家写的代码都大同小异,查重率太高.
(5)总结:
本次阶段的三次作业,主要是对两种原则的掌握:“开-闭”原则,单一职责原则。以及对于“封装性,继承,多态,复用等”需要有自己的理解去很好的利用。相对于之前的代码,这次的代码更多的是靠自己去思考,自己去构想,自己去创建框架,但,对于设计的想法面向对象设计的初衷在于将处理的事情对象化.在这一阶段的学习中,对于作业难度并不是以往的设计好的算法去实现,前几次阶段的题目更像是套着面向对象的壳去用电脑完成数学题。这一阶段本身题目逻辑并不复杂,更加需要靠我们实现的是代码的框架,代码如何写才可以让我们去实现更加好的,符合面向对象思维的框架,考察的是我们对于一个事物去实现,我们该如何去做的一个好的设计,设计围绕着是否符合面向对象的思维方式,是否有足够的扩展性和维护性,以及后续根据源码去添加功能,都在让我们学习并实际去运用着面向对象编程的设计思想。


浙公网安备 33010602011771号