SENG 421: Software Metrics Measuring Internal Product Attributes: Structural Complexity (Chapter 6) Department of Electrical & Computer Engineering, University of Calgary B.H. Far ([email protected]) http://www.enel.ucalgary.ca/People/far/Lectures/SENG421/06/
76
Embed
SENG 421: Software Metrics - University of Calgary in Albertapeople.ucalgary.ca/~far/Lectures/SENG421/PDF/SENG421-06.pdf · SENG 421: Software Metrics Measuring Internal Product Attributes:
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
1: read x,y,z;2: type = “scalene”;3: if (x == y or x == z or y == z) type =“isosceles”;4: if (x == y and x == z) type =“equilateral”;5: if (x >= y+z or y >= x+z or z >= x+y) type =“not a triangle”;6: if (x <= 0 or y <= 0 or z <= 0) type =“bad inputs”;7: print type;
It has something to do with program structure (branches, nesting) & flow of data
Control Flow Graph (CFG) /1 Control flow structure is usually modeled by a directed
graph (di-graph) CFG = {N, A}
Each node n in the set of nodes (N) corresponds to a program statement.
Each directed arc (or directed edge) a in the set of arcs (A) indicates flow of control from one statement of program to another. Procedure nodes: nodes with out-degree 1. Predicate nodes: nodes with out-degree other than 1 and 0. Start node: nodes with in-degree 0. Terminal (end) nodes: nodes with out-degree 0.
Control Flow Graph (CFG) /2Definition [FeR97]: A flowgraph is a directed graph
in which two nodes, the start node and the stop node, obey special properties: the stop node has out-degree zero, and the start node has in-degree zero. Every node lies on some path from the start node to the stop node.
A family S of prime flowgraphs is called S-structured graph (or S-graph) if it satisfies the following recursive rules:
1) Each member of S is S-structured.2) If F and G are S-structured flowgraphs, so is
the sequences F;G and nesting of F(G).3) No flowgraph is S-structured unless it can be
generated by finite number of application of the above (step 2) rules.
S-Structured Graph – Example SD = {P1, D0, D2} The class of SD-graphs is the class of flow graphs that is
called D-structured (or simply: structured) in the Structured Programming literature
Böhm and Jacopini (1966) have shown that every algorithm can be encoded as an SD-graph (i.e., as a sequence or nesting of statements, if-conditions and while-loops)
Although SD is sufficient in this respect, normally if-then-else structures (D1) and repeat-loops (D3) are included in SD.
Prime Decomposition Any flow graph can be uniquely decomposed into a hierarchy
of sequencing and nesting primes, called “decomposition tree”. (Fenton and Whitty, 1991)
Cyclomatic Complexity /2 For a program with the program flowgraph G, the
cyclomatic complexity v(G) is measured as:v(G) = 1 + d
d : number of predicate nodes (i.e., nodes with out-degree other than 1) d represents number of loops in the graph or number of decision points in the program
i.e., The complexity of primes depends only on the predicates (decision points or BCSs) in them.
01. import java.util.*;02. public class CalendarTest03. {04. public static void main(String[] args)05. {06. // construct d as current date07. GregorianCalendar d = new GregorianCalendar();08. int today = d.get(Calendar.DAY_OF_MONTH);09. int month = d.get(Calendar.MONTH);10. // set d to start date of the month11. d.set(Calendar.DAY_OF_MONTH, 1);12. int weekday = d.get(Calendar.DAY_OF_WEEK);13. // print heading14. System.out.println("Sun Mon Tue Wed Thu Fri Sat");15. // indent first line of calendar16. for (int i = Calendar.SUNDAY; i < weekday; i++ )17. System.out.print(" ");18. do19. {20. // print day21. int day = d.get(Calendar.DAY_OF_MONTH);22. if (day < 10) System.out.print(" ");23. System.out.print(day);24. // mark current day with *25. if (day == today)26. System.out.print("* ");27. else28. System.out.print(" ");29. // start a new line after every Saturday30. if (weekday == Calendar.SATURDAY)31. System.out.println();32. // advance d to the next day33. d.add(Calendar.DAY_OF_MONTH, 1);34. weekday = d.get(Calendar.DAY_OF_WEEK);35. }36. while (d.get(Calendar.MONTH) == month);37. // the loop exits when d is day 1 of the next month38. // print final end of line if necessary39. if (weekday != Calendar.SUNDAY)40. System.out.println();41. }42. }
01. import java.util.*;02. public class CalendarTest03. {04. public static void main(String[] args)05. {06. // construct d as current date07. GregorianCalendar d = new GregorianCalendar();08. int today = d.get(Calendar.DAY_OF_MONTH);09. int month = d.get(Calendar.MONTH);10. // set d to start date of the month11. d.set(Calendar.DAY_OF_MONTH, 1);12. int weekday = d.get(Calendar.DAY_OF_WEEK);13. // print heading14. System.out.println("Sun Mon Tue Wed Thu Fri Sat");15. // indent first line of calendar16. for (int i = Calendar.SUNDAY; i < weekday; i++ )17. System.out.print(" ");18. do19. {20. // print day21. int day = d.get(Calendar.DAY_OF_MONTH);22. if (day < 10) System.out.print(" ");23. System.out.print(day);24. // mark current day with *25. if (day == today)26. System.out.print("* ");27. else28. System.out.print(" ");29. // start a new line after every Saturday30. if (weekday == Calendar.SATURDAY)31. System.out.println();32. // advance d to the next day33. d.add(Calendar.DAY_OF_MONTH, 1);34. weekday = d.get(Calendar.DAY_OF_WEEK);35. }36. while (d.get(Calendar.MONTH) == month);37. // the loop exits when d is day 1 of the next month38. // print final end of line if necessary39. if (weekday != Calendar.SUNDAY)40. System.out.println();41. }42. }
v = 1+d v = 1+6 = 7
Example 2
Determine cyclomaticcomplexity for the following flow diagram:
There is always a trade-off between control-flow and data structure. Programs with higher cyclomaticcomplexity usually have less complex data structure. Apparently program B requires more effort that program A.
Morphology Morphology refers to the overall shape of the
software system architecture. It is characterized by:
Size: number of nodes and edges Depth: longest path from the root to a leaf node Width: number of nodes at any level Edge-to-node ratio: connectivity density
Cohesion describes how strongly related the responsibilities between design elements can be described
The goal is to achieve “high cohesion” High cohesion between classes is when class
responsibilities are highly related
Presenter
Presentation Notes
Cohesion refers to how closely the responsibilities between design elements (packages, classes, etc.) are related. Perfectly cohesive classes perform one responsibility where a class that does more than one thing performs more than one responsibility. Remember, a class should do one thing, and do one thing well. There are many types of cohesion: Functional cohesion is the strongest and best type of cohesion. This occurs when a class (or package) does one thing, and only one thing, very well. Sequential cohesion occurs when a class or package contain responsibilities that must be performed in a specific order, that share data from step-to-step, and that don’t make up the complete functionality when done together. Communicational cohesion is when classes use the same data and aren’t related in any other way. An example would be if a Student class and a Dormitory class were to both share the data from an Address class and there is no other relationship between the two classes. Temporal cohesion is when classes are all combined together because their responsibilities are all performed at the same time. An example would be if a number of classes were required to execute simultaneously when an application is opened.
Low class cohesion(coincidental and logical cohesion)
PackageA
Class A1CourseOfferingSchedule
Student
1
0..*0..*
0..4
Presenter
Presentation Notes
These graphics demonstrate cohesion in both a package and a class. The diagram on the left demonstrates high cohesion within a package. High cohesion is preferable to low cohesion. The reason that the package has high cohesion is that all the classes that are encapsulated by the package are functionally related to one another. These classes have high cohesion based on their relationships and functionally in that all are usually used together to execute functionality in a use case. The diagram on the right demonstrates a class with low cohesion. The reason that this class has low cohesion is because it has disparate responsibilities. Rather than focusing on only supplying course responsibilities, this class is also responsible for creating and deleting schedules. Any time a class does not do one thing, and one thing well, there is a danger of lower class cohesion.
Coupling describes how strongly one element relates to another element
The goal is to achieve “loose coupling” Loose coupling between classes is small,
direct, visible, and has flexible relations with other classes
Presenter
Presentation Notes
Coupling refers to the degree of strength or a relationship between two design elements (for example, packages, classes, objects, etc.). The goal of coupling is to achieve loose coupling. Loose coupling allows the designer to create relationships between design elements that are small, direct, visible, and flexible. A real-world example of coupling is found between model railroad cars. In order to connect two model railroad cars, all one has to do is push the two cars together and the plastic latches between the cars automatically hook together. This creates a bond between the two cars that permits the model railroader to easily couple two cars together, and just as important, to allow the model railroader to easily separate the two cars. This same principle applies in visual modeling. The connections between classes, for example, should be as simple as possible.
Coupling: Package Dependencies Packages should not be
cross-coupled Packages in lower
layers should not be dependent upon packages in upper layers
In general, dependencies should not skip layers (unless specified by the architecture)
A BXUpper Layer
Lower Layer
C
X
X = Coupling violation
Presenter
Presentation Notes
Package coupling is good and bad: good, because coupling represent re-use, and bad, because coupling represents dependencies that make the system harder to change and evolve. Some general principles can be followed: Packages should not be cross-coupled (that is, co-dependent): two packages should not be dependent on one another. In these cases, the packages need to be reorganized to remove the cross-dependencies. Packages in lower layers should not be dependent upon packages in upper layers. Packages should only be dependent upon packages in the same layer and in the next lower layer. In these cases, the functionality needs to be repartitioned. One solution is to state the dependencies in terms of interfaces and organize the interfaces in the lower layer. In general, dependencies should not skip layers, unless the dependent behavior is common across all layers, and the alternative is to simply pass through operation invocations across layers. Packages should not depend on subsystems, only on other packages or interfaces. You can determine your package relationships by looking at the relationships between the classes that are part of each package. The class relationships should reflect the package relationships that are defined in the relaxed layers architectural pattern that this project is following.
Coupling between packages should be kept as loose as possible. The diagram on the left demonstrates strong coupling between packages. It would be very difficult to reuse Package A because its coupling to Package B is so strong. There are four different class relationships between Package A and Package B. Each one of these class relationships would need to be addressed if there was a goal to separate the two packages. The diagram on the right demonstrates a very loose coupling between the two packages. There is a relationship between the two packages, and it would be much easier to disconnect the relationship between the two packages because there is only one class relationship that is coupling the packages together. The coupling between the two packages on the right provide much more flexibility in the system design.
Coupling /1 Coupling is the degree of interdependence among
modules Various types of coupling (5 types):
R0: independence: modules have no communication R1: data coupling: modules communicate by parameters R2: stamp coupling: modules accept the same record type R3: control coupling: x passes the parameters to y and the
parameter passed is a flag to control the behaviour of y. R4: content coupling: x refers to inside of y; branches into
Coupling: Representation /2 Global coupling of a system consists of modules is the
median value of the set of all couplings c(x,y)
Statistical review: Median value: The median value is a measure of central tendency.
The median value is the middle value in a set of values. Half of all values are smaller than the median value and half are larger. When the data set contains an odd (uneven) set of numbers, the middle value is the median value. When the data set contains an even set of numbers, the middle two numbers are added and the sum is divided by two. That number is the median value.
Revision of the Henry-Kafura IFC measure: Recursive module calls should be treated as normal calls. Any variable shared by two or more modules should be
treated as a global data structure. Compiler and library modules should be ignored. Indirect flow’s should be ignored. Duplicate flows should be ignored. Module length should be disregarded, as it is a separate
There is always a trade-off between control-flow and data structure. Programs with higher cyclomaticcomplexity usually have less complex data structure. Apparently program B requires more effort that program A.