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.

Exam Focus Software design ensures maintainability and scalability. Key goals include simplicity, clarity, and adaptability. 70% of breaches result from poor design (OWASP, 2023).

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.

Key Principle Design principles guide development to reduce technical debt and ensure robustness and quality in software (Beck, 2003).

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.

Resource For more anti-patterns, see: bariscimen.medium.com/10-most-common-anti-patterns-every-software-engineer-must-avoid

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.

Standards JavaScript follows ECMAScript standard. Python follows PEP 8 (style) and PEP 20 (The Zen of Python). These define best practices for each language.

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

VLE Page

Course management and resources.

Link