Skip to content

UML Class diagram

Het uittekenen van onze klassenmodellen doen we met ‘blokken’ en ‘pijltjes’ zoals bij zoveel diagrammen. Je hebt misschien al eens gezien hoe je dit doet voor een datamodel of voor een functiestroomdiagram. Al deze modellen kunnen we weergeven op dezelfde manier, zodat we met elkaar makkelijker kunnen praten over die modellen en dezelfde taal daarin spreken. Hiervoor is een algemene manier van schrijven en tekenen bedacht die heet “Unified Modeling Language”. Voor klassenmodellen is dit toegepast met speciale symbolen die hier belangrijk zijn. Dan kunnen we een “Class model” maken.

graph BT
    UML[UML Diagram]
    Structural
    Behavioral
    Interaction
    Class
    Object
    Component
    CompositeStructure
    Deployment
    Package
    UseCase
    Activity
    StateMachine
    Communication
    InteractionOverview
    Sequence
    Timing

    Structural --> UML
    Behavioral --> UML

    Interaction --> Behavioral
    Class --> Structural
    Object --> Structural
    Component --> Structural
    CompositeStructure --> Structural
    Deployment --> Structural
    Package --> Structural

    UseCase --> Behavioral
    Activity --> Behavioral
    StateMachine --> Behavioral

    Communication --> Interaction
    InteractionOverview --> Interaction
    Sequence --> Interaction
    Timing --> Interaction

Een “class diagram” is een soort van “diagram” maar dan dus specifiek voor klassebeschrijvingen. Bij programmeren kunnen we ook de “State machine diagram” gebruiken om te bepalen hoe een programma zou moeten werken, als onderdeel van het ontwerp.

Een class beschrijven met UML

Met behulp van UML kunnen we dus ook onze klassen op een uniforme manier definiëren. Het voorbeeld staat hieronder. De naam staat altijd boven, gecentreerd, en iets groter en dikker. De eigenschappen volgen daarna. Voor elke eigenschap definiëren we ook het datatype. Als laatste beschrijven we de methodes. Daarin zie je de naam van de methode en de benodigde argumenten. Het resultaattype wordt niet getoond omdat dit altijd hetzelfde is; een nieuwe vorm van het object (bij setters) of het datatype van het opgevraagde (bij getters).

classDiagram
    class BankAccount{
        owner: String
        balance: Dollar = 0
        deposit(amount: Dollar)
        withdraw(amount: Dollar)
        calculateInterest()
    }

Access modifiers

In UML kunnen we ook aangeven of een eigenschap of methode publiek, privaat of beschermd is. Dit doen we met een plus, min of hekje voor de naam van de eigenschap of methode.

classDiagram
    class BankAccount{
        +owner: String
        -balance: Dollar = 0
        +deposit(amount: Dollar)
        +withdraw(amount: Dollar)
        -calculateInterest()
    }

In het bovenstaande voorbeeld is de eigenschap owner publiek, en de eigenschap balance privaat. De methodes deposit en withdraw zijn publiek, en de methode calculateInterest is privaat.

Static

In UML kunnen we ook aangeven of een eigenschap of methode statisch is. Dit doen we met een onderstreepte naam.

classDiagram
    class BankAccount{
        +owner: String
        -balance: Dollar = 0
        +deposit(amount: Dollar)
        +withdraw(amount: Dollar)
        -calculateInterest()
        numberOfAccounts$: int $
    }

In het bovenstaande voorbeeld is de eigenschap numberOfAccounts statisch.

Relaties tussen klassen

In UML kunnen we ook aangeven hoe klassen met elkaar samenwerken. Dit doen we met lijnen tussen de klassen. De lijnen hebben een bepaalde betekenis.

Association

Een association is een relatie tussen twee klassen. Deze relatie is altijd bidirectioneel. Dit betekent dat beide klassen elkaar kennen. De lijn heeft een pijlpunt aan beide kanten.

classDiagram
    class BankAccount{
        +owner: Owner
        -balance: Dollar = 0
        +deposit(amount: Dollar)
        +withdraw(amount: Dollar)
        -calculateInterest()
        numberOfAccounts: int $
    }

    class Owner{
        +name: String
        -address: String
        +phoneNumber: String
        +getAddress()
    }

    BankAccount --> Owner

In het bovenstaande voorbeeld is de relatie tussen BankAccount en Owner een association.

Aggregation

Een aggregation is een relatie tussen twee klassen. Deze relatie is altijd bidirectioneel. Dit betekent dat beide klassen elkaar kennen. De lijn heeft een leeg ruitje aan de kant van de klasse die de andere klasse bevat.

classDiagram
    class BankAccount{
        +owner: Owner
        -balance: Dollar = 0
        +deposit(amount: Dollar)
        +withdraw(amount: Dollar)
        -calculateInterest()
        numberOfAccounts: int $
    }

    class Owner{
        +name: String
        -address: String
        +phoneNumber: String
        +getAddress()
    }

    BankAccount o-- Owner

In het bovenstaande voorbeeld is de relatie tussen BankAccount en Owner een aggregation. De BankAccount bevat een Owner. De Owner kan bestaan zonder BankAccount.

Composition

Een composition is een relatie tussen twee klassen. Deze relatie is altijd bidirectioneel. Dit betekent dat beide klassen elkaar kennen. De lijn heeft een gevuld ruitje aan de kant van de klasse die de andere klasse bevat.

classDiagram
    class BankAccount{        
        -balance: Dollar = 0
        +deposit(amount: Dollar)
        +withdraw(amount: Dollar)
        -calculateInterest()
        numberOfAccounts: int $
    }

    class Owner{
        -bankAccount: BankAccount
        +name: String
        -address: String
        +phoneNumber: String
        +getAddress()
        +getBankAccount()
    }

    BankAccount --* Owner

In het bovenstaande voorbeeld is de relatie tussen BankAccount en Owner een composition. De BankAccount bevat een Owner. De BankAccount kan niet bestaan zonder Owner.

Inheritance

Een inheritance is een relatie tussen twee klassen. Deze relatie is altijd unidirectioneel. Dit betekent dat de ene klasse de andere klasse kent, maar niet andersom. De lijn heeft een leeg driehoekje aan de kant van de klasse die de andere klasse erft.

classDiagram
    class BankAccount{        
        -balance: Dollar = 0
        +deposit(amount: Dollar)
        +withdraw(amount: Dollar)
        -calculateInterest()
        numberOfAccounts: int $
    }

    class SavingsAccount{
        -interestRate: double
        +calculateInterest()
    }

    BankAccount <|-- SavingsAccount

In het bovenstaande voorbeeld is de relatie tussen BankAccount en SavingsAccount een inheritance. De SavingsAccount erft van BankAccount. De BankAccount kent de SavingsAccount niet.