Modelgedreven ontwikkelstraat in .NET (2): Associaties

 
28 oktober 2008

Als in mijn vorige post gedemonstreerd kunnen we makkelijk attributen (ofwel properties) genereren op basis van een gegeven model. Dat is echter maar één van de basisaspecten van ons model. In deze post wil ik graag ingaan op de transformatie van gemodelleerde associaties naar code.

Allereerst, wat zijn associaties eigenlijk? In feite zou je als je puur object georiënteerd redeneert kunnen zeggen dat alle attributen van een class een associatie vertegenwoordigen. Zo is de ‘Name’ attribuut van de Employee class in feite een associatie met de String class met als associatienaam ‘Name’. Wanneer spreken we dan van een attribuut en wanneer van een associatie? Persoonlijk denk ik dat het duidelijkst is om te spreken van een associatie als het gaat om relaties met classes van binnen het model en te spreken van attributen als gerefereerd wordt naar classes buiten het model (Integers, String, DateTime, etc.).

Er zijn vele vormen van associaties. Ze kunnen gericht zijn, multipliciteiten bevatten maar ook van een bepaald type zijn (composites of aggregates bijvoorbeeld). Daarnaast kan een associatie zelf ook weer attributen of operaties bevatten en spreken we van een association class. Ik zal me in deze structuur slechts beperken tot de gerichte one-to-many associatie alsmede de gerichte one-to-one associatie. UIteraard kan op basis van dit voorbeeld veel meer gedaan worden met andere typen associaties. Binnen de standaard DSL die ik gebruik is het ook mogelijk om bijvoorbeeld composites en aggregations te modelleren; ik laat deze echter voor nu buiten beschouwing.

Handgeschreven code
Zoals eerder begin ik weer met een eenvoudig codevoorbeeld van hoe we een associatie met de hand zouden maken.

One-to-many: Employee.Activities 

private System.ComponentModel.BindingList<Activity> activities =
     new System.ComponentModel.BindingList<Activity>(); 

public System.ComponentModel.BindingList<Activity> Activities
{
    
get
    
{
          
return this.activities;
     }
}

Hier zien we vrijwel hetzelfde patroon als eerder bij de attributen. Er wordt een field gegenereerd en een property die dit field ontsluit. Dit is een vrij standaard manier van implementeren, maar er zou een keuze gemaakt kunnen worden om Activities niet read/write te ontsluiten maar bijvoorbeeld read-only. Op zo’n manier kan je dan via een AddActivity() en/of RemoveActivity() methode de lijst muteren. Dit is een kwestie van smaak maar deze manier van implementeren geeft je keuzevrijheid hierin; ook nog verderop in het project.

One-to-one: Activity.Employee
Dezelfde associatie de andere kant op is zo mogelijk nog eenvoudiger:

private Employee employee; 

public Employee Employee
{
    
get
    
{
         
return this.employee;
     }
    
set
     {
         
this.employee = value;
    
}
}

Exact gelijk aan wat we al zagen bij de attributes. Echter, ook hier zouden we PropertyChanged events willen kunnen afgooien, en zelfs changed events in nested objecten willen doorpropageren naar een parent. Zo zou je wellicht een PropertyChanged in een Activity willen doorpropageren richting de Employee (als dit de aggregaat-root zou zijn in je model). Hier zien we een heel mooi voorbeeld van een toepassing van een composite of een aggregation – hieruit zou je de richting van notification kunnen aflezen. In dit eenvoudige  voorbeeld laat ik dit achterwege.

Template
Aangezien de templatecode toch een beetje een rommeltje wordt biedt ik bij deze de template maar gewoon ter download aan :). Hierin zit overigens two-way change notification (met wiring van de notifications van de collecties in de constructor) en nog een aantal andere zaken (Identities en index-based toegang tot properties; hier kom ik later op terug); hij is in het eerder geposte project te kopieren (in de templates directory) en te executeren.

Ik ven verder erg nieuwsgierig naar andere patronen betreft associaties, dus diegene die hier op zou willen reageren nodig ik (wellicht ten overvloede) van harte uit.


Werken met ?
Kijk dan bij onze mogelijkheden voor starters en/of ervaren IT'ers.


Categorieën: Architectuur, Development, .Net

Tags: , , ,