面向对象设计与构造2019 第一单元总结博客作业

面向对象设计与构造2019 第一单元总结博客作业

一、度量分析程序结构

1.数据度量分析

在这里,以第三次作业为例。前两次作业的架构较为简单,分析价值较低。

Type Name NOF NOPF NOM NOPM LOC WMC NC DIT LCOM FANIN FANOUT
BasicFactor 0 0 4 4 41 11 0 1 -1 0 1
Expression 1 0 11 11 124 31 0 0 0 4 3
Factor 3 0 9 9 108 27 1 0 0 2 2
Main 6 0 5 2 184 32 0 0 0 1 2
Term 1 0 13 13 206 49 0 0 0 4 3

可以看到,我的程序中,类很少,也只用了一个简单的继承。相对的,每个类的代码量较大,最大的类Term,代码长度甚至到达了206行。每个类中的方法数也相对较少,导致每个方法的代码长度也较长。说明程序在处理复杂问题的时候,依然依赖于面向过程的设计思路。

在内聚和耦合程度方面,程序没有太大问题,但是,如此少的类能够达到这种内聚耦合指标,是因为我采用了循环依赖结构。这种结构对于OO设计来说是非常不好的。但是,由于本次多项式求导需要用到递归思路,所以我这样写了。在下次作业中,我会尽量避免这种调用方式。

2.UML类图分析

在这里,贴上我三次作业的UML类图。

可以看到,三次作业中,我的设计一次比一次偏向线性化,而且类和方法的数量偏少。总的来说,还是没有跳出面向过程的设计思路。可以说,这个程序使用面向过程的涉及来写,并不需改动太多的东西。我在使用Java语言的过程中,没能很好地发挥语言的特点和长处,在面对困难问题的时候,首先采用的是我最熟悉的处理思路。

希望我能够在接下来的学习过程中,将自己程序中存在的问题逐一改正,写出优秀OO风格的程序。

二、程序BUG分析

三次作业的强测,正确性评分我都是满分。第一次作业中,互测bug被人检测出来,问题也出在正则表达式上。

总的来说,程序在读入正确数据后,分割、求导、输出的整个过程中,没有出现bug,但是这只是上交的公测最终版本的情况。在截止日期之前,从初版程序到最终版程序,中间bug出现了很多很多次,而我在处理这些bug的时候,有时也会采用特判法。造成这种后果的原因在于,我在最开始设计程序的时候,少考虑了很多东西,导致在程序模块全部搭建完成的时候出现问题,没有简单的办法去解决。

我认为,自己程序的模块化依然不够。程序的类与类之间耦合度偏高,导致出现bug后,修复常常会改掉多个类。这种现象的一个原因,可能是我在设计程序的时候是从顶层向下编写代码,导致许多问题没有丢给模块解决。下次我会尝试从底层开始向上构建程序。

三、发现别人bug的策略

我采用的测试方法,是使用黑箱测试的方法,编写数据自动生成器和对拍器,来对别人的程序进行检测。这种方法在数量上取得优势,也降低了我的思考难度。

贴一段bat代码:

@echo off
set /a count=1
:loop
	echo -------
	echo %count% 
	echo -------
	set /a count+=1
	echo generating...
	python generate.py>data.in
	echo -------
	echo running...
	java -cp saber Main<data.in>./result/saberx.out
	java -cp archer Main<data.in>./result/archerx.out
	java -cp lancer Main<data.in>./result/lancerx.out
	java -cp rider Main<data.in>./result/riderx.out
	java -cp caster Polyomial<data.in>./result/casterx.out
	java -cp assassin MainInput<data.in>./result/assassinx.out
	java -cp berserker Poly<data.in>./result/berserkerx.out
	
	echo -------
	echo checking...
	
	java Valuable<./result/saberx.out>./result/saberz.out
	java Valuable<./result/archerx.out>./result/archerz.out
	java Valuable<./result/lancerx.out>./result/lancerz.out
	java Valuable<./result/riderx.out>./result/riderz.out
	java Valuable<./result/casterx.out>./result/casterz.out
	java Valuable<./result/assassinx.out>./result/assassinz.out
	java Valuable<./result/berserkerx.out>./result/berserkerz.out
	
	
	echo -------
	echo calculating...
	
	python test.py<./result/saberz.out>./result/saber.out
	python test.py<./result/archerz.out>./result/archer.out
	python test.py<./result/lancerz.out>./result/lancer.out
	python test.py<./result/riderz.out>./result/rider.out
	python test.py<./result/casterz.out>./result/caster.out
	python test.py<./result/assassinz.out>./result/assassin.out
	python test.py<./result/berserkerz.out>./result/berserker.out 

	echo -------
	echo comparing...
	python compare.py
	TIMEOUT /T 1
goto loop

无论是测试自己的程序还是别人的程序,我都采用了生成→运行→合法性检验→对拍的计算过程。这样做的优点,是可以用时间堆积去精准寻找程序中的bug。但是缺点是,这样会让我懈怠思考,不去思考程序中可能存在的bug,在将来遇到无法用自动评测去检测的程序时,我会无从下手

从下次作业开始,我会尝试着去自己构造数据集来寻找别人的bug,以求开拓自己的思维。

四、设计模式重构思路

我认为,在自己编写这三次作业的过程中,我的思路依然局限在面向过程之中,没能很好地发挥面向对象的特性。继承、多态、接口等功能没有被我很好地运用。我在编写程序的过程中,是先写main函数,然后写main类里的方法,最后再去写其他类,这种构造顺序像极了面向过程的思路。

如果我要重构自己的程序,我会选择从底层开始搭建模块,一层一层向上设计,使用工厂模式。或者,采用助教推荐的方式,编写顶层模块功能,并将一些方法内容留空,采用填空的方式去编写程序,本质上还是从底端开始构建。先写接口,然后写父类,再写子类,最后在main函数中补全。

posted @ 2019-03-24 17:02  sharinka  阅读(292)  评论(0编辑  收藏  举报