COMP1531
🐶Software Engineering
9.1 - Design - Software Complexity
Author: Hayden Smith 2021
In this lecture
Why?
- We need a constructive way to be able to understand and have conversations about how complex software is
What?
- Accidental V Essential Complexity
- Cyclomatic Complexity Measurements
What is software complexity?
No Silver Bullet
-
A famous paper from 1986:
- No Silver Bullet – Essence and Accident in Software Engineering by Fred Brooks
- Described software complexity by dividing it into two categories essential and accidental.
- Further conclusions of the paper are much debated
Essential
Complexity that is inherent to the problem.
For example, if the user or client requires the program to do 30 different things, then those 30 things are essential
Accidental
Complexity that is not inherent to the problem.
For example, generating or parsing data in specific formats.
Essential
Fundamentally can't be removed, but can be managed with good software design.
Accidental
Can be somewhat mitigated by engineering decisions; e.g. smart use of libraries, standards, etc.
Hard to remove entirely.
Open questions
- Is there a concrete process for distinguishing accidental and essential complexity?
- How much of the complexity of modern software is accidental?
- To what degree has or will accidental complexity be removed in future?
Can we look at some code examples to analyse?
Further reading
- The original No Silver Bullet paper:
- A more modern description:
- A recent rebuttal:
How can we measure software complexity?
Coupling
- A measure of how closely connected different software components are
- Usually expressed as a simple ordinal measure of "loose" or "tight"
- For example, web applications tend to have a frontend that is loosely coupled from the backend
- Loose coupling is good
Cohesion
- The degree to which elements of a module belong together
- Elements belong together if they're somehow related
- Usually expressed as a simple ordinal measure of "low" or "high"
- High cohesion is good
- Read more here
Cyclomatic complexity
- A measure of the branching complexity of functions
- Computed by counting the number of linearly-independent paths through a function
Cyclomatic complexity
-
To compute:
- Convert function into a control flow graph
- Calculate the value of the formula
where e is the number of edges and n is the number of nodes
V(G) = e - n + 2
Example 1
def foo():
if A():
B()
else:
C()
D()
A
B
C
D
V(G) = 4 - 4 + 2 = 2
Example 2
def foo():
if A():
B()
else:
if C():
D()
E()
A
B
C
E
V(G) = 6 - 5 + 2 = 3
D
Example 3
def foo():
while A():
B()
C()
A
B
C
V(G) = 3 - 3 + 2 = 2
Example 4
def day_to_year(days):
year = 1970
while days > 365:
if is_leap_year(year):
if days > 366:
days -= 366
year += 1
else:
days -= 365
year += 1
return year
V(G) = 8 - 6 + 2 = 4
Example 5
def day_to_year(days):
year = 1970
while days > 0:
if is_leap_year(year):
days -= 366
else:
days -= 365
year += 1
return year - 1
V(G) = 7 - 6 + 2 = 3
Usage
- A simple understandable measure of function complexity
- Some people argue 10 should be the maximum cyclomatic complexity of a function where others argue for 8
Drawbacks
- Assumes non-branching statements have no complexity
- Keeping cyclomatic complexity low encourages splitting functions up, regardless of whether that really makes the code more understandable
Automatic calculation
- http://pylint.pycqa.org/en/latest/technical_reference/extensions.html#design-checker
- NOTE: May get different results compared to doing it by hand as the extension generates a more complex CFG
Feedback
COMP1531 21T3 - 9.1 - SDLC Design - Software Complexity
By haydensmith
COMP1531 21T3 - 9.1 - SDLC Design - Software Complexity
- 1,350