ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java题目集第三阶段总结

2021-06-13 14:33:16  阅读:243  来源: 互联网

标签:第三阶段 题目 Account 查找 取款 java 方法 Card


java题目集第三阶段总结

1前言

题目集7主要涉及类的继承、多态性使用方法以及接口的应用。题目7-1要求实现对不同形状的图形按面积进行排序,7-2则多要求按图形种类进行分类排序。总体难度比较传统,只要吃透类图基本不会有太大困难。

题目集8只有一道题,atm机模拟程序,主要涉及综合性的软件设计知识,要写出优雅的代码难度相对比较高,对设计思想也是一个考验。对于类的组织要经过深思熟虑,按照符合直觉的方法规划类的层次,同时善用业务类进行解耦。

 

 

 

题目集9是题目集8的优化,新增了对于信用卡透支和跨行取款的支持,这增加了取款程序的复杂度,也增加了类的种类和继承层次,尤其是取款的时候要具体的账户类型,而银行管理的是抽象的账户,类型判断给程序添加了更多复杂性。

 

 

 

(2)设计与分析不同

  题目集7 7-1

 

 

 

 

处理这道题先让所有图形类从shape继承,shape有类型名的属性和返回面积的方法,可以实现不同图形了之间的比较,和类形名的输出同时兼具了判断图形合法性的方法,这些方法都由子类实现,但外部的类又基于shape的抽象调用。Card类中包含一个shape类的实例,并且实现了Comparable<>接口,DealCardList类型维护了一个Card类的链表,并且利用list类自带的sort方法实现了card对象的排序。输入的检查,和DealCardList的维护则是在main中完成。

 

 

 

可见,程序的分支是比较少的,代码复杂度也比较低。

题目集7 7-2

7-2的类图与7-1基本一致,DealCardList中添加了四种toString,分别从DealCardList维护的Card链表中利用getShgapeName选择出对应的子类输出,分类排序输出利用了同样的方法。当一个链表是有序的,那么其中任何一部分都是有序的。

 

 

 

这两道题目运用了类的继承和接口两种抽象方式,大大减少了代码的复杂度,简化了提高了代码的可读性与可维护可拓展性。对外部隐藏了复杂性让程序的各个部分解耦合。Card类,dealcardlist都是基于shape的抽象进行编程。

题目集8 7-1

  这道题的难点是如何组织如此多的实体类,并且确定方法是由什么类实现,以及在保证实现高效的情况下保证系统的解耦。

 

 

 

我的实现是Card包含一个Account引用,指向Card关联的账户,具有password属性和number(卡号)属性,而Account则包含一个Card链表,一个User对象的引用代表账户的所有者,一个Bank对象代表账户所属的银行,number属性则代表账户号,余额也有Account存储。

ChinaUnionPay对象则维护这一个bank链表,并且实现了查找账户,卡号,银行的方法。

BankServer类则包含一个ChinaUnionPay对象,和一个User链表,并且实现了查找账户,卡号,银行,atm,存取款,检查取款合法性的方法。以及维护user链表和账户,银行卡,银行,atm的方法。

BankServer中的Check方法用来检查取款合法性,先利用卡号和atm名找到具体的Card对象和ATM对象,如找不到则返回相应错误,查找的方式是自上而下,深度优先的查找。然后会利用Card对象获相应的Account对象比较余额,之后会用同样的方法比较Bank,一切无误后返回true。

取款方法则相似,先检查取款合法性,再查找Card对象,再利用Card获取Account对项,修改余额值完成取款并输出结果。

 

从结果而言,效果不错。但实际上存在这样那样的问题。

首先是查找方法过于耦合,复杂度高。要调用BankServe查找Card对象,首先要调用每个Bank的查找方法,Bank再调用每个Account的查找方法,查找方法耦合过于严重,而且因为对象在其“上级”中都是用List储存,查找效率低。

此外是业务类设计不合理,业务类本来应该是抽象的服务,但BankServe却实际上储存了银联和用户,不符合直觉。而且BankServe这个类过于宽泛了,实际上业务类应该专门处理某一类业务,而不是什么业务都处理。

 

 

 

改进方法:为Card和Account类实现compareable<>接口,并用set优化储存,Bank和银联同时管理一个Card的Set对象,银联管理一个Account的Set对象,优化查找和减少耦合,银联管理一个用户set对象。
BankServe不再储存银联和用户列表,而是在运行时传入卡号等信息。把BankServe拆分,拆分为检查合法性的类和存取款的类。

