雨刷问题及相关课程作业总结
雨刷问题及相关课程作业总结
近几周学习内容,课程方面包括面向对象七大设计原则(雨刷问题),作业方面则包括PTA,及实验题,现对上述学习内容进行阶段性总结如下。
雨刷问题
由雨刷问题开始的七大设计原则
第一次 雨刷1.0
课上给出了雨刷系统的基本运作模式,根据司机对控制杆,刻度盘的调节,改变雨刷的状态(主要是雨刷速度),当然也包括一些条件如控制杆和刻度盘需逐级调节等等,类似于现实中的控制杆,刻度盘,采用三种编程语言(c,java,python)实现。三种语言的代码都只包含在单一文件中,包括main函数及其他一些函数,笔者的java及python程序主要为面向对象,采用雨刷对象进行操作,而c则主要为面向过程,仅考虑司机操作,雨刷响应操作这一过程。
现截取部分代码截图如下:
Java,Python,C



第二次 雨刷2.0
相比第一次雨刷问题,将控制杆,刻度盘,雨刷等分离,引入单一职责原则(老死不相往来),迪米特法则,利用Java做成多个类,各司其职,不同对象拥有它们自己的属性方法而不受其他类影响,
不同对象采用业务类进行交互,因此我引入了ControlBar类,Dail类,Brush类,Control类,还有Driver类(仅为读取用户输入,记录司机操作,虽然意义不明 ),Main中做了输出
由Control类获取Driver操作来更改Dail,ControlBar的刻度,然后获取刻度调节Brush速度
类图

不足:对输入输出没实现分离,且类之间关系较为混乱
第三次 雨刷3.0
在第二次的基础上对程序进行了改进,Control类更名为Intermediary,更好区分于ControlBar,也对Driver类进行了大改,不再记录司机操作,而是Driver通过Intermediary来实现操作控制雨刷
新增了OutPut类来做输出,同样由InterMediary类(即原来的Control)来控制不同对象间的交互,
把输入放进了Main中
类图

不足:对输入输出的处理依旧不到位
第四次 雨刷4.0
在第三次基础上未增加新类,删除类,将输入输出统一移至OutPut类下,并将Driver类改为了单例模式,即不可创建多个Driver对象,仅能存在一个Driver,
当然现实中也是只有一个人开车,而非两个人同时开车,又因为Driver通过Intermediary控制雨刷,也就同时避免了创建多个Brush等
这样分离开后,OutPut类也即用户界面,显示信息给用户,并接受用户信息
Intermediary类也即业务类,管理不同对象间的交互,也通过OutPut对象接受用户传入的信息
类图

第五次 雨刷5.0
在第四次基础上根据里氏代换原则 ,依赖倒置原则对程序进行了修改,为实现能使用两套不同的雨刷,将ControlBar类,Dail类,Intermediary类,OutPut类改为了抽象类,作为父类
并添加了它们的子类ControlBarType1,ControlBarType2,DailType1等,以DailType1,DailType2举例,它们都拥有父类的属性挡位gear,但是挡位的上限有所不同,它们拥有与父类同名的挡位调节方法(里氏代换原则)
但是经过重写它们对挡位的调节上限不同,也即拥有不同的调档位方法。
在Intermediary类中进行ControlBar,Dail,OutPut等抽象类交互,而不涉及它们的实体子类(依赖倒置原则,依赖抽象,顶层打交道,不依赖具体,底层解耦)。
类图

PTA
题目集1
主要为日期的相关问题,三个日期的题目中类的关系也有所不同,主要是利用程序求当前日期(年月日表示)的后n天,或前n天,
重点在笔者看来,整体上是不同类之间关系的理解,不同的继承的处理,即处理好不同的年月日之间的关系,具体实现上则是边界值的处理,跨年跨月,尤其是二月的天数会根据年份变化,需考虑周到。
日期类设计其一

实现一个DateUtil类,包含上图方法,基本不涉及类的设计,只需正确实现上述功能
日期类设计其二

与其一不同,除DateUtil类,还需实现Year,Month,Day类
它们通过聚合关系联系,DateUtil聚合Day,Day聚合Month,Month聚合Year,类之间具有较高耦合性,
所以应该从Year类开始实现,再依次实现Month,Day,最后才能实现DateUtil
日期类设计其三

类的数量不变,依旧是DateUtil,Year,Month,Day类,但相较于其二,由DateUtil类聚合Year,Month,Day类,降低了类之间的耦合性,Year,Month,Day相互独立,互不影响。
而在其二中Month受Year类影响,Day又受Month类影响,而最后实现功能的类DateUtil受到Day的影响,疯狂套娃,导致如果Year类出问题则会层层波及,全盘皆错,而在调试时又会因为不同类间层层联系的关系,
无法精确定位错误,给后续程序维护带来较多麻烦。
其三中将不同类分离的设计则更好,对单独一个类的修改不会影响到其他类,就拿Year类来说,它与Month,Day类无任何直接关系,它们都可以看成一个独立的个体。
题目集2
主要为对基础语法的复习,利用好分支,循环即可。
题目集3
主要为对输入的判别,需考虑周到,对不同情况即不同输入作出相应方法,恰当利用正则表达式即可
实验Experiment
实验1
分为两块,一是加入一个新的学生后,找出班级中取得最高分的学生,及取得最高平均分的学生

二是修改求分数间运算的代码

小结
通过题目1,巩固了类的基本写法,但对类之间没有做好整体规划,拖慢了进度
后续打算提前做好规划,明确不同类应实现的功能
题目2为调试程序,不断改正题目所给代码的错误,巩固了语法,对调试程序有了进一步理解,学会了基本的调试手段
实验2
一个农夫带着一匹狼、一只羊、一颗白菜要过河,河上只有一条船能够渡河,而且农夫每次最多只能带一个动物或物品过河。当农夫不在的时候狼会吃羊,羊会吃白菜
农夫过河问题其一:



补全以给出的代码,再根据已给出的代码实现Farmer,Wolf,Rabbit,Cabbage类,它们都包含过河状态和生存状态两个属性
而Wolf,Rabbit还具有eat的方法用来检测狼是否能吃羊,以及羊是否能吃卷心菜
针对报错,原有代码直接用类名调用类中方法,故修改为静态方法
农夫过河问题其二:



在第一次实验基础上将不同类属性改为private,实现了封装性,相较于第一次的实验,能更好的保护数据不被任意修改
更改农夫过河功能,可以准确判断农夫是否过了河
小结
完善代码时要关注业务类,根据业务类确定其他类应当实现的功能,关注具体的实现过程,不断改进最终做出应有的效果,对程序的逻辑有了更深入的了解
总结与感想
写程序之前花的时间应该多于或等于写程序本身花的时间,即要对程序中应该实现的功能要先有个了解,并做好整体规划,切不可看到题目直接动手写代码,
具体些则是,想好程序应该有些什么样的类,类中应该实现怎样的方法,类之间又有何关系,写程序过程中也应该时刻注意是否犯下一些语法或逻辑错误,减少
之后调试的时间,写完后则要关注程序是否有什么不足,可以怎样修改。

浙公网安备 33010602011771号