Ontkoppeling

 
19 oktober 2008

Dijkstra heeft ons jaren terug al verteld dat we koppeling in onze software laag moeten houden maar zaken die bijelkaarhoren moeten groeperen (high cohesion). Dit komt kort gezegd neer op goede indeling van verschillende onderdelen van software zodat onderdelen beter onafhankelijk van elkaar kunnen worden ontwikkeld en onderhouden. We zien dit bijvoorbeeld in object georienteerde talen terugkomen onder de noemer ‘encapsulatie’. Als we naar architectuurstijlen kijken zien we dat we component gebaseerd ofwel gelaagd kunnen werken om zo logische ontkoppeling van verschillende applicatieonderdelen te realiseren. Ik zou graag echter twee zaken omtrent ontkoppeling willen bediscussieren in deze post.

Ten eerste de manier van ontkoppelen; verschillende onderdelen van een applicatie worden vaak in fysiek verschillende onderdelen gedistribueerd (lees: verschillende projects/assemblies in .NET, ofwel packages / JAR’s in Java) maar dit is voor ontkoppeling niet relevant. Interessante inzichten hierin zijn o.a. te vinden bij Paul Stovell en Jeremy Miller. Sterker nog, door op deze manier fysieke scheidingen aan te brengen in de codebase introduceer je vaak alleen maar ingewikkelde structuren waar dit lang niet altijd noodzakelijk is.

Ten tweede het ontkoppelen zelf. Vaak gezien als quest die we moeten nastreven wordt alles los gekoppeld zodat verschillende applicatieonderdelen geen enkele kennis meer hebben van hoe en waarmee gecommuniceerd wordt. Ik zie in de praktijk al snel een aantal problemen ontstaan:

  • Er is geen goede manier van foutopsporing meer mogelijk. ‘Overdreven’ losse koppeling maakt dat op compile time minder of geen validatie meer plaatsvindt van de samenwerking tussen de onderdelen.
  • Om de ontkoppeling te realiseren worden frameworks en structuren geintroduceerd die vaak werken op basis van reflectie om maar alles aan te kunnen. Gevolgen hiervan zijn sterk verminderde onderhoudbaarheid van de code aangezien dit op een andere manier extra complexiteit introduceert.

Hoe kan je nu wel gebruik maken van losse koppeling zonder de nadelen van toegevoegde complexiteit om de ontkoppeling te realiseren en de verminderde validatie op compile-time? Door op een andere manier te ontkoppelen (maar dit wel degelijk te doen!). Zo is er in mijn optiek alleen noodzaak om conceptueel te ontkoppelen en in je ontwikkelstraat de verschillende onderdelen te kunnen aanwijzen en onderhouden, dit is echter na het compileren van de software niet meer relevant.
Een mooi voorbeeld van hoe iets dergelijks kan werken is AOP. Daarmee is op design time een rigide scheiding van verschillende concerns duidelijk maar op run-time is er van deze scheiding door code weaving niets meer terug te vinden. Een nadeel hiervan is echter dat AOP je vaak nog niet de uitgebreide validatie van moderne compilers tot je beschikking hebt; er wordt code gewoven na het compilen.

Ik kom terug op deze problematiek in een serie posts die ik zal publiceren over een ontwikkelstraat die gebaseerd is op modelgedreven werken en code generatie. Mijn vermoedens zijn namelijk dat de combinatie van een centraal businessmodel dat los beheerd wordt van technische componenten (‘Domain Driven Design’) en een eerdere samenvoeging van deze concerns (code generatie in plaats van opdeling in verschillende fysieke modules) wel eens een aantal van deze problemen zou kunnen oplossen.


Werken met ?
Kijk dan bij onze mogelijkheden voor zowel starters als ervaren engineers.


Categorieën: Development

Tags: ,


Reactie

  • Ivo Limmen schreef:

    Ikzelf maak tegenwoordig veel gebruik van SPI (Service Provider Interface). Dit is een Java specifieke oplossing voor dit probleem. Dit geeft mij de mogelijkheid om implementaties te maken van een interface die runtime gevonden worden op de classpath. Overigens beschrijf ik deze techniek in een oudere post van mij: http://www.software-innovators.nl/2008/04/08/bootstrap-delegatie/.

    Geplaatst op 20 oktober 2008 om 22:07 Permalink