题目集9 7-1

这道题相对于题目集8增加了对跨行取款,和信用卡透支的支持,对软件编码和设计提出了更高的要求。

 

 

 

这个题目中我为Account对象添加了两个子类,一个是信用账户,一个是借记账户,Card有两个子类,信用卡和借记卡,分别对应两种账户。业务类分两个,分别用来检查合法性,和存取款。

取款方法比较复杂,先检查卡,atm是否存在,在检查密码是否正确,然后先计算贷款利息(为了防止取款导致余额变化无法确定透支部分),然后判断是否跨行,如跨行就计算手续费,二者费用相加。然后利用insteadof判断Account的类型,并基于类型判断取款是否合法,取款并输出结果。

整个取款方法相比题目集8过程更加复杂,而且要保证计算过程中余额不变,否则可能导致费用计算错误,所以取款过程先后是经过仔细推敲确定的。

在这个题目集中,卡的类型和账户的类型在定义时是确定的,而在实际管理中是抽象的,但是在取款过程中由需要具体的类型,于是我设计了两个insteadof的条件判断语句来确认账户是哪个实际类型。

虽然将对类的操作抽象出来作为业务类是非常实用的解耦方法,但是针对抽象的业务类,难以直接处理各种具体的子类。事实上如果在每个具体类中添加工具方法,或许能减少类型判断从而是方法更加优雅,程序也更加具有可维护性。

 

 

 

采坑心得

在实际编码过程中,尤其是atm的两道题目,我一开始始终希望把所有方法都放在相应的实体类当中,所以话大量的时间去思考检查取款合法性是应该属于atm类,还是银行类,还是账户类,取款动作的发出是由用户,atm,还是银行。一旦踏入了这种误区,我的思想就在里面绕来绕去,想不到方案,要不然就是太耦合,每个类都要相互配合操作,要不然就是不够直观,不符合直觉,总之一直没什么好办法。最后我联想到正则表达式相关的几个类,才尝试业务类的方案,虽然做了出来但还是认为不够优雅。最终看到答案代码才觉得,业务类是比较通用的做法。

在写形状的两道题目的时候,我对于使用接口还是非常陌生的,因为网络上资料良莠不齐,而且时间跨度很大,对比起来就非常乱。而且对于直接我不熟悉的接口和类总是有一种不信任,没把握的感觉,所以主客观的困难让我有点艰难。好在是过程比较平缓,很容易就做出来了,还学到了lamda表达式。

改进建议

在我自己的实现中基本上是很少使用接口来抽象的,实际上很多地方用接口是可以让代码更加简洁优雅的,比如题目集九,可以为Account的子类提供取款接口,再在业务类中调用相应的接口方法,就可以完全避免在类中判断类型导致耦合和可扩展性下降,此外在题目集7中使用接口来判断具体类型,而不是显示的定义String类型的字段是更好的解决方法。

此外,在题目集九中一部分判断结果输出实际上是位于主函数里面的,这种图方便的做法是非常不好的,实际上应该内置到业务类里面,保证功能的完整统一,减少不必要的复杂度。

总结

不得不说,对着类图编程是一种很奇怪的经历,在编程过程中,我要尝试和类图“达成共识”,要理解类图为什么这么设计,实际上是要干什么。如果对类图产生误读,或者不理解,那么对算法的实现又会有很大的影响。所以实际体验有时候又像是负重前行,忍受一些“不好”的设计。但在完全自己设计类的继承结构和算法之前,这种学习方式就像是一种规范,即不让我们倒退回过程的编程,也不让我们在类的设计上野蛮生长,这种引导的效果还是非常不错的。

除了设计意外,对于父类和抽象类的设计也让我受益颇多,利用抽象类,和父类或者接口,结合java自带的数据结构方法模板,能够快速方便的实现复杂的功能,并且减少bug的出现,合理的利用list,set,和增强的for循环,能大大提高效率,是非常值得推荐的做法。

在数据存储的位置方面,同一个数据可以同时存在不同的实体中,尽管这些增强的程序的耦合,但是能大大降低算法的复杂度,从而提高效率。而这种方法提供的自然而然的同步,也是非常有用的,相对于一级一级向下查找,这种方法实际上可以说利大于弊。

标签:第三阶段,题目,Account,查找,取款,java,方法,Card
来源: https://www.cnblogs.com/slsj/p/14880248.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有