第三次Blog作业

作业自评
20201615班20201615
一.前言
本次作业分析的内容如下:
①题目集7(7-1)、(7-2)两道题目的递进式设计分析总结
②题目集8和题目集9两道ATM机仿真题目的设计思路分析总结

这三次作业的难度并不是很大,中等吧,量也没有多大,主要都是基于之前作业的改进与优化,所以比较麻烦的都是第二次的改进,花的时间也集中在第二次上面,因为要添加的东西比较多。然后7-1,8-1,主要是新学东西的运用,难度偏易,如7-1中总的来说就是对comparable接口的考察,需要有类来实现comparable接口并重写它的compareTo()方法,还有另一种创建比较器的方法来实现比较——comparator比较器,7-1中就是用到第一种方法来实现比较。8-1是模拟一个自动ATM机,这次作业实现的功能不是很多,主要是数据的录入与单一职责原则的设计,比较容易些,9-1在它的基础上进行的改进其实是比较大的,实现的功能有点多,比较麻烦。比如要考虑税收,要考虑贷记卡的税收比例,跨行的税收比例,其实这更加接近实际的ATM机。9-1主要难度集中在对每一种情况的考虑是否到位,情况是在是多,给我的感受是很多的if-else语句。

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

先把类图和报表图放出来:

这里老师刚刚引入比较器的概念,然后题目要求还要有程序设计的开-闭原则,题目中的卡片实现了comparable接口,实际上就是实现对各种图形的面积的排序。而题目又要求是从大到小排序,所以重写的compareTo()方法中应该是return o.area-this.area,这即是降序排列。

此外就是类的聚合与继承,card类中有shape类,各种形状类继承shape类,并重写shape中的方法:

还有的就是对输入的处理要分类,用一个while循环来实现对每种图案的数据输入。
2.7-2
沿袭作业 7-1,本次作业主要对卡片(Card)进行分组游戏,其规则为随机发放一些卡片给学生,卡片仍然分为四种形状:圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid),并给出各种卡片的相应参数,要求学生首先根据卡片类型将所有卡片进行分组,之后再进行排序,这依然是比较接口来实现的。
下面是卡片分组的类图与报表图:

我个人感觉他在与第一次的最大改进方面就是输出方式吧,7-1只是分类后再输出里面的数据,但是7-2中的每次输出都要带上它所处的图形名,输入的数据是怎么样的顺序,输出时数据也要按照顺序,排序后的数据也是要对应的,我写的感觉是比较麻烦的,我是直接创建了一个初始输入的集合相当于来存储顺序的,之后再分类每一种图形,对于每一个的数据相当于要存储两次,先是按照输入顺序来存储·各种形状,这个集合我设置为存储shape类型的,这样不管什么形状都可以存储,然后才将形状分类的,第一个直接针对输出The original list的,然后是每一种形状的输出。

之后的排序我是用另一种方法写的,当时用的是collection.swap方法,其实用compare接口来写更简单的。之后的按照大小输出和直接输出存储顺序我是直接输出分号后接着另一个分号的,并没有用什么简单的方法来遍历,应该是可以用类的toString方法的,在各种形状的类中重写一下toString方法,输出时直接输出类名,不用输出一大串点点点的。
开始时一直有个问题就是在idea中输出完全没有问题。但是交作业时一个都不对,我也是后来才注意到题目中要求是将Scanner方法写成静态方法,这样在每一个类中调用时直接访问Main.input.,改成这样之后再测试就对了,这其实涉及到简洁性的问题,我也不知道原理。

3.8-1
编写一个银行 ATM 机的模拟程序,能够完成用户的存款、取款以及查询余额功能。尝试使用面向对象技术对银行用户在 ATM 机上进行相关操作的模拟系统设计,上述的相关概念均要设计为实体类,业务(控制)类请自行根据实际需要进行扩充和完善。注意:为降低难度,本次作业限定银行卡均为借记卡(不能透支),且不允许跨行办理相关业务(例如在中国建设银行的 ATM 机上对其他银行的账户进行操作)。
下面是模拟atm机的类图:

类图看上去挺简单的,其实处理起来这道题也算是比较难的,此次作业要求主要是体现单一职责原则,老师给的类图和部分设计都体现了这一编程原则,此外还有几个类的聚合设计,再次考察对类的继承与实现。银联类有一个银行集合成员,银行类有一个atm机集合属性,还有一个用户集合属性,用户类有一个账户集合属性,账户类有一个银行卡集合属性,这些是主流聚合关系,还有其他的银行名称,账户总金额,atm机编号等等。要正确找到他们得关系其实也是一个比较费时间的过程,要不是上课是老师提示了一下,真的是很难想到该如何布局,这些类都是一层套一层的,布局完成后整体结构会很清晰,照着这个结构书写就会很简单。
还有一些要注意的点,比如10000元是银行用户的账号的总金额,也就是说如果这个账号下有很多银行卡的话,那么这些银行卡共用这一张卡的金额。

