UML Short Introduction#

Interface#

  • Does not implement anything

  • C++: abstract base class

  • Purest form (preferred): no implementation of anything

    • Except destructor of course, which has to be defaulted (see here for this sad story)

  • Implementation inheritance is possible though, but should not be overused

  • In this course, lets say the following C++ “interface” is expressed in UML like follows (“I” for “interface” in plantuml)

    • Alternative notation: a stereotype <<interface>>

    • Alternative notation: a small circle in the upper right corner

class Sensor
{
public:
    virtual ~Sensor() = default;
    virtual double get_temperature() = 0;
};

@startuml

interface Sensor {
  + double get_temperature()
}

@enduml

Interface Implementation, Inheritance#

  • I2CSensor is-a Sensor

  • I2CSensor can-be-used-as-a Sensor (i.e. I2CSensor* is automatically converted to Sensor*)

class I2CSensor : public Sensor
{
public:
    I2CSensor(unsigned int bus, uint8_t address);
    double get_temperature() override;
};

@startuml

interface Sensor {
  + double get_temperature()
}

class I2CSensor {
  + double get_temperature()
}

Sensor <|.. I2CSensor

@enduml

Association#

  • Lightest form of a “using” relationship

  • Usually implemented in C++ as raw pointer relationship

  • Lifetime and resource management unspecified

class PIDController
{
// ...
private:
    Sensor* _sensor;
};

@startuml

class PIDController {}
interface Sensor {}

PIDController -right-> Sensor

@enduml

Aggregation#

  • Semi has-a

  • Often implemented as std::shared_ptr<>

class PIDController
{
// ...
private:
    std::shared_ptr<Sensor> _sensor;
};

@startuml

class PIDController {}
interface Sensor {}

PIDController o-right-> Sensor

@enduml

Composition#

  • Most-defined form

  • Owned object is lifetime-tied to owning object

  • Commonly implemented as

    • Automatic membership

    • std::unique_ptr<>

class PIDController
{
// ...
private:
    Sensor _sensor;
};
class PIDController
{
// ...
private:
    std::unique_ptr<Sensor> _sensor;
};

@startuml

class PIDController {}
interface Sensor {}

PIDController *-right-> Sensor

@enduml