Software Engineering Design

Module aims

The module is designed to equip you with tools and techniques to reliably design and evolve larger software systems. The course will look at principles of software design, where to apply them, and how they may inform design choices, addressing common problems with recognised design solutions. It will also cover techniques for ensuring that systems we build behave correctly. The course introduces Java - one of the most widespread programming languages in the industry today - and uses this language and supporting tools for all examples and exercises.

More specifically, you will:
* Gain familiarity with the core Java language, and implementing OO designs in Java.
* Gain familiarity with key Java library classes and tools in order to be a productive Java programmer.
* Practise the technique of Test-Driven Design to ensure behavioural correctness.
* Practise refactoring to improve software structure according to design principles.
* Be able to select and apply popular Design Patterns as solutions to common design problems.
* Learn to make reasoned design choices based on trade-offs and principles.           

Learning outcomes

After completing this module, you should be able to:
* write both imperative and object-oriented code in Java for software design
* apply Test-Driven Development to guide design and check behavioural correctness
* use mock object tests to verify interactions between collaborators in a Tell Don’t Ask style
* select and implement appropriate design patterns to reduce duplication, allow for extension, and manage object creation
* apply dependency inversion and testing to work effectively with legacy code
* build interactive applications for desktop or the web following common architectural styles           

Module syllabus

# Core Java language and ecosystem
* Basic syntax, tooling (IntelliJ), writing and running simple imperative programs
* General good Java style
* Java Standard Library

# Object oriented design and implementation in Java
* Classes and interfaces
* Overriding and overloading, use of final

# Making use of core libraries
* standard Java collections
* Java Generics
* Exceptions, exception handling and custom exceptions

# Test-Driven Development and Refactoring
* The TDD cycle (red/green/refactor) - using JUnit
* Relationship between refactoring and automated testing
* Tooling to support automated refactoring

# Testing with Mock Objects
* Mock-Object TDD (and relation to sequence diagrams)
* Working with Legacy Code

# Re-use and Extensibility
* the open/closed principle
* Design Patterns (based on Alexandrian patterns)
* template method pattern, strategy pattern, trade-offs examined
* Code Quality Metrics - complexity, cloning, turbulence

# Interactive (GUI) applications
* MVC and PAC
* Web Applications

# System Integration
* Ports and Adapters / Hexagonal Architecture
* Unit / Integration / System testing

Teaching methods

Weekly rhythm of :

Prerecorded video lecture providing new content

Short (intended ~3hr) coursework exercises to be done in pairs, in supported lab classes, and potentially finished during independent study time. Weekly exercises submitted for marks and feedback.

Live interactive session after exercise submission to discuss, provide general feedback and build on this material.

Assessments

Weekly "heartbeat" coursework exercises, pedagogically formative in nature, through the term contributing to 20% of the module marks develop core skills for software design. Final computer based written exam contributes to the remaining 80% of the module marks.                

Feedback will be given on each weekly exercise submitted (ideally within a week allowing them to incorporate this feedback in their next submission). Overall feedback will be given in the live class, and through 1:1 discussion with staff and TAs.

Module leaders

Dr Matt Collison
Dr Sebastian Uchitel