还有就是输入的是每一张的银行卡号,也就是最底层的部分,不要错误地当成了输入的是账号,初始化数据后再进行一系类的操作,输入前要确保你确实存储了值在银联这一大类中,再输入前你可以设置一条或者多条输出语句,来输出银联的银行属性中的某个属性值,来确保存值是否有误。
之后的操作就是对输入属性的各种检测,对卡号是否存在的检测,对密码的检测,对atm机的检测,对余额的检测,这些都是比较常规的,余额的检测只是大于账户所剩余额即可,没有税率一说,然后就是取款,存款的操作,我都是分函数来写的,这样结构比较分明,检查起来就十分容易,直接对照测试点对各个功能进行改查就行。

我写的是用for循环来找到在银联类中的属性的位置,此时在最里层访问时就相当于已经找到它的下标,直接访问数据就可以,其实是可以直接将这个查找过程写到一个方法里,每次用到的时候直接调用就好,我每次都用的是再来一遍。

然后比较麻烦的就是如何处理输入的东西了吧!这个跟之前的关键字提取的输入处理挺相似,还是用到二维数组来存储每行的空格分隔的数据,先定义一个字符串数组来存储输入的多行数据,再对每一行数据进行分隔,用到split()方法来分隔,所以我定义数组时直接定义两个数组,一个一维数组,一个二维数组。

由于输入的时候是字符串形式而用到检测或者处理的时候需要数字形式,所以要用到包装类的方法,Double.parseDouble()和Integer.parseInt()方法,来将字符串形式转化为double型或者Int型。方法体并没有多复杂。

4.9-1
注意:本次作业中银行卡包含借记卡和信用卡两类,且允许跨行办理相关业务(例如在中国建设银行的 ATM 机上使用中国工商银行的银行卡进行业务操作)
下面是atm机优化的类图:

这是在之前的基础上的,需要调整的东西还挺多,它新加了一个农业银行,然后又新加了几个用户,此外最让人头大的就是税率了,税率挺复杂的,还要有贷记卡的区分,它这个测试点的数据也是我算了挺久的。
为了区分贷记卡与借记卡,我在账户上面加了一个属性,用来区分:

然后就是贷款额度为50000,在检查余额时要判断最终的金额是否小于-50000。检查金额时情况比较复杂,首先要判断为哪种卡,如果是贷记卡,然后就要判断它当前余额是大于0还是小于0,因为大于0的部分与小于0的部分税率不同,再然后就是判断跨行的情况,税率又有区别,这个余额是减去税率后金额满足条件才行,不是光余额大于取的钱。如果你的检查金额情况过了的话,之后的考虑就按照这个分类讨论就好。
存款取款操作也是按照之前检查金额的顺序来,先是判断账户种类,若为贷记卡,则要分取款的金额是否大于余额,再分是否跨行,再在之前的嵌套里分余额是否大于0,取款的金额小于余额较简单,然后是借记卡的话会简单的多,讨论的情况少很多。

还有就是测试点问题,pta上的测试点我都是对的,但是一分都没有,我觉得还是要增加测试点的数量,要不然找不到改进的方向。

三.踩坑心得
1.对题目要求真的要看清,比如8-1我开始写的情况是对输入的银行账号的处理,导致最后改了很久输出没有数据。
2.对于很多组数据的初始化时,要注意细心,不要有遗漏,而且如果遗漏你会在后面寻找错误,你会认为是逻辑出现问题,其实不然,会很浪费时间,比如在写9-1时,我少创建了农业银行,导致输出一直为空,我还以为没有找到用户。
3.逻辑处理得当可以少些很多代码,比如在9-1中的税率计算中,你如果将对于账户余额是否大于0,放在判断银行卡的前面时,会很麻烦。
4.对于多个for循环嵌套时如果只针对最里面的一层关系,处理完后可以直接return,退出这个方法,不要再让它继续了,虽然好像并不怎么影响。

四.改进建议:
1.建议pta作业测试点多增加几个,上次9-1我数据都存储错误了但是所有测试点都对,误导我认为写对了不给分。
2.对于难度较大的题目老师可以给出一点提示,自己有时会很难想到,且会很费时间。

五.总结
1.编程的单一职责原则可以很清楚地看到各个类之间的关系即结构,这也需要编程者对每个类的功能分工分析准确,准确实现每个类的特有方法,恰当地增强代码的可复写性,每个类和方法的功能尽量体现出来。
2.再次练习了类的定义、方法的调用、参数的传递、对象的构造与使用,其中我觉得最大的进步是对结构的分析,准确地判断在何时引用各个职责功能类。
3.父类引用指向子类对象,若父类中属性定义为私有属性,则子类不能继承,编译和访问时的变量都是父类,setter,getter方法改变的值也是父类对象的值。
4.多态拥有很好的代码复写性,方法的形参用父类引用,传值时会方便很多,可以简化很多代码,并且书写很自由。
5.对结构的分析要把握好,看清内部调用关系,正确处理每个实验要求。

posted @ 2021-06-14 14:16  jiangjin1  阅读(92)  评论(0)    收藏  举报