This document presents the results of analyzing a 5,000 line Java project with the VizzMaintenance metrics tool. The project was developed over 3 months by a single developer without formal defect prevention methods. Each class is preceded by its metrics report from VizzMaintenance and a comment on potential design issues based on the metrics. Several classes are highlighted as having low Locality of Data or Tight Class Cohesion metrics, indicating errors in abstraction or design. The CommaHyphenString class is discussed in more detail as an example, with explanations of how its LD and TCC metrics relate to potential problems in testability and maintainability.
3. CONTENTS
1 Introduction 4
2 Means and Practices for Defect Prevention in Java Software
Development
4
3 EXAMPLE TOOLS FOR DEFECT PREVENTION IN
JAVA PROJECTS
5
4 Sample Project Specifications 5
5 METRICS 6
6 VizzMaintenance Report For Sample Project 7
7 Java Source Code 8
8 About the Author 170
4. Zarko Acimovic
1 INTRODUCTION
I present 5000 lines of Java source code mostly written by using trial-error, code-test, design-at-keyboard “techniques”
without using VizzMaintenance defect prevention tool. After the project was written, VizzMaintenace tool was run
against it and delivered report for it. Each class is preceded with VizzMaintenace report and comment about class
design issue based on VizzMaintenance judgment.
The code was written for prototype project in three months. I wrote the code in 2004 and ever since had several
business offers to commercialize it which I resisted due to complexity of the code.
I recommend readers to switch to formal software development, such as B, Event-B, VDM or Z.
2 MEANS AND PRACTICES FOR DEFECT PREVENTION
Prototyping (modeling) defect prevention method has efficiency 52%. Before implementing this method
defect potential per 1 FP (function point) was 5, after, 2.4.
Tool: ArgoUML
Static analysis of source code defect prevention method has efficiency 44%. Defect potential per 1 FP was 5,
after implementing this method is 2.8.
Tool: Coverity
Mathematical test case design defect prevention efficiency was 34%. Defect potential per 1 FP is 5, after is
3.3.
Tool: Bullseye
Bonus: Root cause analysis 1044-1993 - IEEE Standard Classification for Software Anomalies. Efficiency 41% -
Before 5 – After 2.95
Source: Chapter 3. Estimating and Measuring Software Quality. The Economics of Software Quality, ISBN:
9780132564762 , Capers Jones, Olivier Bonsignour
http://www.amazon.com/Economics-Software-Quality-Capers-Jones/dp/0132582201
iv
5. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
http://www.informit.com/store/product.aspx?isbn=0132582201
3 EXAMPLE TOOLS FOR DEFECT PREVENTION IN JAVA PROJECTS
Source: http://codedependents.com/2009/07/01/top-5-static-analysis-plugins-for-eclipse/
Code Coverage tool EclEmma http://www.eclemma.org/
Byte Code Analysis FindBugs http://findbugs.sourceforge.net/
Code Complexity Analysis http://www.stateofflow.com/projects/16/eclipsemetrics
Dependency Analysis JDepend4Eclipse http://andrei.gmxhome.de/jdepend4eclipse/
Source Code Analysis PMD http://pmd.sourceforge.net/
4 SAMPLE PROJECT SPECIFICATION
Project duration 3 months, single developer , 5000 lines of code (including comments), 15 Java 2 Micro Edition
classes
Tools used: Sun J2ME Wireless Toolkit, Eclipse, IBM WebSphere Device Developer 5.5, CVS, Motorola and Nokia
phone emulators and SDKs. Technology: J2ME, MIDP 2.0, CLDC 1.1.
Device-independent Java 2 Micro Edition (J2ME) midlet, executable in any emulator or mobile device, for displaying
map with scale, following moving objects, zoom in-out and pan, selection of location , measuring distance, following
individual or vehicle on map with route presentation, presentation of waypoints on map, presentation of list of
existing waypoints (sorted by name, type, distance) for selecting destination or editing and deletion, creating, editing
and deletion of waypoint – points with coordinates, name, type, icon; coordinates are defined by current position,
selected location on map or inserted in textual form, selection of waypoint as destination and navigation towards that
destination. Some classes implemented: MapBackground, MapObject, Point, SelectorPoint, PVector, MapsMIDlet
v
6. Zarko Acimovic
5 METRICS (CLICK ON LINK FOR DETAILS)
•Complexity
•Size
•Lines of Code (LOC)
•Interface Complexity
•Number of Attributes and Methods (SIZE2)
•Number Of local Methods (NOM)
•Structural Complexity
•McCabe Cyclomatic Complexity (CC)
•Weighted Method Count (WMC)
•Response For a Class (RFC)
•Architecture and Structure
•Inheritance
•Depth of Inheritance Tree (DIT)
•Number Of Children (NOC)
•Coupling
•Afferent Coupling (Ca)
•Coupling Between Objects (CBO)
•Change Dependency Between Classes (CDBC)
•Change Dependency Of Classes (CDOC)
•Efferent Coupling (Ce)
•Coupling Factor (CF)
•Data Abstraction Coupling (DAC)
vi
7. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
•Instability (I)
•Locality of Data (LD)
•Message Passing Coupling (MPC)
•Package Data Abstraction Coupling (PDAC)
•Cohesion
•Lack of Cohesion in Methods (LCOM)
•Improvement of LCOM (ILCOM)
•Tight Class Cohesion (TCC)
•Design Guidelines and Code Conventions
•Documentation
•Lack Of Documentation (LOD)
•Code Conventions
5 VIZZMAINTENANCE REPORT FOR SAMPLE PROJECT
vii
8. Zarko Acimovic
6 SOURCE CODE
As you can see in the above table the problem with below CommaHyphenString class is that LD metric is zero. From
http://www.arisa.se/compendium/node112.html we learn more about Loclity of Data metric:
The Locality of Data metric relates the amount of data being local the class to the total amount of data used by the
class. This relates to the quality of abstraction embodied by the class and allows conclusions on the reuse potential of
the class and testability. To find out precisely how this metric is calculated and how it affects software quality
attributes such as testability or maintainability please check http://www.arisa.se/compendium/node112.html
Also there is problem with Tight Class Cohesion. The Tight Class Cohesion metric measures the cohesion between
the public methods of a class. That is the relative number of directly connected public methods in the class. Classes
having a low cohesion indicate errors in the design. http://www.arisa.se/compendium/node118.html
Here is the CommaHyphenString.java source code
1 /**
2 *
3 * CommaHyphenString parses .properties file. It eliminates commas or low
lines
4 * from .properties file so items in it( such as categories) could be
properly
5 * showed on screen
6 */
7 import java.util.*;
8
9 public class CommaHyphenString {
10
11 //String s;
12 int lastIndex;
viii
Class Name Maintainability CBO CYC_Classes DAC DIT ILCOM LCOM LD LEN LOC LOD_Class MPC NAM NOC NOM RFC TCC WMC
MapsMIDlet 0.4696 15 1 15 0 2 75 0.9909 10 1356 0.667 152 134 0 11 95 0.1429 142
MapBackground 0 2 1 2 0 4 480 1.923 13 616 0.29 27 77 0 30 40 0.207 59
Outlook 0.0490881667 5 1 5 0 1 3 0.9 7 103 0.917 19 21 0 11 27 0.436 20
DelRoute 0.068318936 0 1 0 0 1 0 1 8 23 0.75 0 5 0 3 3 0 3
MapObjects 0 5 1 5 0 1 311 1 10 370 0.4 54 41 0 29 53 0.29 70
CompassCanvas 0.0490881667 3 1 3 0 1 0 0.864 13 291 1 78 26 0 3 14 1 13
PVector 0.068318936 3 1 3 0 3 255 1 7 313 0.334 25 21 0 17 32 0.037 40
Point 0.2540449746 2 1 2 0 10 1164 1.3 5 699 0.18 33 60 0 38 45 0.074 51
MathFP 0.0981763335 0 1 0 0 1 732 0.875 6 440 0.86 0 46 0 34 34 0.16 95
ImageCanvas3 0.0490881667 1 1 1 0 1 0 1 12 52 1 5 3 0 2 6 1 6
TextFormFriend 0.068318936 0 1 0 0 2 0 0 14 52 0.33 0 7 0 5 5 0.4 5
TextFormWP 0.2049568079 0 1 0 0 10 112 0 10 175 0.077 0 23 0 12 12 0.03 12
TextForm 0.1366378719 1 1 1 0 5 67 0 8 103 0.67 2 16 0 11 12 0.145 11
Thread4Friend 0.1174071027 5 1 5 0 3 37 1 13 173 0.875 5 16 0 7 11 0.048 18
MapsMIDlet 0.4696284108 15 1 15 0 2 75 0.991 10 1356 0.67 152 134 0 11 95 0.143 142
SelectorPoint 0 6 1 6 0 1 70 1 13 520 0.381 90 28 0 20 63 0.36 71
Friend 0.0490881667 1 1 1 0 3 20 1 6 50 0.889 1 12 0 8 9 0.25 9
SimpleTextForm 0.068318936 0 1 0 0 3 11 0 14 70 0.5 0 11 0 7 7 0.29 7
MapBackgroundFactory 0.2049568079 1 1 1 0 1 0 0 20 32 0.5 1 2 0 1 1 0 1
HeapSorter 0.1857260387 0 1 0 0 0 169 0 10 125 0.929 0 13 0 13 13 0 27
TextFormImage 0.1366378719 0 1 0 0 3 40 0 13 75 0.556 0 11 0 8 8 0.107 8
Coordinates 0.1366378719 1 1 1 0 4 68 0.285 11 266 0 31 21 0 10 20 0.083 16
CommaHyphenString 0.1366378719 0 1 0 0 0 25 0 17 80 0.167 0 6 0 5 5 0 13
9. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
13 CommaHyphenString(){}
14
15
16 /** Eliminates commas, returns array of strings with low line
17 * @return String[]
18 */
19 String[] getWithLowLine(String s) {
20 int lastIndex = defineLast(s);
21 if(lastIndex==0){
22 String[] ss = new String[1];
23 ss[0] = s;
24 return ss;
25 } else {
26 int start = -1;
27 Vector v = new Vector();
28 int current = s.indexOf(',');
29 do {
30 v.addElement(s.substring(start+1,current));
31 start = current;
32 current = s.indexOf(',',current+1);
33 } while (start!=lastIndex);
34
35 String[] ss = new String[v.size()+1];
36 for(int i=0; i<v.size(); i++){
37 ss[i] = (String)v.elementAt(i);
38 }
39 ss[v.size()] = s.substring(lastIndex+1,s.length());
40 return ss;
41 }
42 }
43
44 /** Eliminates low line
45 * @return String[]
46 */
47 String[] getStringsOnly(String s){
48 String[] temp = this.getWithLowLine(s);
49 for (int i=0; i<temp.length; i++){
50 char[] tempChar = temp[i].toCharArray();
51 String k = "";
52 for (int j=0; j<tempChar.length; j++){
53 if(tempChar[j]=='_') tempChar[j]=' ';
54 k+=tempChar[j];
55 }
56 temp[i] = k;
57 }
58 return temp;
59 }
60
61
62 /** Returns categories with low line
63 * @return String[]
ix
11. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
Number of Attributes and Methods (SIZE2)
Number Of local Methods (NOM)
Structural Complexity
McCabe Cyclomatic Complexity (CC)
Weighted Method Count (WMC)
Response For a Class (RFC)
Architecture and Structure
Inheritance
Depth of Inheritance Tree (DIT)
Number Of Children (NOC)
Coupling
Afferent Coupling (Ca)
Coupling Between Objects (CBO)
Change Dependency Between Classes (CDBC)
Change Dependency Of Classes (CDOC)
Efferent Coupling (Ce)
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
xi
12. Zarko Acimovic
Lack Of Documentation (LOD)
Code Conventions
As you can see on the above table the problem with below class CompassCanvas is that LOD metric is zero. Lack Of
Documentation description: How many comments are lacking in a class, considering one class comment and a
comment per method as optimum. Structure and content of the comments are ignored. To find out how this metric is
calculated please check http://www.arisa.se/compendium/node121.html .
CompassCanvas.java source code
1 /**
2 *
3 * ComapssCanvas draws compass on screen
4 */
5 import javax.microedition.lcdui.*;
6 //import javax.microedition.midlet.*;
7
8
9
10 public class CompassCanvas extends Canvas implements Runnable{
11 long north;
12 long south;
13 long east;
14 long west;
15 int bigRadius;
16 int smallRadius;
17 int smallestRadius;
18 Coordinates c;
19 long delta = 0;
20 Thread t;
21 boolean end = false;
22 boolean switchVar = false;
23 boolean switched = false;
24 MapObjects mob;
25
26 int dummy1 = 0;
27 int dummy2 = 0;
28 int dummy3 = 0;
29 int dummy4 = 0;
30 Image img;
31
32 Image imgDest;
33 long destUp;
34 long destDown;
35 long gama;
36
37
xii
13. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
38 CompassCanvas(MapObjects mob){
39 this.mob = mob;
40 north = MathFP.toFP("0");
41 south = MathFP.div(Coordinates.MathFP_2PI,MathFP.toFP("2"));
42 east = MathFP.mul(Coordinates.MathFP_2PI,MathFP.toFP("0.25"));
43 west = MathFP.mul(Coordinates.MathFP_2PI,MathFP.toFP("0.75"));
44
45 destUp = MathFP.toFP("0");
46 destDown = MathFP.div(Coordinates.MathFP_2PI,MathFP.toFP("2"));
47
48 bigRadius = Math.min(this.getWidth(),this.getHeight());
49 smallRadius = (int)(0.75*bigRadius);
50 smallestRadius = (int)(0.37*bigRadius);
51 try{
52 img = Image.createImage("Arrow2.jpg");
53 }catch(Exception e){}
54
55 try{
56 imgDest = Image.createImage("Dest.jpg");
57 }catch(Exception e){}
58
59 t = new Thread(this);
60 t.start();
61 }
62
63 public void paint(Graphics g){
64 //System.out.println("delta="+MathFP.toString(delta));
65 g.setColor(255,255,255);
66 g.fillRect(0,0,this.getWidth(),this.getHeight());
67 g.setColor(0,0,0);
68 if(end == false){
69 g.drawImage(img,75,25,0);
70
71
//System.out.println("this.getWidth()="+this.getWidth());
72
//System.out.println("this.getHeight()="+this.getHeight());
73 g.drawArc(8,0,bigRadius,bigRadius,0,360);
74 g.drawArc(30,22,smallRadius,smallRadius,0,360);
75
76 String sx =
MathFP.toString(MathFP.add(MathFP.toFP(93),MathFP.mul(MathFP.toFP(75),MathFP.sin(Ma
thFP.sub(north,delta)))));
77 String sy =
MathFP.toString(MathFP.sub(MathFP.toFP(85),MathFP.mul(MathFP.toFP(75),MathFP.cos(Ma
thFP.sub(north,delta)))));
78 int ix = sx.indexOf('.');
79 sx = sx.substring(0,ix);
80 int iy = sy.indexOf('.');
81 sy = sy.substring(0,iy);
82
xiii
14. Zarko Acimovic
83 int x = Integer.parseInt(sx);
84 int y = Integer.parseInt(sy);
85
86 String s9 =
MathFP.toString(MathFP.add(MathFP.toFP(93),MathFP.mul(MathFP.toFP(smallestRadius),M
athFP.sin(MathFP.sub(north,delta)))));
87 ix = s9.indexOf('.');
88 s9 = s9.substring(0,ix);
89 int NX = Integer.parseInt(s9);
90 String s10 =
MathFP.toString(MathFP.sub(MathFP.toFP(85),MathFP.mul(MathFP.toFP(smallestRadius),M
athFP.cos(MathFP.sub(north,delta)))));
91 iy = s10.indexOf('.');
92 s10 = s10.substring(0,iy);
93 int NY = Integer.parseInt(s10);
94
95 g.drawString("N",x,y,0);
96
97 sx =
MathFP.toString(MathFP.add(MathFP.toFP(93),MathFP.mul(MathFP.toFP(75),MathFP.sin(Ma
thFP.sub(south,delta)))));
98 sy =
MathFP.toString(MathFP.sub(MathFP.toFP(85),MathFP.mul(MathFP.toFP(75),MathFP.cos(Ma
thFP.sub(south,delta)))));
99 ix = sx.indexOf('.');
100 sx = sx.substring(0,ix);
101 iy = sy.indexOf('.');
102 sy = sy.substring(0,iy);
103
104 x = Integer.parseInt(sx);
105 y = Integer.parseInt(sy);
106
107 String s11 =
MathFP.toString(MathFP.add(MathFP.toFP(93),MathFP.mul(MathFP.toFP(smallestRadius),M
athFP.sin(MathFP.sub(south,delta)))));
108 ix = s11.indexOf('.');
109 s11 = s11.substring(0,ix);
110 int SX = Integer.parseInt(s11);
111 String s12 =
MathFP.toString(MathFP.sub(MathFP.toFP(85),MathFP.mul(MathFP.toFP(smallestRadius),M
athFP.cos(MathFP.sub(south,delta)))));
112 iy = s12.indexOf('.');
113 s12 = s12.substring(0,iy);
114 int SY = Integer.parseInt(s12);
115
116
117
118 g.drawString("S",x,y,0);
119 int del = 0;
120 g.drawLine(NX-del,NY-del,SX-del,SY-del);
121
xiv
21. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
As you can see on above table, Coordinates class has problem with metrics LD and TCC. TCC or Tight Class
Cohesion Description: The Tight Class Cohesion metric measures the cohesion between the public methods of a
class. That is the relative number of directly connected public methods in the class. Classes having a low cohesion
indicate errors in the design. http://www.arisa.se/compendium/node118.html
Locality of Data. Description. The Locality of Data metric relates the amount of data being local the class to the total
amount of data used by the class. This relates to the quality of abstraction embodied by the class and allows
conclusions on the reuse potential of the class and testability. http://www.arisa.se/compendium/node112.html
Coordinates.java source code
1 /**
2 *
3 * Coordinates class different performs geographical calculations
4 */
5
6
7
8 //import net.jscience.math.MathFP;
9 public class Coordinates {
10 /**
xxi
22. Zarko Acimovic
11 * Earth's radius (in meters)
12 */
13 public static final long EARTH_RADIUS = MathFP.toFP(6367000);
14 public static final long EARTH_RADIUS2 = MathFP.toFP(6367000*2);
15 /**
16 * the WGS-84 latitude of a location
17 */
18 private long latitude;
19 /**
20 * the WGS-84 longitude of a location
21 */
22 private long longitude;
23 /**
24 * The altitude of the location in meters, defined as height above WGS-84
ellipsoid. Float.NaN can be used to indicate that the altitude is not known.
25 */
26
27
28 /**
29 * Constructor
30 * @param latitude latitude as WGS-84 system coordinate
31 * @param longitude longitude as WGS-84 system coordinate
32 * @param altitude the altitude in meters, if known, or Float.NaN
33 * @param timestamp the time when information stored in this object
was created, in milliseconds since midnight January 1, 1970 GMT, or -1
34 * @param source the short string describing where data contained
in this object came from, like "GPS", "Network", "Database", etc
35 * @param horizontalAccuracy the horizontal accuracy of coordinates
in meters, or Float.NaN
36 * @param verticalAccuracy vertical accuracy of coordinates in
meters, or Float.NaN
37 */
38 public Coordinates(long latitude, long longitude){
39 this.latitude=latitude;
40 this.longitude=longitude;
41 }
42
43 /**
44 * Copy constructor
45 * @param original copied object
46 */
47 public Coordinates(Coordinates original){
48 this.latitude=original.latitude;
49 this.longitude=original.longitude;
50 }
51
52
53 /**
54 * The WGS-84 latitude of a location
55 * @return WGS-84 latitude
56 */
xxii
23. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
57 public long getLatitude(){
58 return latitude;
59 }
60
61 /**
62 * The WGS-84 longitude of a location
63 * @return WGS-84 longitude
64 */
65 public long getLongitude(){
66 return longitude;
67 }
68
69
70 /**
71 * Set latitude as WGS-84 system coordinate.
72 * @param latitude latitude as WGS-84 system coordinate
73 */
74 public void setLatitude(long latitude){
75 this.latitude=latitude;
76 }
77
78 /**
79 * Set longitude as WGS-84 system coordinate.
80 * @param longitude longitude as WGS-84 system coordinate
81 */
82 public void setLongitude(long longitude){
83 this.longitude=longitude;
84 }
85
86 /**
87 * Calculate bearing to another location on the surface of the Earth,
using the Great Circle.
88 * bearing - 1.way of behaving 2.connection 3.direction shown by
compass 4.understanding of one's position
89 * @param to another point
90 * @return long representing angle in degrees [0,360) between
corresponding meridian in first point and line on the Great Circle between those
points
91 */
92 public long bearing(Coordinates to){
93 return bearing(getLatitude(), getLongitude(), to.getLatitude(),
to.getLongitude());
94 }
95 /**
96 * Calculate bearing between points (latFrom, lonFrom) and (latTo,lonTo)
on the surface of the Earth, using the Great Circle.
97 * @param latFrom latitude of the first point
98 * @param lonFrom longitude of the first point
99 * @param latTo latitude of the second point
100 * @param lonTo longitude of the second point
xxiii
24. Zarko Acimovic
101 * @return long representing angle in degrees [0,360) between
corresponding meridian in first point and line on the Great Circle between those
points
102 */
103 protected static long bearing(long latFrom, long lonFrom, long latTo,
long lonTo){
104 //BMa: Some numeric with MathFP still happen - but error is mostly
below 16 degrees
105 // This should be fixed only if the final target device stays without
not have floats or doubles (e.g. it is not CLDC 1.1)
106 long bearing;
107 long deltaLat=latTo-latFrom;
108 long deltaLon=lonTo-lonFrom;
109 if (MathFP.abs(deltaLat)<MathFP_1 && MathFP.abs(deltaLon)<MathFP_1) {
110 // longiude and latitude distance within one deegre, could invent
better condition
111 //This approximation works better for smaller distances
112 latFrom = degreesToRadians(latFrom);
113 deltaLon=MathFP.mul(deltaLon, MathFP.cos(latFrom));
114 bearing = MathFP.atan2(deltaLat,deltaLon);
115 }else{
116 latFrom = degreesToRadians(latFrom);
117 latTo = degreesToRadians(latTo);
118 lonFrom = degreesToRadians(lonFrom);
119 lonTo = degreesToRadians(lonTo);
120
121
122 if (latFrom==latTo && lonFrom==lonTo)
123 return 0;
124 //if (MathFP.cos(latFrom) < Double.MIN_VALUE) // Double.MIN_VALUE a
small number ~ machine precision, so here we check for +/-0
125 if (MathFP.cos(latFrom) == 0 ) // Double.MIN_VALUE a small number ~
machine precision, so here we check for +/-0
126 if (latFrom > 0)
127 return MathFP.PI; // starting from N pole
128 else
129 return MathFP_2PI; // starting from S pole
130 //double bearing = radiansToDegrees(Math.atan2(Math.sin(lon2-
lon1)*Math.cos(lat2),Math.cos(lat1)*Math.sin(lat2)-
Math.sin(lat1)*Math.cos(lat2)*Math.cos(lon2-lon1))%(2*Math.PI));
131
132 bearing = MathFP.atan2(
133 MathFP.mul(MathFP.sin(deltaLon),MathFP.cos(latTo)),
134 MathFP.mul(MathFP.cos(latFrom),MathFP.sin(latTo))-
135
MathFP.mul(MathFP.mul(MathFP.sin(latFrom),MathFP.cos(latTo)),MathFP.cos(deltaLon)))
;
136 }
137 bearing = MathFP.mod(radiansToDegrees(bearing), MathFP_360);
138
139 if (bearing<0) bearing = MathFP_360 + bearing;
xxiv
25. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
140 return bearing;
141 }
142
143 /**
144 * Calculate distance to another location on the surface of the Earth,
using the Great Circle.
145 * @param to another point
146 * @return distance to another location in meters, using the line on the
Great Circle
147 */
148 public long distance(Coordinates to){
149 //BMa: Some numeric with MathFP are still possible - errors happen
sometimes
150 // This should be fixed only if the final target device stays without
not have floats or doubles (e.g. it is not CLDC 1.1)
151 return calculateDistance(getLatitude(), getLongitude(),
to.getLatitude(), to.getLongitude());
152 }
153
154 /**
155 * Calculate distance between points (latFrom, lonFrom) and (latTo,lonTo)
on the surface of the Earth, using the Great Circle.
156 * lat , lon - degrees ([-90, +90]; [-180, +180])
157 *
158 * @param latFrom latitude of the first point
159 * @param lonFrom longitude of the first point
160 * @param latTo latitude of the second point
161 * @param lonTo longitude of the second point
162 * @return distance to another location in meters, using the line on the
Great Circle
163 */
164 public static long calculateDistance(long latFrom, long lonFrom, long
latTo, long lonTo){
165 /*
166 * d=2*asin(sqrt((sin((latFrom-latTo)/2))^2 +
cos(latFrom)*cos(latTo)*(sin((lonFrom-lonTo)/2))^2))
167 * or
168 * d=2*asin(sqrt((sin((latFrom-latTo)/2))^2 +
cos(latFrom)*cos(latTo)*(sin((lonTo-lonFrom)/2))^2))
169 * distance = R*d
170 */
171
172 latFrom = degreesToRadians(latFrom);
173 latTo = degreesToRadians(latTo);
174 lonFrom = degreesToRadians(lonFrom);
175 lonTo = degreesToRadians(lonTo);
176 //long distance = R * MathFP.acos(MathFP.sin(latFrom)*MathFP.sin(latTo)
+ MathFP.cos(latFrom)*MathFP.cos(latTo)*MathFP.cos(lonTo-lonFrom));
177 /*
178 double distance = R * 2 * Math.asin(
179 Math.sqrt(
xxv
26. Zarko Acimovic
180 Math.pow(Math.sin((lat1-lat2)/2), 2)
181 +
182
Math.cos(lat1)*Math.cos(lat2)*Math.pow(Math.sin((lon2-lon1)/2), 2)
183 )
184 );
185 */
186
187 /*
188 System.out.print("latFrom: "+MathFP.toString(latFrom));
189 System.out.println(" lonFrom: "+MathFP.toString(lonFrom));
190 System.out.print("latTo: "+MathFP.toString(latTo));
191 System.out.println(" lonTo: "+MathFP.toString(lonTo));
192 */
193
194 long p1=MathFP.sin(MathFP.div((latFrom-latTo), MathFP_2));
195 p1 = MathFP.mul(p1, MathFP.toFP(1000000));
196 //System.out.println(" p1: "+MathFP.toString(p1));
197 p1 = MathFP.mul(p1, p1);
198 //System.out.println(" p1: "+MathFP.toString(p1));
199
200 long p2=MathFP.sin(MathFP.div((lonTo-lonFrom), MathFP_2));
201 p2 = MathFP.mul(p2, MathFP.toFP(1000000));
202 //System.out.println(" p2: "+MathFP.toString(p2));
203 p2 = MathFP.mul(p2, p2);
204 //System.out.println(" p2: "+MathFP.toString(p2));
205
206 long sqrtarg=p1
+MathFP.mul(MathFP.mul(MathFP.cos(latFrom),MathFP.cos(latTo)),p2);
207 //System.out.println(" sqrtarg: "+MathFP.toString(sqrtarg));
208
209 sqrtarg=MathFP.sqrt(sqrtarg);
210 //System.out.println(" sqrtarg: "+MathFP.toString(sqrtarg));
211
212 long distance;
213 if (sqrtarg>MathFP.toFP(19000)) { //toFP("0.019")*1000000 - boundary
for MathFP.asin approximation by X
214 // calculation is erroneus for small angles
215 long asinarg=MathFP.div(sqrtarg, MathFP.toFP(1000000));
216 //System.out.println(" > asinarg: "+MathFP.toString(asinarg));
217 asinarg=MathFP.asin(asinarg);
218 //System.out.println(" > asinarg: "+MathFP.toString(asinarg));
219 distance = MathFP.mul(EARTH_RADIUS2, asinarg);
220 //System.out.println(" distance asin: "+MathFP.toString(distance));
221 } else {
222 //asin(X) is aproximately equall to X,
223 //This approximation allow us to change the order of multiplication
and division in order to reduce loss of significant digits
224
225 distance = MathFP.mul(EARTH_RADIUS2, sqrtarg);
226 //System.out.println(" > distance: "+MathFP.toString(distance));
xxvi
27. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
227 distance=MathFP.div(distance, MathFP.toFP(1000000));
228
229 }
230
231 //System.out.println(" distance: "+MathFP.toString(distance));
232
233 //if (Double.isNaN(distance)) //equivalent to (distance=0), but safer
234 // return 0;
235 return distance;
236 }
237
238
239 /**
240 * Convert degrees to radians
241 * @return value transformed to radians
242 * @param degrees value to be transformed to radians
243 */
244 public static long degreesToRadians(long degrees){
245 return MathFP.div(degrees,MathFP_180DivPI);
246 }
247
248 /**
249 * Convert radians to degrees
250 * @return value transformed to degrees
251 * @param radians value to be transformed to degrees
252 */
253 public static long radiansToDegrees(long radians){
254 return MathFP.mul(radians,MathFP_180DivPI);
255 }
256
257 public static final long MathFP_2 = MathFP.toFP(2);
258 public static final long MathFP_1 = MathFP.toFP(1);
259 public static final long MathFP_2PI = MathFP.mul(MathFP_2, MathFP.PI);
260 public static final long MathFP_1000 = MathFP.toFP(1000);
261 public static final long MathFP_360 = MathFP.toFP(360);
262 public static final long MathFP_180DivPI = MathFP.div(MathFP.toFP(180),
MathFP.PI);
263 public static final long MathFP_0_5 = MathFP.toFP("0.5");
264
265
266 }
xxvii
29. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
Weighted Method Count (WMC)
Response For a Class (RFC)
Architecture and Structure
Inheritance
Depth of Inheritance Tree (DIT)
Number Of Children (NOC)
Coupling
Afferent Coupling (Ca)
Coupling Between Objects (CBO)
Change Dependency Between Classes (CDBC)
Change Dependency Of Classes (CDOC)
Efferent Coupling (Ce)
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
DelRoute class seems to be perfect
xxix
30. Zarko Acimovic
DelRoute.java class source code
1 /**
2 *
3 * DelRoute is used when deleting route
4 */
5 public class DelRoute {
6 int index;
7 int routeID;
8 DelRoute(int index, int routeID){
9 this.index = index;
10 this.routeID = routeID;
11 }
12 int getIndex(){
13 return index;
14 }
15 int getRouteID(){
16 return routeID;
17 }
18
19 public String toString(){
20 return "ID Route is "+routeID+"n"+"Index of element to
delet is "+index;
21 }
22
23 }
xxx
32. Zarko Acimovic
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
Friend class has problem with Lack of Documentation. Lack Of Documentation Description. How many comments
are lacking in a class, considering one class comment and a comment per method as optimum. Structure and content
of the comments are ignored. http://www.arisa.se/compendium/node121.html
Friend.java source code
1 /**
2 *
3 * Friend class holds all important data for a friend
4 */
5 public class Friend {
6 String name;
7 String resource;
8 int hashThread;
9 Thread4Friend t;
10
11 Friend(String name, String resource, int hashThread, Thread4Friend
t){
xxxii
33. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
12 this.name = name;
13 this.resource = resource;
14 this.hashThread = hashThread;
15 this.t = t;
16 }
17
18 public String getName(){
19 return name;
20 }
21
22 public String getResource(){
23 return resource;
24 }
25
26 public int getHash(){
27 return hashThread;
28 }
29
30 public void setID(int hash){
31 hashThread = hash;
32 }
33
34 public String toString(){
35 return "Friend is "+name+"n"+"Hash is "+hashThread;
36 }
37
38 public void setFirst(){
39 t.setFirst();
40 }
41
42 public boolean getThread(){
43 if (t==null){ return false; }
44 else {return true; }
45 }
46
47 public void setThread(Thread4Friend t){
48 this.t = t;
49 }
50 }
xxxiii
35. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
Response For a Class (RFC)
Architecture and Structure
Inheritance
Depth of Inheritance Tree (DIT)
Number Of Children (NOC)
Coupling
Afferent Coupling (Ca)
Coupling Between Objects (CBO)
Change Dependency Between Classes (CDBC)
Change Dependency Of Classes (CDOC)
Efferent Coupling (Ce)
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
HeapSorter class has problem with LD, TCC and LOD: Lack Of Documentation Description. How many comments
are lacking in a class, considering one class comment and a comment per method as optimum. Structure and content
of the comments are ignored. http://www.arisa.se/compendium/node121.html
xxxv
36. Zarko Acimovic
Tight Class Cohesion Description
The Tight Class Cohesion metric measures the cohesion between the public methods of a class. That is the relative
number of directly connected public methods in the class. Classes having a low cohesion indicate errors in the design.
http://www.arisa.se/compendium/node118.html
HeapSorter.java source code
1 /**
2 *
3 * HeapSorter class sorts points by distance or by name
4 */
5 public class HeapSorter{
6
7 HeapSorter(){}
8
9 public void heapsort(long[] a){
10 long[]A = setHeapWithSize(a,a.length);
11 buildHeap(A);
12 for(int i=0; i<A.length; i++){
13 System.out.println(A[i]);
14 }
15 for(int i=a.length; i>1; i--){
16 a[i-1]=A[0]; A[0]=A[i-1];
17 A=setHeapWithSize(A,A.length-1);
18 heapify(A,1);
19 }
20 a[0]=A[0];
21 }
22
23 public void heapsort(String[] as){
24 String[] AS = setHeapWithSize(as,as.length);
25 buildHeap(AS);
26 for(int i=0; i<AS.length; i++){
27 System.out.println(AS[i]);
28 }
29 for(int i=as.length; i>1; i--){
30 as[i-1]=AS[0]; AS[0]=AS[i-1];
31 AS=setHeapWithSize(AS,AS.length-1);
32 heapify(AS,1);
33 }
34 as[0]=AS[0];
35 }
36
37 public void buildHeap(long[] a){
38 for(int i=a.length/2; i>0; i--) heapify(a,i);
39 }
xxxvi
37. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
40
41 public void buildHeap(String[] as){
42 for(int i=as.length/2; i>0; i--) heapify(as,i);
43 }
44
45 public void heapify(long[]a, int i){
46 int l=left(i);
47 int r=right(i);
48 int largest;
49
50 if(l<=heapSize(a) && a[l-1]>a[i-1]){
51 largest=l;
52 }else{
53 largest=i;
54 }
55
56 if(r<=heapSize(a) && a[r-1]>a[largest-1]){
57 largest=r;
58 }
59
60 if(largest!=i){
61 //exchange a[i], a[largest]
62 long tmp=a[i-1]; a[i-1]=a[largest-1]; a[largest-
1]=tmp;
63 heapify(a,largest);
64 }
65 }
66
67 public void heapify(String[]as, int i){
68 int l=left(i);
69 int r=right(i);
70 int largest;
71
72 if(l<=heapSize(as) && as[l-1].charAt(0)>as[i-1].charAt(0)){
73 largest=l;
74 }else{
75 largest=i;
76 }
77
78 if(r<=heapSize(as) && as[r-1].charAt(0)>as[largest-
1].charAt(0)){
79 largest=r;
80 }
81
82 if(largest!=i){
83 //exchange a[i], a[largest]
84 String tmpS=as[i-1]; as[i-1]=as[largest-1];
as[largest-1]=tmpS;
85 heapify(as,largest);
86 }
87 }
xxxvii
38. Zarko Acimovic
88
89
90 public int heapSize(long a[]){
91 return a.length;
92 }
93
94 public int heapSize(String as[]){
95 return as.length;
96 }
97
98 public int parent(int i){
99 return(i/2);
100 }
101
102 public int left(int i){
103 return(2*i);
104 }
105
106 public int right(int i){
107 return(2*i+1);
108 }
109
110 public long[] setHeapWithSize(long[]m , int n){
111 long[] k = new long[n];
112 for(int i=0; i<n; i++){
113 k[i]=m[i];
114 }
115 return k;
116 }
117
118 public String[] setHeapWithSize(String[]m , int n){
119 String[] k = new String[n];
120 for(int i=0; i<n; i++){
121 k[i]=m[i];
122 }
123 return k;
124 }
125 };
xxxviii
40. Zarko Acimovic
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
ImageCnavas3 lacks documentation. Lack Of Documentation Description. How many comments are lacking in a
class, considering one class comment and a comment per method as optimum. Structure and content of the
comments are ignored. http://www.arisa.se/compendium/node121.html
ImageCanvas3.java source code
1 /**
2 *
3 * ImageCanvas3 draws elements on screen and captures events on canvas
4 */
5
6 //import java.io.IOException;
7 import javax.microedition.lcdui.*;
8 //import java.util.*;
9
10 public class ImageCanvas3 extends Canvas {
11
12 Outlook ol;
13
14 ImageCanvas3(Outlook ol){
15 this.ol =ol;
xl
43. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
Response For a Class (RFC)
Architecture and Structure
Inheritance
Depth of Inheritance Tree (DIT)
Number Of Children (NOC)
Coupling
Afferent Coupling (Ca)
Coupling Between Objects (CBO)
Change Dependency Between Classes (CDBC)
Change Dependency Of Classes (CDOC)
Efferent Coupling (Ce)
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
MapBackground class seems to be well designed class.
MapBacground.java source code
xliii
44. Zarko Acimovic
1 /**
2 *
3 * MapBackground transforms map according to user actions, zoom In, zoom
out or pan
4 */
5 import java.util.*;
6 import java.io.*;
7 import javax.microedition.lcdui.*;
8
9
10 public class MapBackground {
11
12 /** Current JPEG Background of map
13 */
14 private Image img;
15
16 /** Images for Different Zoom Levels;
17 */
18 private Image[] zoomImg = new Image[3];
19
20 private int zoomLevel = 0;
21
22 /** Width of current background image
23 */
24 private long sizeX;
25
26 /** Height of current background image
27 */
28 private long sizeY;
29
30
31 /** Float-point value of upper limit
32 */
33 private long upLat;
34
35 /** Float-point value of lower limit
36 */
37 private long downLat;
38
39 /** Side of upper limit
40 */
41 //private char upNS;
42
43 /** Side of lower limit
44 */
45 //private char downNS;
46
47 /** Float-point value of left limit
xliv
45. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
48 */
49 private long leftLon;
50
51 /** Float-point value of right limit
52 */
53 private long rightLon;
54
55 /** Side of left limit
56 */
57 //private char leftWE;
58
59 /** Side of right limit
60 */
61 ///private char rightWE;
62
63 /** Integer value of latitude degrees of upper limit
64 */
65 private long upDlat;
66
67 /** Integer value of latitude minutes of upper limit
68 */
69 private long upMlat;
70
71 /** Integer value of latitude seconds of upper limit
72 */
73 private long upSlat;
74
75 /** Integer value of latitude degrees of lower limit
76 */
77 private long dwDlat;
78
79 /** Integer value of latitude minutes of lower limit
80 */
81 private long dwMlat;
82
83 /** Integer value of latitude seconds of upper limit
84 */
85 private long dwSlat;
86
87
88 /** Integer value of longitude degrees of left limit
89 */
90 private long lfDlon;
91
92 /** Integer value of longitude minutes of left limit
93 */
94 private long lfMlon;
95
96 /** Integer value of longitude seconds of left limit
97 */
98 private long lfSlon;
xlv
46. Zarko Acimovic
99
100 /** Integer value of longitude degrees of right limit
101 */
102 private long rtDlon;
103
104 /** Integer value of longitude minutes of right limit
105 */
106 private long rtMlon;
107
108 /** Integer value of longitude seconds of right limit
109 */
110 private long rtSlon;
111
112
113 /** Scale of map
114 */
115 private long scale;
116
117 /** Number of lat-seconds per pixel
118 */
119 private long pixLat;
120
121 /** Number of lon-seconds per pixel
122 */
123 private long pixLon;
124
125
126 /** Total number of Latitude seconds for upper limit point
127 */
128 long totLatSec ;
129
130 /** Total number of Longitude seconds for left limit point
131 */
132 long totLonSec ;
133
134 /** new upper left edge due to pan or Zoom;
135 * newEdge represents Point of upper left corner of visible screen
136 */
137 Point newEdge;
138
139 /** new upper left edge due to pan or Zoom;
140 * newEdge represents Point of upper left corner of visible screen
141 */
142 Point previousEdge;
143
144
145 /** World coordinates of Down end of Image
146 */
147 Point downEnd;
148
149 /** Character that represents side of Pan
xlvi
47. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
150 */
151 char sidePan;
152
153 /** x-coordinate of begining of image
154 */
155 long x = 0;
156
157 /** y-coordinate of begining of image
158 */
159 long y = 0;
160
161 /** Indicates beginning of pan range verticaly
162 */
163 boolean reachBeginV = true;
164
165 /** Indicates end of pan range verticaly
166 */
167 boolean reachEndV = false;
168
169 /** Indicates beginning of pan range horizontaly
170 */
171 boolean reachBeginH = true;
172
173 /** Indicates end of pan range horizontaly
174 */
175 boolean reachEndH = false;
176
177 /** Step of panning
178 */
179 long step = 30;
180
181 /** Counter of shifts vertically
182 */
183 long movV=0;
184
185 /** Counter of shifts horizontally
186 */
187 long movH=0;
188
189 /** Name of smallest image
190 */
191 String[] imgArray = new String[3];
192
193 /** Canvas Height
194 */
195 private long canvasHeight;
196
197 /** Canvas Width
198 */
199 private long canvasWidth;
200
xlvii
49. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
249 this.totLatSec =
MathFP.mul(this.upLat,MathFP.toFP("3600"));
250 this.totLonSec =
MathFP.mul(this.leftLon,MathFP.toFP("3600"));
251
252
253 this.setPixels();
254 }
255
256
257
258 /** Returns number of longitude seconds per pixel
259 * @return int
260 *
261 */
262 public long getPixLon(){
263 return pixLon;
264 }
265
266 /** Returns number of latitude seconds per pixel
267 * @return int
268 */
269 public long getPixLat(){
270 return pixLat;
271 }
272
273 /** Sets pixels as Float-Point when main constructor is called
274 * and when Zoom In/Out is applied
275 */
276 public void setPixels(){
277 long pxy1 =
MathFP.mul(MathFP.sub(rightLon,leftLon),MathFP.toFP("3600"));
278 pixLon = MathFP.div(pxy1,MathFP.toFP(sizeX));
279
280 long pxy2 =
MathFP.mul(MathFP.sub(upLat,downLat),MathFP.toFP("3600"));
281 pixLat = MathFP.div(pxy2,MathFP.toFP(sizeY));
282 }
283
284 /** Returns image to draw
285 *
286 * @return Image
287 */
288 public Image getImage(){
289 return img;
290 }
291
292
293 /** Returns total number of seconds for LEFT LONGITUDE
294 * @return int
295 */
xlix
50. Zarko Acimovic
296 public long getLonSec() {
297 return this.totLonSec;
298 }
299
300 /** Returns total number of seconds for UPPER LATITUDE
301 * @return int
302 */
303 public long getLatSec() {
304 return this.totLatSec;
305 }
306
307
308 /** Returns Canvas height
309 *
310 * @return int
311 */
312 public long getCanvasHeight(){
313 return canvasHeight;
314 }
315
316 /** Returns Canvas width
317 *
318 * @return int
319 */
320 public long getCanvasWidth(){
321 return canvasWidth;
322 }
323
324 /** Sets newEdge; new Edge is created every time when user pans or zooms
map ;
325 * newEdge represents Point of upper left corner of visible screen (x=0
and
326 * y=0 for newEdge)
327 *
328 * @return Point
329 */
330 public void setNewEdge(){
331 previousEdge = newEdge;
332
333 long tt1 =
MathFP.mul(this.getPixLat(),MathFP.toFP(Math.abs(this.getY())));
334 long tt2 =
MathFP.mul(this.getPixLon(),MathFP.toFP(Math.abs(this.getX())));
335
336 newEdge = new Point(MathFP.sub(this.getLatSec(),tt1),
337
MathFP.add(this.getLonSec(),tt2),"","",false);
338 }
339
340 /** Returns new edge
341 */
l
51. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
342 public Point getNewEdge(){
343 return newEdge;
344 }
345
346 /** Returns down End
347 */
348 public Point getDownEnd(){
349 return downEnd;
350 }
351
352 /** Returns new Edge as String
353 *
354 * @return String
355 */
356 public String getNEdgeStr(){
357 return newEdge.toString();
358 }
359
360
361 /** Sets map due to Pan transformation
362 *
363 */
364 public void setMap(char side){
365
366 if (side=='u'){
367 if(reachBeginV==false){
368 y+=((this.img.getHeight() - canvasHeight)/step);
369 if(y>0) y=0;
370 movV--;
371 }
372 reachEndV=false;
373 if(movV==0) reachBeginV=true;
374
375 }
376
377 if (side=='d'){
378 if(reachEndV==false){
379 y-=((this.img.getHeight()-canvasHeight)/step);
380 movV++;
381 reachBeginV=false;
382 if(movV==step) reachEndV=true;
383 }
384
385 }
386
387 if (side=='l'){
388 if(reachBeginH==false){
389 x+=((this.img.getWidth()-canvasWidth)/step);
390 if(x>0) x=0;
391 movH--;
392 reachEndH=false;
li
58. Zarko Acimovic
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
Problem with MapBackgroundFactory is Length of class name (LEN).
MapBackgroundFactory.java source code
1 /**
2 *
3 * Different map formats could be implemented and dealt with with
MapBackgroundFactory
4 */
5 public class MapBackgroundFactory {
6
7 MapBackground m;
8
9 /**
10 MapBackgroundFactory(String name0, String name1, String name2,
lviii
60. Zarko Acimovic
Lines of Code (LOC)
Interface Complexity
Number of Attributes and Methods (SIZE2)
Number Of local Methods (NOM)
Structural Complexity
McCabe Cyclomatic Complexity (CC)
Weighted Method Count (WMC)
Response For a Class (RFC)
Architecture and Structure
Inheritance
Depth of Inheritance Tree (DIT)
Number Of Children (NOC)
Coupling
Afferent Coupling (Ca)
Coupling Between Objects (CBO)
Change Dependency Between Classes (CDBC)
Change Dependency Of Classes (CDOC)
Efferent Coupling (Ce)
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
lx
61. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
MapObjects seem to be well designed class.
MapObjects.java source code
1 /**
2 *
3 * MapObjects controls appearance of all map objects on current screen
4 */
5 import java.util.*;
6 //import java.io.*;
7 import javax.microedition.lcdui.*;
8
9 public class MapObjects {
10
11 MapBackground mb;
12 Point currentPosition;
13 Point previousPosition;
14 Point destinationPosition;
15 PVector freeWaypoints;
16 Vector routes;
17 PVector currentRoute;
18 Vector drawablePoints;
19 Hashtable friends;
20 boolean drawLine = false;
21 boolean destSet = false;
22 boolean currentSet = false;
23
24
25
26 MapObjects(MapBackground mb){
27 this.mb = mb;
28 currentPosition = mb.getNewEdge();
29 destinationPosition = mb.getNewEdge();
30 currentPosition.setName("dummy");
31 destinationPosition.setName("dummy");
32 routes = new Vector();
33 friends = new Hashtable();
34 }
lxi
62. Zarko Acimovic
35
36 /** Sets drawable Points for current Screen
37 *
38 */
39 public void setDrawablePoints(){
40 Vector temp1 = new Vector();
41 Vector temp2;
42
43 //check if current and destination are visible
44 if(this.currentPosition.check(mb.getNewEdge(), mb.getDownEnd())) {
45
currentPosition.setXY(mb.getNewEdge(),mb.getPixLon(),mb.getPixLat());
46 temp1.addElement(currentPosition);
47 }
48 if(this.destinationPosition.check(mb.getNewEdge(),
mb.getDownEnd())) {
49
destinationPosition.setXY(mb.getNewEdge(),mb.getPixLon(),mb.getPixLat());
50 temp1.addElement(destinationPosition);
51 }
52
53 //check which free waypoints are visible
54 temp2 = freeWaypoints.getPoints(mb.getNewEdge(),mb.getDownEnd());
55 for (int j=0; j<temp2.size(); j++){
56 Point wp = (Point)temp2.elementAt(j);
57 wp.setXY(mb.getNewEdge(),mb.getPixLon(),mb.getPixLat());
58 temp1.addElement(wp);
59 }
60
61
62 //check which route points are visible
63 for (int i=0; i<routes.size(); i++){
64 PVector v = (PVector)routes.elementAt(i);
65 if (v.getVisible()==true){
66 temp2 =
v.getPoints(mb.getNewEdge(),mb.getDownEnd());
67
68 for (int j=0; j<temp2.size(); j++){
69 Point wp = (Point)temp2.elementAt(j);
70
wp.setXY(mb.getNewEdge(),mb.getPixLon(),mb.getPixLat());
71 temp1.addElement(wp);
72 }
73 }
74 }
75 drawablePoints = temp1;
76 }
77
78 /** Returns drawable Points for current Screen
79 * @return Vector
80 */
lxii
63. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
81 public Vector getDrawablePointsOld(){
82
83 return drawablePoints;
84 }
85
86 public Vector getDrawablePoints(){
87 this.setDrawablePoints();
88 return drawablePoints;
89 }
90
91
92 public void setCurrentPosition(Point wp){
93 previousPosition = currentPosition;
94 currentPosition = wp;
95
currentPosition.setXY(mb.getNewEdge(),mb.getPixLon(),mb.getPixLat());
96 currentSet = true;
97 }
98
99 /** Reset current position
100 */
101 public void resetCurrentPosition(){
102 currentPosition = mb.getNewEdge();
103 drawLine = false;
104 currentSet = false;
105 }
106
107 /** Returns current position
108 * @return Point
109 */
110 public Point getCurrentPosition(){
111 return currentPosition;
112 }
113
114
115 /** Set destination position
116 */
117 public void setDestinationPosition(Point wp){
118 destinationPosition = wp;
119 destSet = true;
120 }
121
122 /** Reset destination position
123 */
124 public void resetDestinationPosition(){
125 destinationPosition = mb.getNewEdge();
126 drawLine = false;
127 destSet = false;
128 }
129
130 /** Returns destination position
lxiii
64. Zarko Acimovic
131 * @return Point
132 */
133 public Point getDestinationPosition(){
134 return destinationPosition;
135 }
136
137 /** Returns all routes
138 */
139 public Vector getRoutes(){
140 return routes;
141 }
142
143 /** Returns free Vector of free Points
144 */
145 public PVector getFreeWaypoints(){
146 return freeWaypoints;
147 }
148
149 /** Draws MapObjects --- OBSOLETED!!!
150 */
151 public void drawMOBold(Graphics g, boolean route){
152 long zl = mb.getZoomLevel()+1;
153 Long zzl = new Long(zl);
154 int zoomL = Integer.parseInt(zzl.toString());
155 this.setDrawablePoints();
156
157 // Drawing of line beetwen destination and current position
158 if(drawLine==true){
159
currentPosition.setXY(mb.getNewEdge(),mb.getPixLon(),mb.getPixLat());
160
destinationPosition.setXY(mb.getNewEdge(),mb.getPixLon(),mb.getPixLat());
161
g.drawLine(currentPosition.getXX(),currentPosition.getYY(),destinationPosition.getX
X(),destinationPosition.getYY());
162 }
163
164 // Drawing of free Points, current position and destination
position
165 for(int i=0; i<drawablePoints.size(); i++){
166 Point wp = (Point)drawablePoints.elementAt(i);
167 if(wp.getImage().equals("blanco")){
168 g.fillRect(wp.getXX(),wp.getYY(),5*zoomL,5*zoomL);
169 g.drawString(wp.getName(),wp.getXX()+5,wp.getYY()
+5,0);
170 } else {
171 Image img = null;
172 try{
173 img =
Image.createImage(wp.getImage());
174 }catch(Exception e){}
lxiv
71. Example Java Project Tested by VizzMaintenance Metrics Eclipse Plugin
Coupling Factor (CF)
Data Abstraction Coupling (DAC)
Instability (I)
Locality of Data (LD)
Message Passing Coupling (MPC)
Package Data Abstraction Coupling (PDAC)
Cohesion
Lack of Cohesion in Methods (LCOM)
Improvement of LCOM (ILCOM)
Tight Class Cohesion (TCC)
Design Guidelines and Code Conventions
Documentation
Lack Of Documentation (LOD)
Code Conventions
MapsMIDlet class has problem with Lines of Code.
Lines of Code Description: Lines of code simply counts the lines of source code (line break characters) of a certain
software entity. It is a simple yet powerful metric to assess the complexity of software entities. Since it is depending on
code conventions and format, it is critical to use it in generated codes since it may lack of line breaks. Additionally it
can only be measured in the source code itself from the front-end and is therefore a front-end side metric.
http://www.arisa.se/compendium/node91.html
Response For a Class Description
Count of (public) methods in a class and methods directly called by these. RFCis only applicable to object-oriented
systems. http://www.arisa.se/compendium/node98.html
Message Passing Coupling Description
The MPC measures the number of method calls defined in methods of a class to methods in other classes, and
therefore the dependency of local methods to methods implemented by other classes. It allows for conclusions on the
message passing (method calls) between objects of the involved classes. This allows for conclusions on re-useability,
maintenance and testing effort. http://www.arisa.se/compendium/node113.html
Weighted Method Count Description
A weighted sum of methods implemented within a class. It is parameterized by a way to compute the weight of each
method. Possible weight metrics are:
McCabe Cyclomatic Complexity 3.1.3,
Lines of Code 3.1.1,
1 (unweighted WMC).
lxxi
72. Zarko Acimovic
This variant of WMC uses McCabe Cyclomatic Complexity 3.1.3 metric for calculating the weight for each method.
Originally defined as an object-oriented metric, it can easily adapted to non-object-oriented systems computing the
weighted sum of functions implemented within a module or file. http://www.arisa.se/compendium/node97.html
MapsMIDlet.java
1 /**
2 *
3 * MapsMIDlet creates control menus due to user's actions and handles GPS
issues
4 *
5 */
6 import javax.microedition.lcdui.*;
7
8 import javax.microedition.midlet.*;
9
10 import java.util.*;
11 import java.io.*;
12
13
14
15
16
17 public class MapsMIDlet extends MIDlet implements CommandListener,Runnable
{
18
19
20 MapBackgroundFactory mbf = new MapBackgroundFactory("/Mali2.png",
"/Srednji.png","/Veliki.png",
21 "44.83049905", "20.44570857", "44.79241639",
"20.48713523");
22
23
24 MapBackground mb;
25 MapObjects mob;
26 SelectorPoint selP;
27 Outlook oul;
28
29 PVector vwpF = new PVector("free",false);
30 ImageCanvas3 ic;
31 CompassCanvas cc;
32
33 //Point wp3 = new
Point("44.81916183","20.45417165","Klub'Akademija'","j","/Cultural_or_Tourist/Event
.png",true);
34 Point wp2 = new Point("44.82990854","20.45661377","25.
maj","j","/Sport/Swimming.png",true);
lxxii