Software Engineering and Object-Oriented Analysis & Design · 9 min read

Object-oriented design implementation

Object-oriented implementation turns the design artefacts — design class diagrams and interaction (collaboration/sequence) diagrams — into working code in an object-oriented language such as Java, C++ or C#. Because OO design already defines classes, attributes, methods and the messages between objects, much of the coding is a systematic mapping. This topic covers where implementation fits in the development process, how to map designs to code, how to update class definitions, and how to handle exceptions and errors robustly.

Key concepts

Programming and the development process

  • In an iterative process (e.g. Unified Process), each iteration takes designs of the selected use cases into code, tests them, and integrates. Design is not finished before coding; coding feeds back into design.
  • Code changes and discoveries during programming are normal; the design models are updated (or regenerated) to match — round-trip engineering with CASE tools: forward engineering (diagram → code skeleton) and reverse engineering (code → diagrams).
  • Order of implementation: start with the least-coupled classes (those that depend on few others) and move to the most coupled, so each class can be compiled and unit tested as soon as it is written.
  • Practices: test-driven development (write a unit test first), refactoring (improve structure without changing behaviour), coding standards and reviews.

Mapping design to code: two main sources —

  • the design class diagram gives class definitions (names, attributes, method signatures, inheritance, associations);
  • the interaction diagrams give method bodies (the sequence of messages each method sends).

Creating class definitions from design class diagrams

  • Each class becomes a class in code; each attribute with a simple type becomes a field (private Money total;).
  • Method signatures come directly from the DCD (public void makeLineItem(ProductDescription desc, int qty)).
  • Constructors are added from create messages in interaction diagrams.
  • Reference attributes: an association with navigability from A to B becomes a field in A holding a reference to B (private ProductCatalog catalog;). Role names in the diagram become field names.
  • A multiplicity of * becomes a collection (e.g. List<SalesLineItem> lineItems = new ArrayList<>();).
  • Generalisation becomes inheritance (class CreditPayment extends Payment); interfaces become implements.
  • Visibility markers map to access modifiers: + public, - private, # protected.

Creating methods from collaboration (interaction) diagrams

  • Each message sent to an object becomes a method in that object's class; the sequence of outgoing messages inside it becomes statements in the method body.
  • Example: if :Register receives enterItem(id, qty) and sends 1: desc = getProductDescription(id) to :ProductCatalog and 2: makeLineItem(desc, qty) to :Sale, then
public void enterItem(ItemID id, int qty) {
    ProductDescription desc = catalog.getProductDescription(id);
    currentSale.makeLineItem(desc, qty);
}
  • Iteration markers (*) become loops over collections; conditions ([x > 0]) become if statements; create messages become new.

Updating class definitions: as methods are written, new attributes, parameters or helper methods appear; class definitions and the DCD are updated accordingly. Getters/setters and toString/equals methods are added as needed.

Classes in code: in Java/C++ a class bundles data (fields) and behaviour (methods); objects are instances created at run time. Key features: encapsulation (private fields, public methods), inheritance (reuse), polymorphism (overriding and dynamic binding), abstract classes and interfaces, static (class-level) members, packages/namespaces for organisation.

Exception and error handling

  • An exception is an abnormal event during execution (invalid input, missing file, network failure) that disrupts normal flow.
  • Java/C#/C++ mechanism: try (code that may fail), catch (handle a specific exception type), finally (always executes — release resources), throw (raise), and in Java throws (declare in method signature).
  • Java distinguishes checked exceptions (must be caught or declared; e.g. IOException) from unchecked runtime exceptions (NullPointerException, ArithmeticException) and errors (OutOfMemoryError, usually not caught).
  • Custom exceptions are created by extending Exception. In UML, exceptions can be shown as signals or listed in operation properties.
  • Good practice: catch specific exceptions, do not silently swallow them, use exceptions for exceptional cases (not normal control flow), log meaningful messages, clean up resources (finally or try-with-resources), convert low-level exceptions to meaningful higher-level ones.
  • Errors vs faults vs failures: a programmer's error (mistake) creates a fault (defect) in code, which may cause a failure when executed.

High-yield points

  • Class definitions come from the DCD; method bodies from interaction diagrams.
  • A navigable association becomes a reference attribute; a * multiplicity becomes a collection.
  • Implement from least-coupled to most-coupled classes.
  • finally always runs; Java checked exceptions must be caught or declared with throws.
  • An error (mistake) causes a fault (defect), which may cause a failure.

Worked example

DCD: class Sale with attribute isComplete: Boolean, method getTotal(): Money, and a navigable association to * SalesLineItem with role name lineItems. Write the class skeleton.

public class Sale {
    private boolean isComplete;
    private List<SalesLineItem> lineItems = new ArrayList<>();

    public Money getTotal() {
        // sum of each line item's subtotal (from the interaction diagram)
    }
}

The attribute becomes a field, the * association becomes a collection named after the role, and the operation becomes a method.

Exam tips

  • Class definitions come from the DCD; method bodies come from interaction diagrams.
  • A * multiplicity at the navigable end maps to a collection field.
  • Implement from least-coupled to most-coupled classes.
  • finally runs whether or not an exception occurs.
  • Checked exceptions must be caught or declared with throws; unchecked need not be.

Exam-style questions

From Calmon's question bank, which has 25 questions on this topic.

1. When creating methods from a collaboration diagram, a create message sent to a new object is normally implemented in code as which of the following?

  • A. A destructor call
  • B. A call to the object's constructor (e.g. using new)
  • C. A getter method
  • D. A static variable declaration

Answer: B. A create message in an interaction diagram maps to instantiating the object, i.e. calling its constructor (for example new SalesLineItem(desc, qty)).

2. According to Larman, when implementing classes from a design, in what order should classes be implemented and unit tested?

  • A. From least-coupled to most-coupled
  • B. In the order actors appear in the use case diagram
  • C. In alphabetical order of class names
  • D. From most-coupled to least-coupled

Answer: A. Classes should be implemented from least-coupled to most-coupled, so that the classes each one depends on already exist and are tested.

Practise ACtE08 questions →

read it. practise it. pass it.

a free account adds chapter-wise practice, mock tests in the real exam pattern and a daily study plan.

create free account →