Light overview of how we can tackle complexity using existing tools and frameworks. Talk given at Blip University in September 2013 for all interested devs.
is at the essence of the problem. 2. "Accidental" complexity which covers the work that does not really have much to do with the problem at hand but needs doing anyway 3. “Unnecessary” complexity which is just noise. Unnecessary
that maintenance typically consumes 40 to 80% (60% average) of software costs, and then that enhancement is responsible for roughly 60% of software maintenance costs, while error correction is about 17%... Robert Glass, Frequently Forgotten Fundamental Facts about Software Engineering, 2001
system does not lie in the code itself. The hard part is maintaining it. Anyone can give orders to a computer. Not everyone is able to do so while being explicit about his/hers intentions.
It is a function of code branching complexity. Boils down to a number. The higher that number, the worst. It’s not additive, i.e., inner function calls do not affect the outcome. It has been correlated with low reliability and frequent errors
worst; McCabe himself defined M <= 10 OK 10 < M <= 15 ~OK Please justify M > 15 NOK Other standards say Define your rule and follow it 1-10 OK 11-20 ~OK; Justify please 21-50 NOK 51+ NOK; Untestable
keep track of the complexity of the modules they are developing, and split them into smaller modules whenever the cyclomatic complexity of the module exceeded 10.” Tom McCabe
# of white box tests that need to be run in order to obtain sufficient coverage of the module. More tests may be necessary because of path coverage. branch coverage <= cyclomatic complexity <= # paths May help code conciseness by limiting the size of an imperative module.
McCabe’s metric was used on one 77.000 line program to identify problem areas. The program had a post- release defect rate of 0.31 defects per thousand lines of code. A 125.000 line program has had a 0.02 defects per thousand lines of code – William T. Ward, Hewlett Packard Similar results were observed in countless other companies such as Steve McConnel’s Construx Software.
metrics Number of classes and interfaces Classes, Pure abstract classes, abstract classes Afferent Couplings / Ca (Package responsibility) Number of packages that depend on classes within a package (inwards) Efferent Couplings / Ce (Package independence) Number of packages the classes within a package depend upon (outwards) Abstracteness Ratio of the packages abstracteness. 0 < A < 1. Instability (resiliency to change) I = Ce / (Ce + Ca) 0 < I < 1.
metrics Distance from the Main Sequence (balance between abstractness and stability) D = A+I, 0 < D < 1 D=0 indicating a package that is coincident with the main sequence D=1 indicating a package that is as far from the main sequence as possible Ideal packages are either completely abstract and stable (x=0, y=1) or completely concrete and unstable (x=1, y=0) 1 1 0
Code coverage; Cohesion degree to which the elements of a module belong together Coupling Cohesion counterpart; High cohesion may mean low coupling and vice-versa. Program execution time Nesting levels in control constructs Variable span (number of lines between successive references to variables) Variable lifetime (number of lines a variable is in use) Others (use tools such as sonar, fortify, etc…)
Describes the limiting behavior of a function when the argument tends to a particular value or infinity; Used to classify algorithms – time & space - by how they respond to input size;
as O(x); Describes the limiting behavior of a function when the argument tends to a particular value or infinity; Used to classify algorithms – time & space - by how they respond to input size; It’s about the worst-case scenario of an algorithm; Ω(x) (Big Omega), Θ(x) (Big Theta) also exist and offer different measures.
not affect the complexity; Example: Given a binary representation of a number say if it is even or odd If rightmost bit is one then the number is odd; even otherwise No matter how many bits the number representation has we only need to look at the first bit (right to left). 0111101011010100100101 0111101011010100100100
numbers Line the numbers up (to the right) Add the digits in a column writing the last number of that addition in the result; The 'tens' part of that number is carried over to the next column. If we add two 100 digit numbers together we have to do 100 additions. If we add two 10,000 digit numbers we have to do 10,000 additions. See the pattern? 1234 + 5678 6912
Book Given a person's name, find the phone number by picking a random point about halfway through the part of the book you haven't searched yet Check to see whether the person's name is at that point Repeat the process about halfway through the part of the book where the person's name lies. you can simply divide-and-conquer, and you only need to explore a tiny fraction of the entire space before you eventually find someone's phone number. A bigger phone book will still take you a longer time, but it won't grow as quickly as the proportional increase in the additional size. See the pattern? (also you could just the internet)
numbers Line the numbers up (to the right) take the first digit in the bottom number and multiply it in turn against each digit in the top number; and so on through each digit For 4 digit number we need to do 16 multiplications (and 7 adds). For 100 digit numbers we need to do 10.000 multiplications and 200 adds. See the pattern? Should it be O(n2 + 2n)? 1234 x 5678 9872 86380 740400 + 6170000 7006652
salesman You have N towns Each of those towns is linked to 1 or more other towns by a road of a certain distance find the shortest tour that visits every town
A, B & C A → B → C A → C → B B → C → A B → A → C C → A → B C → B → A There are 3 equivalents: A-B-C:C-B-A, A-C-B:B-C-A, B-A-C:C-A-B; So there are 3 possibilities Take this to 4 towns and you have 12 possibilities. With 5 it's 60. 6 becomes 360. See the pattern?
to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do. Donald Knuth – Literate Programming, Centre for the Study of Language & Information, 1992
Is the reason for creating a new routine/class sufficient? Have all the parts of the routine/class that would benefit from being put into routines/classes of their own been put into routines/classes of their own? Does the name describe everything the routine/class does? Does the routine/class have strong, functional cohesion – doing one and only one thing and doing it well? Do the routine/class have loose coupling – are the routine/ class connections to other routines/classes small, intimate, visible and flexible? Is the length of the routine determined naturally by its function and logic rather than by an artificial coding standard?
Does the routine have 5 or fewer parameters? Is each input parameter used? Is each output parameter used? Does the routine avoid using input parameters as working variables? If the routine is a function does it return a valid value under all possible circumstances? Does the routine parameter list, taken as a whole, present a consistent interface abstraction?
Does the routine protect itself from bad input data? Have you used assertions to document assumptions, including pre-conditions and post-conditions? Check out Eiffel’s invariants; Java has support at some extent also Have assertions been used only to document conditions that should never occur?
Have debugging aids been installed in such a way that they can be activated /deactivated without a great deal of fuss? Is the amount of defensive programming code appropriate – neither to much nor too little? Have you used offensive programming techniques to make errors difficult to overlook during development? Make sure asserts abort the program Be sure the code in each case statement’s default or else clause fails hard or is otherwise impossible to overlook
“Don't be afraid to show your code ™” You are not one in a million. And if you were there would be 10 like you in Portugal alone. Think about this. A pervasive elitism hovers in the background of collaborative software development: everyone secretly wants to be seen as a genius. How to avoid this trap and gracefully exchange personal ego for personal growth and super-charged collaboration. http://www.youtube.com/watch?v=0SARbwvhupQ
them Knowledge sharing – functional and business. Engage with your peers. Learn from others – be open minded. Criticize and be criticized But being polite and respectful doing both Be like water my friend – Bruce Lee