COMP2511
🎨 7.1 - The Unknown
In this lecture
- The unknown; types of unknowns
-
The role of the unknown in Software Engineering
- The role of the unknown in developing new software
- The role of the unknown in working with existing software
- Software Longevity
- Collaborative Engineering
A brief step back - what makes good software?
The Unknown
- Two types of hard problems:
- Easy to understand, hard to solve
- Hard to understand, easy to solve
-
Two types of unknowns
-
Known unknowns - we know that it exists, but we don't know what it is
-
Unknown unknowns - that which we had never even thought to consider
-
- Learn to deal with unknowns gracefully as they arise
I: The Role of The Unknown in Developing New Software
The Software Development Lifecycle
Traditional Engineering: The Big Design Up Front
- One step at a time
- Ensure the current step is perfect before moving onto the next one
- A big design up front
- Project can take months-years to complete
Difficulties Presented by the Unknown
-
The game changes
- Changing market
- Changing client expectations
- Changing technical world
- Evolution of Requirements
- Too many unknown unknowns to be able to design everything up-front
- There comes a need to learn through experience and iterate on design
Iterative Design
- Work in sprints, iterations, milestones
- 'Agile' software development
- Many variants - eXtreme programming, Rapid Application Development, Kanban, Scrum
-
Design incrementally
- Adapt to changes in requirements
- Discover and deal with problems in design as they arise
Problems with Purely Iterative Design
- No clear sense of direction/trajectory
- In poorly designed systems, adaptations to new requirements become smaller-scale 'workarounds' - limit functionality/decrease maintainability
- Tendency to 'make it up as we go along'
- "The only thing worse than a big design up front is no design up front"
A solution?
-
High Level Design
- Design a broad overview up-front
- A framework to begin development
- Set the trajectory and boundaries of work at the start
- Adapt and change the design during development as needed
- Design up-front a solution that is open for extension, reusable, etc.
- Complete work in small increments and improve iteratively
Requirements Engineering
- As systems grow in size and complexity, so do their requirements
-
Requirements become harder to:
- Communicate, on the side of the client;
- Understand, on the side of the engineer
- Domains are often highly specific, nuanced and complex
- Requirements Analysis might be better termed Engineering
- The problem space grows around us with our understanding
- Transformation of the unknown into the known
- Often, this requires us to dive into the deep end and start actualising solutions in order to better understand what the problem is
- We have to make assumptions to limit the contract to which we program
II: The Role of The Unknown in Working with Existing Software
Now, and Later
- What about later?
- 5 weeks, 5 months, 5 years... 15 years?
- What happens when code grows and systems get bigger?
Complexity
- Code becomes more complex as it grows in size
- Cyclomatic complexity
-
More complexity leads to:
- More scope for errors to creep in;
- Higher risk of software breaking;
- More unknown unknowns
- Too many possible combinations to predict up-front
Software Becomes a Beast
- When software reaches a certain level of complexity, it becomes alive, and constantly moving
- We can no longer informally reason about it with certainty; behaviour can become unpredictable
- Changes in one class/package have far-reaching unpredictable effects due to coupling
- Testing becomes essential here
-
Monolith Repositories
- Large applications, with all the code inside a single repository
- Slower build and Continuous Integration times
- More inertia - harder to ship new features
- More incidents, bugs and defects due to mathematical complexity
- Industry is moving towards microservice architecture
Technical Debt & Trade-offs
- In large-scale software systems, the design decisions you make today will have consequences for years to come.
- Every design decision comes with a cost (termed "technical debt")
- This cost must later be paid back in the form of maintenance, refactoring, or rewriting
- Design decisions are often a matter of picking the deal that is least-worst in the long run - no easy way out
- Opportunity cost - pick one or the other
- All software architecture and design consists of making trade-offs
How to deal with the unknown here?
- Code Hygiene - take care of your code, and your code will take care of you
- Rigorous testing is essential
-
A Symbiotic Relationship between Product and Engineering
- Sacrifice time spent shipping new features now to maintain software hygiene, meaning we can still ship new features later
- Slower today, faster forever
Software Longevity
-
Difficult challenges:
- Dealing with code that you wrote weeks, months or years ago
- Dealing with code that other people wrote weeks, months and years ago
- In large-scale software systems, many software components are treated as black-boxes since the original author is no longer present and no one understands how it works!
- Can often be a tendency to completely migrate (move) systems rather than maintaining or decomposing existing legacy infrastructure
- Software has a very fast turnover compared to other forms of engineering
Longevity and the Open-Closed Principle
- There can be a tendency to build around existing software rather than going in and making changes
- In some philosophical respects, this is the open-closed principle
- The band-aid problem
Parting Thoughts on Longevity
- Mark of well-written code:
- It remains intact for a long time
- And new engineers are able to onboard and understand how it functions
- Bugs lying dormant - Human tendency to ignore that which we do not immediately understand or must analyse - leads to problems in legacy codebases remaining unchecked before surfacing
Collaborative Engineering
- Pair assignment - dealing with the unknown together
- Bounce ideas off one another
- Review each others' work - design reviews, test reviews, code reviews
- Pair programming
- One person codes, one person watches
COMP2511 23T2 - 7.1 - The Unknown
By npatrikeos
COMP2511 23T2 - 7.1 - The Unknown
- 2,124