Construct Class Designs

Designing Classes and Their Behaviour

When building a software solution, you first identify the key classes needed to model the problem domain, then define each class’s attributes and methods to meet the application requirements.

Effective design ensures that each class has a clear responsibility and interacts cleanly with other classes.

Unified Modeling Language (UML) Class Diagrams

Unified Modeling Language (UML) class diagrams provide a standard way to visualise the structure of software systems.

They help you plan and communicate your design before writing code, ensuring consistency and completeness.

UML diagrams:

  • Clarify how data is organised within a system.
  • Document design decisions for team communication and future maintenance.
  • Reveal relationships and dependencies before writing any code.

Modeling a Car

Consider a simple application that simulates vehicles in a parking lot. We need a Car class to model each vehicle. This class should:

  • Store make, model, and fuelLevel as attributes.
  • Provide methods like startEngine() to turn the car on, and drive(distance) to minimise fuel consumption.
  • Ensure that fuelLevel never goes below zero (a potential future validation).

By including a UML diagram, we capture all of this at a glance: no code required yet.

UML Class Diagram: Car

UML Diagram for Car Class

Figure: UML class diagram showing attributes and operations of the Car class.

Anatomy of a UML Class Diagram

  • Compartments: 3 horizontal sections: class name, attributes, and methods (operations), each separated by lines.
  • Class Name: Displayed in the top compartment (e.g. Car).
  • Attributes Compartment: Lists data members with visibility and type (e.g. - make: String, - fuelLevel: float).
  • Operations Compartment: Lists methods with visibility, parameters, and return types (e.g. + drive(distance: float): void).
  • Visibility Indicators:
    • + public - accessible from any class.
    • - private - accessible only within the declaring class; fully encapsulated.
    • # protected - accessible within the class and its subclasses (and, in some languages, also within the same package).
    • ~ package/internal - accessible only to classes in the same package/module (optional UML notation).
  • Data Types & Parameters: Shown as name: Type for attributes and method(param: Type): ReturnType for operations.

Modelling Relationships Between Classes

Some problems are best solved with more than one class. Here we model relationships using two classes at a time so the role of each class is clear and easy to reason about.

Aggregation

Aggregation is a HAS-A (shared) relationship: one object groups others that can still live independently. Scenario: Library and Book-books can exist outside a specific library and can be moved between libraries.

UML Diagram, Aggregation
  • Reading Left→Right: Library HAS-A Book (0..*), the library holds a collection of books.
  • Right→Left: Book BELONGS-TO Library, but a book can be removed, loaned, or reassigned without being destroyed.

Composition

Composition is a HAS-A (strong ownership) relationship: the part’s lifetime depends on the whole. Scenario: Order and LineItem-line items only make sense inside their order; delete the order and its items go with it.

UML Diagram, Composition
  • Reading Left→Right: Order HAS-A LineItem (1..*), the order creates and owns its items.
  • Right→Left: LineItem PART-OF Order, it cannot exist or be shared without its parent order.

Inheritance

Inheritance is an IS-A relationship: a more specific class reuses and extends a general class. Scenario: Shape and Circle-a circle is a kind of shape with extra details (like radius).

UML Diagram, Inheritance
  • Reading Parent→Child: Shape provides shared attributes/behaviours that Circle inherits and may override.
  • Child→Parent: Circle IS-A Shape, so it can be used wherever a shape is expected (polymorphism).

 Key Takeaways

  • Translate requirements into clear classes with focused responsibilities.
  • Define each class’s attributes and methods to satisfy its role in the application.
  • Use UML class diagrams to map out class relationships and interfaces before coding.
  • Early design and visualisation save time by catching design flaws before implementation.