De eigenschappen van properties

 
08 januari 2009

Een tijdje geleden had ik een discussie met een collega. deze collega had kritiek ontvangen op zijn code vanwege de binding van data van een object via properties aan een formulier. Dit doorbrak encapsulatie en was geen goede object oriented techniek luidde de kritiek.

Vrijwel elke user interface bied slechts mogelijkheden om te binden op properties dus in het gesprek met de collega hebben we deze kritiek afgedaan als niet praktisch en natuurlijk was het gebruik van properties volstrekt legitiem.

Recent probeerde ik een oplossing te vinden voor een probleem met lazy loading. Oplossingen waren er voldoende, maar geen van alle waren elegant of transparant. Diepere beschouwing bracht de schuldige aan het licht: Properties. Onze criticus had gelijk.

Een van de basis principes van object geörienteerd programmeren is encapsulatie. Het idee is dat objecten hun state bewaken en niemand direct deze state kan beïnvloeden. Properties werken in theorie mee aan deze strategie omdat ze de ontwikkelaar de mogelijkheid bieden om code te injecteren voor of na de toegang tot een property. Op deze manier kan er validatie plaats vinden en is er geen directe toegang toe fields.

De encapsulatie die properties bieden is echter alleen technisch. Conceptueel is eigenlijk geen verschil of ik nu direct bij het naam veld van een persoon object can of dit via een property naam moet realiseren. Nog steeds heeft de aanroeper kennis en toegang tot de interne state van het object, een veld omhullen in een laagje code verandert dit niet.

Door properties op deze manier in te zetten missen we de intentie van de interactie. De ontvanger van het bericht kan geen conclusies trekken over wat de verzender precies nodig heeft. Vergelijk weer het voorbeeld waarbij een bericht verstuurd wordt om het adres van een persoon aan te passen. ‘persoon adres: eenNieuwAdres‘ bevat veel minder betekenis dan een bericht ‘persoon verhuisNaar: eenNieuwAdres‘. De ontvanger kan veel meer conclusies trekken op basis van het laatste bericht.

Dit wil nog niet zeggen dat we helemaal geen properties moeten gebruiken. Voor het aanpassen van een object is het misschien beter om een methode te gebruiken, maar er lijkt niet echt een reden te zijn om lees properties af te schaffen. Als er niets verandert aan het object dan kan direct lezen van de state van een object via properties to geen kwaad?

Dit klopt tot zekere hoogte. Als de state van het object niet verandert is er geen effect en kan het eigenlijk geen kwaad. Maar we weten niet zeker dat het uitvragen van een property geen effect heeft. Een property bied ons namelijk de mogelijkheid om code uit te voeren tijdens het lezen van een property. Het lezen van het property in een modern systeem kan veel gevolgen hebben. Audit gegevens kunnen vast gelegd worden, toegankelijkheids regels toegepast of niet geladen velden alsnog geladen.

Dit laatste was het gene waar ik tegenaan liep. Het lezen van een property kon tot gevolg hebben dat het betreffende veld of de velden geladen werden vanuit de database. Dit is niet erg, maar wat gebeurt er als dit gebeurt omdat er een aanroep is vanuit een formulier dat een bepaalde groepering van informatie wil laten zien. De ontvanger heeft geen idee van de intentie van het bericht en kan slechts braaf het veld op halen en terug geven. Als we meerdere velden willen laten zien gebeurt dit telkens weer over nieuw.

Voor bijvoorbeeld het tonen van een lijst van personen kun je je voorstellen dat dit niet er efficiënt is, maar omdat de ontvangers geen verschil kunnen maken tussen het tonen van een enkel persoon en het tonen van een lijst kan er geen beslissing genomen worden om dit efficiënter te laten plaats vinden. De oplossing voor dit probleem is gelijk aan het verhuis probleem. Gebruik geen properties om gegevens op te halen, maar stuur een bericht naar het object waarin aangegeven wordt wat er verwacht wordt. Bijvoorbeeld door het bericht ‘persoon toonOp: eenScherm‘ te sturen. Voor een lijst van personen zou dit dan worden: ‘personen toonOp: eenScherm‘.

Nu hebben onze objecten de mogelijkheid om conclusies te trekken over de acties die er gaan plaats vinden. Helaas ken ik nog een binding frameworks die op deze manier werken, maar deze methode zou volgens mij een veel flexibelere en efficiëntere manier van werken kunnen opleveren.

Dus: Weg met properties!


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


Categorieën: Project- & procesmanagement, Architectuur, Development, Overige talen en platformen

Tags: , ,


Reacties (2)

  • @Ralf
    Klinkt inderdaad goed. Standaard databinding in .NET werkt in de praktijk in mijn optiek ook helemaal niet. Dat zou op een heel andere manier moeten, bijvoorbeeld met wat jij aandraagt.
    Het neigt een beetje naar een soort DTO (Data Transfer Object) die specifiek die data bevat om op het scherm te tonen. Wellicht zelfs een DataSet/DataTable die je heen- en weer stuurt van en naar je scherm waarna het object zelf besluit wat met al die gegevens te doen?

    @Tom
    Door de collectie op te halen krijg je een pointer naar dezelfde collectie terug. Die kan je dan dus direct manipuleren. Dat is op te lossen door in de getter logica op te nemen zodat er een read-only kopie van de collectie wordt doorgegeven in plaats van de collectie zelf.

    Geplaatst op 17 januari 2009 om 14:37 Permalink

  • Tom schreef:

    Licht terzijde, maar over het behouden van State en Get-only properties:

    Ik was de eerste keer vrij verbaasd toen ik vanuit een andere klasse een ‘get/private set’ lijst ophaalde en er elementen aan kon toevoegen zonder waarschuwing/foutmelding…

    Geplaatst op 15 januari 2009 om 11:27 Permalink