oo前三次作业总结

OO作业总结(1-3)


 

前言

这三次作业,是我第一次,真正的系统性接触和学习Java,在这三次作业中,我对Java的理解也逐渐加深,也逐渐领悟到了从C语言入门的我在应对工程代码方面的不足,这一次学习到的度量分析又为我打开了新的大门。


(一)代码的度量分析

(1)第一次作业

第一次作业,内容是多项式计算,其中并没有涉及到复杂的计算原理和程序逻辑,而是在输入和输出的处理上略有难度。对于当时不懂正则表达式的我来说,我的第一次作业使用了状态自动机。

在第一次作业中,分为3个类,Input类处理输入,Polynomial作为主类,Term类表示单个多项式。之前我一直觉得这份代码写得还算不错,直到我最近学习了Java代码的度量分析,才惊觉之前的代码有着诸多缺点。

接下来贴上分析结果截图

显然,我的循环复杂度Cyclomatic complexity)在Input类里过高了,也就是说我的Input类功能不够单一,做不到功能内聚,需要再划分为更小的模块,才能减小程序的漏洞数。

这次由于将状态机封装进了Input类,导致的Input类复杂度过高,以后的状态机或许可以分成多个简单类的交互。

(2)第二次作业

第二次作业,内容是傻瓜电梯的调度。虽然指导书刻意复杂化了代码逻辑,但其实代码非常之简单,只需要每次处理当前请求时,将请求队列之中的同质请求消除就可以了。

在这一次作业当中,我也意识到了try,catch的重要性,在面临可能数组越界或是访问空指针的危险情况时,try and catch变得尤为重要,这样可以快速帮助锁定错误所在,希望以后我也能像各位大牛一样将try catch运用熟练。

下面贴上类图和度量分析结果

本次代码设计上的主要问题从度量分析看来主要来自于Request类的SelfCheck方法,但是本人点进去仔细查看SelfCheck函数后却并不认为其有什么问题,代码如下:

1 boolean SelfCheck(double LastTime)
2 {
3     if(Time<LastTime)return false;
4     if(Type==0 && (Aim==0 || Aim>10))return false;
5     if(Type==1 && (Dep<=1 || Dep>10))return false;
6     if(Type==2 && (Dep==0 || Dep>9))return false;
7     if(Time>(1L<<32)-1)return false;
8     return true;
9 }

这个功能仅仅用来判断Request类是否合法,而由于限制条件的众多,代码内的众多if语句也难以避免,况且该功能十分明确且简单,个人不认为这段代码有不妥的地方。

以上就是这次分析的结果,个人认为这次的情况正好对应了维基百科上所说的对于特殊情况,代码的循环复杂度可以酌情放宽

(3)第三次作业

关于第三次作业,我需要提前申明的是,本次作业我一开始的想法就错了,导致后面回天乏术。具体原因会在第二部分的bug互查说明,这里仅仅分析代码的性能。

下面贴上度量分析结果:

下面贴上Watcher中的FindDir作为示例:

 1     Request FindDir(double time)
 2     {
 3         if(time==L.GetLast()+1 && L.IsOpen())
 4         {
 5             //System.out.println("LastTime="+L.GetLast()+"  time="+time);
 6             L.Change(time);
 7             //System.out.println(L);
 8             if(Temp.GetFor()==0)
 9             {
10                 if(L.GetCnt(L.GetPos())>0 && L.GetReq(L.GetPos(), 1).GetAim()==L.GetPos())
11                 {
12                     OUT.Add("VALID", 0, L.GetReq(L.GetPos(), 1), L.GetPos(), time);
13                     L.pop(L.GetPos());
14                 }
15                 if(F[L.GetPos()].GetQn()>0 && F[L.GetPos()].GUP(1).GetDep()==L.GetPos())
16                 {
17                     //System.out.print("First:");F[L.GetPos()].GUP(1).Print();
18                     OUT.Add("VALID", 0, F[L.GetPos()].GUP(1), L.GetPos(), time);
19                     F[L.GetPos()].PopQ();
20                 }
21                 if(F[L.GetPos()].GetDn()>0 && F[L.GetPos()].GDN(1).GetDep()==L.GetPos())
22                 {
23                     OUT.Add("VALID", 0, F[L.GetPos()].GDN(1), L.GetPos(), time);
24                     F[L.GetPos()].PopD();
25                 }
26                 while(L.GetCnt(L.GetPos())>0 && L.GetReq(L.GetPos(), 1).GetAim()==L.GetPos())
27                 {
28                     OUT.Add("#SAME", 0, L.GetReq(L.GetPos(), 1), L.GetPos(), time);
29                     L.pop(L.GetPos());
30                 }
31                 while(F[L.GetPos()].GetQn()>0 && F[L.GetPos()].GUP(1).GetDep()==L.GetPos())
32                 {
33                     OUT.Add("#SAME", 0, F[L.GetPos()].GUP(1), L.GetPos(), time);
34                     F[L.GetPos()].PopQ();
35                 }
36                 while(F[L.GetPos()].GetDn()>0 && F[L.GetPos()].GDN(1).GetDep()==L.GetPos())
37                 {
38                     OUT.Add("#SAME", 0, F[L.GetPos()].GDN(1), L.GetPos(), time);
39                     F[L.GetPos()].PopD();
40                 }
41             }
42         }
43         //System.out.println("haha="+L.GetAim()+" "+L.GetPos()+" "+L.IsOpen()+" time="+time+" last="+L.GetLast());
44         //L.Print(time);
45         if(L.GetAim()==L.GetPos() && !L.IsOpen())
46         {
47             //System.out.println("hahahahahahahhahaha");
48             //L.Print(time);
49 
50             //L.Print(time);
51             int aim1=0, aim2=0, aim3=0;
52             if(time==L.GetLast())
53             {
54                 int finish = L.Finish();
55                 if(finish!=0)
56                 {
57                     L.Direct(L.GetAim()-L.GetPos()==0 ? 0 : L.GetAim()-L.GetPos()==1 ? 1 : -1);
58                     return new Request(-1);
59                 }
60             }
61             //L.Print(time);
62             for(int i=1;i<=10;++i)
63             {
64                 if(L.GetCnt(i)>0 && (aim1==0 || L.GetFront(i).GetSeq()<L.GetFront(aim1).GetSeq()))
65                     aim1 = i;
66                 if(F[i].GetQn()>0 && (aim2==0 || F[i].GUP(1).GetSeq()<F[aim2].GUP(1).GetSeq()))
67                     aim2 = i;
68                 if(F[i].GetDn()>0 && (aim3==0 || F[i].GDN(1).GetSeq()<F[aim3].GUP(1).GetSeq()))
69                     aim3 = i;
70             }
71             if(aim1>0 && 
72                     (aim2==0 || (F[aim2].GetQn()>0 && L.GetFront(aim1).GetSeq()<F[aim2].GUP(1).GetSeq())) && 
73                     (aim3==0 || (F[aim3].GetDn()>0 && L.GetFront(aim1).GetSeq()<F[aim3].GDN(1).GetSeq()))) return L.GetFront(aim1);
74             if(aim2>0 && 
75                     (aim3==0 || (F[aim3].GetDn()>0 && F[aim2].GUP(1).GetSeq()<F[aim3].GDN(1).GetSeq())) && 
76                     (aim1==0 || (L.GetCnt(aim1)>0 && L.GetFront(aim1).GetSeq()>F[aim2].GUP(1).GetSeq()))) return F[aim2].GUP(1);
77             if(aim3>0 && 
78                     (aim2==0 || (F[aim2].GetQn()>0 && F[aim2].GUP(1).GetSeq()>F[aim3].GDN(1).GetSeq())) && 
79                     (aim1==0 || (L.GetCnt(aim1)>0 && L.GetFront(aim1).GetSeq()>F[aim3].GDN(1).GetSeq()))) return F[aim3].GDN(1);
80             return new Request(-1);
81         }
82         //L.Print(time);
83         return new Request();
84     }

可见由于之前的逻辑分析失误,导致了if-else语句的滥用,由此可见,在写代码之前,有一个清晰,简单的框架是写好程序之必备,而本人在这一方面则反了经验不足的错误,以为简单按照描述来写就行,结果表明不成熟的程序框架会导致大量的冗余代码和复杂的·逻辑判断,今后必须引以为戒。


(二)bug分析

(1)第一次作业

第一次作业本人存在一个bug,那就是没有判断程序最开始是空格的情况。因为本人的最初版本程序要求程序第一个左括号,所以空格会导致判断为ERROR。

由此可见两个问题:

1.对内置函数不熟练,本来可以用string.replace来解决

2.逻辑思维不够严密

(2)第二次作业

第二次作业本人由于对助教意思的误解,对于同质请求没有输出#SAME,这是一个incomplete

(3)第三次作业

而第三次作业,本人为了完全再现电梯接受请求的反应,决定按照时间的运行来模拟,而这时由于一开始得考虑不周,本人犯了一些严重的错误:

1.电梯请求放在了电梯类,楼层请求放在了楼层类,导致交互时的代码非常繁琐

2.由于一开始的考虑不周,放弃了请求队列的想法,本意是想每次接受请求时只与当前请求比较,结果发现请求有可能排成队列

3.对于时间和请求的交互请求关系考虑不周,导致出现电梯没有及时改变方向,出现runtime error

综上所述,本人的第三次作业并没有达到理想要求,并非是修补bug可以解决的问题需要推倒重来。

以后也要吸取教训,对待程序一定要思考清楚后开始写,否则仅是浪费时间而已。

 

posted on 2018-04-04 13:42  xuyibo  阅读(158)  评论(0编辑  收藏  举报