Lecture 9: Comprehensive Revision
Overview
This comprehensive revision lecture consolidates key software design concepts covered throughout the module. We revisit SOLID principles with deeper examples, explore common anti-patterns to avoid, learn refactoring techniques, and get hands-on with Unix command-line tools and code quality utilities. This is essential preparation for exam revision.
Lecture Material - Part 1 (PDF)
Lecture Material - Part 2 (PDF)
SOLID Principles Revisited
The SOLID principles are core design principles for maintainable, flexible code. Understanding these deeply with practical analogies helps apply them correctly in real projects.
Single Responsibility (SRP)
Each class or module has one responsibility and one reason to change. Analogy: A chef doesn't also clean the dining area. Keep Logger and OrderProcessor separate.
Open-Closed (OCP)
Modules should be extendable without modification. Analogy: Adding a new feature to a phone without altering its existing hardware. Add new shapes without changing existing code.
Liskov Substitution (LSP)
Derived classes should work as substitutes for base classes without altering behaviour. Analogy: Electric cars can replace fuel cars in a garage - both are vehicles.
Interface Segregation (ISP)
Avoid forcing classes to implement unused interfaces. Break large interfaces into smaller, specific ones. Separate Printable and Scannable for devices.
Dependency Inversion (DIP)
High-level modules depend on abstractions, not details. Analogy: Using an adapter to plug devices into different outlets. PaymentService relies on PaymentProcessor interface.
DRY & Modularization
The Don't Repeat Yourself principle and modular design are fundamental to maintainable code. Centralizing logic reduces bugs and improves clarity.
Don't Repeat Yourself (DRY)
Avoid redundancy to improve maintainability. 60% of bugs stem from repetitive code (Larman, 2004). Centralize logic in functions or modules.
Applying DRY
Use templates for repeated structures. Parameterize queries in database code instead of string concatenation. Standardize tools across teams.
Modularization
Break systems into independent, cohesive modules. Example: Separate billing, inventory, and user management into distinct modules.
Encapsulation
Restrict access to internal module details using private methods in classes. Hide implementation complexity from consumers.
Abstraction
Simplify complex details behind simple interfaces. A print() function abstracts all the printer driver complexity.
Anti-Patterns to Avoid
Anti-patterns are recurring solutions that often cause more problems than they solve. Recognizing these helps you avoid common pitfalls in software design.
God Object
A class that knows too much or does too much. It violates SRP and becomes a maintenance nightmare. Solution: Refactor into smaller, focused classes.
Spaghetti Code
Unstructured and difficult-to-read code with tangled control flows. Solution: Modularize code and use clear, structured control flows.
Copy-Paste Programming
Duplicating code instead of abstracting common functionality. Violates DRY and makes maintenance difficult across copies.
Magic Numbers
Using unexplained numeric literals in code. Solution: Use named constants that explain what the number represents.
Refactoring Techniques
Refactoring improves the structure of code without changing its behaviour. 70% of developers refactor to reduce bugs (Fowler, 2018).
Rename Variables
Use clear, descriptive names that explain purpose. Good names eliminate the need for comments explaining what something does.
Extract Methods
Remove duplication by extracting repeated code into reusable functions. Makes code more readable and testable.
Replace Conditionals with Polymorphism
Instead of switch statements for types, define a class for each type (rectangle, circle) with embedded logic. Easier to maintain.
Parameterize Queries
Replace string concatenation with parameterized queries. Instead of f-strings with user input, use ? placeholders for safety and reuse.
Unix Fundamentals
Command-line skills are essential for working on remote servers. These commands help you navigate, manipulate files, and manage processes without a GUI.
Navigation Commands
ls (list files), cd (change directory), pwd (print working directory), mkdir (create directory). Use ls -l for detailed info.
File Operations
cp (copy), mv (move/rename), rm (remove - be careful with rm -rf!), nano (text editor). Create files with nano filename.txt.
Text Processing
grep (search patterns), awk (extract data columns), sed (text transformations). Use pipes (|) to chain commands together.
Finding Files
find . -name '*.js' -mtime -7 locates all .js files modified in the last week. Crucial when you don't have version control.
Process Management
ps (list processes), kill (terminate by ID). Use ps aux | grep 'process_name' to find specific process IDs.
I/O Redirection
Use | to pipe output between commands. cat file1 file2 | grep 'error' | wc -l counts error occurrences across files.
Code Quality Tools
Automated formatting and linting tools ensure consistent, high-quality code. They catch errors early and enforce coding standards across teams.
Prettier (JavaScript)
Automatic code formatter. Install: npm install -g prettier. Format: prettier --write my_code.js. Web alternative: prettier.io/playground
Black (Python)
Opinionated Python formatter. Install: pip install black. Format: black my_code.py. Ensures consistent style automatically.
ESLint (JavaScript)
JavaScript linter following ECMAScript standards. Install: npm install -g eslint. Lint: eslint my_code.js. Identifies code issues.
Pylint (Python)
Python linter following PEP 8 guidelines. Install: pip install pylint. Lint: pylint my_code.py. Rates code quality with a score.
Labs & Practical Exercises
Work through hands-on Unix command-line exercises and code quality tool usage. SSH into remote servers and practise essential developer skills.
Section 1: Unix Fundamentals
SSH into Igor, create files with nano, practise ls/cd/pwd/mkdir/rm/cp/mv commands, I/O redirection, piping, and finding files.
Section 2: Code Optimization
Use Prettier and Black to format JavaScript and Python code. Observe how automatic formatting improves readability.
Section 3: Linting
Use ESLint and Pylint to analyse code. Identify issues they highlight and understand how to fix them according to language standards.
Tools & Further Reading
VLE Page
Course management and resources.