Webblog

Domain Driven Design in gewoon Nederlands (artikel 2): Het model

Domain Driven Design in gewoon Nederlands (artikel 2): Het model

In het vorige artikel is DDD geïntroduceerd. Hierbij is beschreven wat de “why” is van DDD. Dit artikel zal dieper ingaan over het “wat” van DDD. Het “wat” van DDD is het middel om tot het doel te komen. Dit middel is het komen tot een “model”.

Wat is een “problem domain”?
De term “probleemdomein” wordt vaak aangeduid in DDD voor het definieren van een functioneel gebied in een organisatie. Een applicatie zal nimmer alle processen ondersteunen van de organisatie. Denk bijvoorbeeld aan applicaties voor personeelszaken en inkoop. Organisaties van enige omvang hebben hiervoor altijd verschillende applicaties. Personeelszaken is bijvoorbeeld een “probleemdomein”.

Er wordt een “model” opgesteld. Wat is een “model”?
Een groot denker en pionier op het terrein van Domain Driven Design, Eric Evans zegt over het “model” het volgende: “every model represents some aspect of reality or an idea of interest. A model is a simplification. It is an interpretation of reality that abstracts the aspects relevant to solving a problem at hand and ignores extraneous detail”

Een architect en/of analist faciliteert het opstellen van het model. Wat heb je dan? Het model beschrijft het “uiterlijk” en “gedrag” van het gekozen probleem domein. Het “uiterlijk” is de verzameling van gegevens die van belang zijn. Hierbij is ook de relatie tussen deze gegevens interessant. Het “gedrag” beschrijft de processtappen en gebeurtenissen die met/op deze gegevens plaatsvinden. Je kan het ook menselijk maken. Het gedrag is wat van buitenaf wordt gezien. Dit gedrag heeft intentie/motivatie, dat zijn de gegevens. Binnen DDD wordt gedrag beschreven als een verzameling van “events” en de intentie als een verzameling van “entiteiten”. De verzameling van deze beschrijvingen worden geborgd in tekeningen en code.

Wat is het doel van het model?
In artikel 1 wordt het “swingtree project” beschreven. Het middel om dit soort projecten te voorkomen is het model. Dit is de “why” van het modelleren. Het model levert documentatie in de taal van de kenniswerker in het probleemdomein. Dit betekent dat het model in een taal is geschreven zonder technische oplossingen en begrijpbaar voor de kenniswerker en andere betrokkenen. Concreet, er moeten termen worden gebruikt van de “werkvloer”. Als meerdere termen voor hetzelfde onderwerp worden gebruikt, moet de best passende term worden gekozen.
Het primaire doel van het model is dus het beschrijven van de “why” en “what” van het probleemdomein. Door middel van het model wordt:

• Kennis over het probleemdomein geborgd
• Spreken toekomstige gebuikers en de ontwikkelaars dezelfde taal
• De oplossing in code is herkenbaar, ook in de toekomst

Een secundaire doelstelling is het hebben van een basis voor het software ontwikkelteam om de oplossing te realiseren van het probleemdomein. Deze basis moet in de code worden herkend zodat ontwikkelaars snel vanuit het probleemdomein, de technische oplossing eigen kunnen maken. Op deze manier wordt code herkenbaar en wordt alleen noodzakelijke code geschreven. Binnen DDD wordt de taal van de werkvloer “ubiquitous language” genoemd.

Hoe pakken we dat aan?
Zonder het gestructureerd aanpakken van de analyse om tot het model te komen, kan een applicatie ontstaan zoals hieronder weergegeven. Voor een klein probleemdomein hoeft dat geen probleem te zijn. Echter, het probleem domein zal altijd onderhevig zijn aan veranderingen en wellicht uitbreidingen. Het resultaat is een nog complexer plaatje. Binnen DDD worden dergelijke oplossingen “Big ball of mud” genoemd.


Bron: Patterns, Principles and Practices of Domain Driven Design by: Millet & Tune

Beter is om deelgebieden van het probleemdomein te beschrijven. Dit zijn de “subdomains” van het probleemdomein. Per subdomein worden vervolgens de modellen opgesteld. Dit betekent ook dat de oplossing (de architectuur) bestaat uit subdomeinen. Het realiseren van de oplossing gebeurt met focus en kan zelfs door verschillende teams worden uitgevoerd. De applicatie resulteert dan in een plaatje wat vergelijkbaar is met de onderstaande.


Bron: Patterns, Principles and Practices of Domain Driven Design by: Millet & Tune

In het volgende artikel wordt dieper ingegaan op de inhoud van een model. Hier komen de termen als “aggregate root”, “entity” en “value objects” aan de orde.

Auteur: Arjen Kraak, Bergler Competence Center © 2018

Geinteresseerd in dit onderwerp? Lees dan ook het eerste artikel: www.bergler.nl/ddd-in-gewoon-nederlands-artikel-1-introductie (level-100)

berglerDomain Driven Design in gewoon Nederlands (artikel 2): Het model
Lees meer

TechSummit Supply Chain Hacks

TechSummit Supply Chain Hacks

Persoonlijk zie ik de beweging naar een meer open source cultuur in software development als een positieve. Daarin sta ik zeker niet alleen en ik weet dat veel collega’s hier een zelfde positief gevoel bij krijgen. Maar elke beweging heeft zijn eigen uitdagingen, nu bezocht ik laatst bij de Microsoft TechSummit waar ik een sessie over Ethical Hacking van Milad Aslaner heb bijgewoond. Hierin kwam ter sprake dat hackers zich momenteel vooral focussen op hacken van supply chains.

Onder supply chain verstaan wij de hele aaneenschakeling van ketens om van begin tot eindproduct te komen. Dit kunnen dus allemaal verschillende grondstoffen/ halffabricaten zijn, of in het geval van softwareontwikkeling b.v. reeds bestaande libraries, open source projecten of commerciële producten.

Nu is het hacken van de supply chain een vrij breed begrip, maar het komt erop neer dat alle schakels om tot een eindproduct te komen, vatbaar zijn voor een hack. Dit is natuurlijk niets nieuws maar toch ligt de focus vaak op het beveiligen van een eindproduct en worden de tussenstappen nog wel eens over het hoofd gezien.

Zo valt bijvoorbeeld de stuxnet hack onder een supplychain hack, hierbij wordt middels het beïnvloeden van Siemens PLC’s (welke nucleair materiaal centrifugeren) een poging gedaan om het Iraanse nucleaire project negatief te beïnvloeden. Of denk bijvoorbeeld aan deze waarschuwing over Russische hackers die netwerk apparatuur aanvallen. Dit klinkt wellicht als James Bond scenario’s, maar dichter bij huis zijn er legio voorbeelden van supply chain hacks waar we als softwareontwikkelaars direct last van hebben. Denk hier bijvoorbeeld aan hacks in package managers of Container Base Images. Deze kunnen deel uitmaken van de supply chain voor je softwareproject.

Package managers
Hier komt opensource weer om de hoek kijken, veel van de opensource initiatieven worden aangeboden via 1 van de vele package managers. Zoals b.v. NuGet, maven, bower of npm.

En zo is er in 2017 bijvoorbeeld malware gevonden in een zeer populair npm opensource package.
Als Microsoft ontwikkelaar maak ik persoonlijk veel gebruik van de NuGet Package Manager. We moeten niet naïef zijn, ook NuGet packages kunnen schadelijke code bevatten.

Hoe kun je je wapenen tegen malware en toch gebruik maken van de goede dingen van open source?

Hier zijn gelukkig wel mogelijkheden voor beschikbaar. Vanuit NuGet is er een initiatief op de roadmap gezet om packages te ondertekenen. Dit om de integriteit en authenticiteit van een package te kunnen garanderen.

https://blog.nuget.org/20170914/NuGet-Package-Signing.html

Daarnaast zijn er meerdere 3rd party services beschikbaar die alle dependencies in de code controleren. Voorbeelden hiervan zijn bijvoorbeeld:

Deze of soortgelijke tools kunnen worden opgenomen in de build pipeline. Dit om direct bij elke build feedback te kunnen geven of een dependency is geïntroduceerd met een bekende kwetsbaarheid.

Containers
Naast het gebruik van package managers zijn containers momenteel een hot topic. Ook hier hebben we een potentieel risico aangezien hier vaak gebruik wordt gemaakt van reeds beschikbare door een derde partij gemaakte base images.

Hier hebben Michael Cherny en Sagie Dulce in 2017 een interessant stuk over geschreven.

Buiten het feit dat je hier met infrastructurele oplossingen mitigerende maatregelen kunt nemen zijn hier ook 3rd party mogelijkheden op je te wapenen tegen potentiele hacks. Voorbeelden hiervan zijn bijvoorbeeld:

  • Clair : (https://github.com/coreos/clair) Clair is een open source project wat gebruik maakt van statische analyse van kwetsbaarheden. Clair doet periodieke updates van een database met daarin de bekende kwetsbaarheden.
  • AquaSec: (https://www.aquasec.com/) AquaSec is een commercieel product ontworpen met containers in gedachte. Security audit, container image verificatie, runtime beveiliging, geautomatiseerde policy learning en inbraakbeveiliging mogelijkheden zijn de belangrijkste features.
  • Anchore Navigator: (https://anchore.io/) Commercieel product maar Anchore Navigator biedt wel een gratis service om public Docker images aan een Deep inspection te onderwerpen. Je kunt ook gebuik maken van hun reeds controleerde container repository.

Deze producten werken vaak in combinatie met een specifieke container registry waarin alleen gecontroleerde containers in terecht kunnen komen.

Azure Security Center
Naast het gebruik van tools specifiek voor Package management en Container controle op kwetsbaarheden, is het geen overbodige luxe om de inzet van Azure Security Center te overwegen.

Azure Security Center biedt mogelijkheden om on premise en in de cloud, op basis van grote hoeveelheden telemetrie, abnormale patronen te herkennen. Dit gaat middels Machine Learning algoritmes. Er zijn allerlei verschillende indicatoren welken potentieel schadelijk gedrag zouden kunnen aantonen. Zo wordt er bijvoorbeeld door geavanceerde malware, traditionele malware scanners omzeild door niet meer (of versleuteld) naar schijf te schijven. Azure Security Center gebruikt hier een geheugenanalyse voor om deze malware toch te kunnen herkennen. Daarnaast worden afwijkingen van normaal gedrag gedetecteerd. Als het aantal aanmeldingen of het tijdstip van de aanmeldingen of de locatie van waaruit de aanmeldingen zijn aangevraagd of andere aanmeldingsgerelateerde kenmerken aanzienlijk verschillen van wat normaal is, kan een waarschuwing worden gegenereerd.
Azure Security Center biedt een zeer uitgebreide set aan services welke op hun beurt weer zeer veel mitigerende maatregelen treffen tegen allerlei potentiële kwetsbaarheden.

Be aware!
Wees je er van bewust dat er in het hele ontwikkeltraject meerdere plekken zijn waar zich potentiële kwetsbaarheden bevinden. Het is goed om hier bewust mee om te gaan en indien noodzakelijk hier mitigerende maatregelen te treffen. De hier beschreven services kunnen hier een rol in spelen, want om maar eens een open deur in te gooien: “Voorkomen is beter dan genezen”.

Auteur: Patrick Bes, Bergler Competence Center © 2018

berglerTechSummit Supply Chain Hacks
Lees meer

DDD in gewoon Nederlands (artikel 1): Introductie (Level 100)

DDD in gewoon Nederlands (artikel 1): Introductie (Level 100)

Als Lead Developer ben ik betrokken bij het opmaken van business cases, uitwerken van ideeën en het implementeren van softwareoplossingen. Een steeds vaker terugkomend thema is dat mijn relaties hun applicatie landschap willen moderniseren zonder opnieuw het wiel te willen uitvinden.

berglerDDD in gewoon Nederlands (artikel 1): Introductie (Level 100)
Lees meer

Misbruik DRY niet

Misbruik DRY niet
Er zijn van die principes die er bij menig ontwikkelaar al vroeg in zijn carrière ingestampt worden. “Don’t repeat yourself” is misschien wel een van de bekendste.

berglerMisbruik DRY niet
Lees meer

Maak je eigen Business Rule Engine

Maak je eigen Business Rule Engine
Op het net zijn over dit onderwerp vele artikelen te vinden. Vaak beschrijven ze een onderdeel van een pattern of is de oplossing geschikt in een omgeving waar meer dan ervaren developers actief zijn.

berglerMaak je eigen Business Rule Engine
Lees meer

.NET Renaissance

.NET Renaissance
Recentelijk wordt er binnen het .NET framework regelmatig gesproken over een .NET renaissance. Wat is nu eigenlijk een renaissance? In de letterlijk zin staat het voor een wedergeboorte, dus de terugkeer van iets bestaands.

bergler.NET Renaissance
Lees meer

Angular ontwikkeling met Visual Studio Code

Angular ontwikkeling met Visual Studio Code
Angular is een framework om single page applications op te zetten waarin testbaarheid en separation of concern als basis voor de ontwikkeling zijn genomen.

berglerAngular ontwikkeling met Visual Studio Code
Lees meer

Videoverslag seminar Test Driven Development

Videoverslag seminar Test Driven Development

Bekijk hieronder het hele seminar van het Bergler Competence Center over sneller en beter software ontwikkelen met Test-Driven-Development (44 minuten).

berglerVideoverslag seminar Test Driven Development
Lees meer

Internal classes injecteren met SimpleInjector

Internal classes injecteren met SimpleInjector

Omdat we onze applicaties modulair opzetten komt het nogal eens voor dat een ontwikkelaar gebruik maakt van modules van een andere ontwikkelaar. De meeste voorbeelden van IOC-containers initialiseren de container vanuit de client applicatie, met als gevolg dat deze applicatie toegang moet hebben tot alle classes die geregistreerd moeten worden bij de container. Voor dit voorbeeld gebruik ik een web api (.NET MVC fullstack), die we stapsgewijs zullen opzetten met gebruik van SimpleInjector als IOC-framework.

Stap 1

Installeer de benodigde NuGet packages om SimpleInjector te kunnen gebruiken in je web api project.

Stap 2

Creëer in je App_Start map een InjectorConfig class aan en geef deze een statische methode waarin je de initialisatie van de SimpleInjector gaat opnemen.

Stap 3

Voeg in je global.asax een regel toe waarmee de injector configuratie wordt aangeroepen.

Stap 4

Maak een nieuwe instantie van een SimpleInjector container aan en laat je container de api controllers registreren. Registreer vervolgens de container als dependency resolver.

Stap 5

Registreer de afhankelijkheden die in je client applicatie zelf zitten.
Op dit moment is je client applicatie klaar om de inversion of control te gebruiken. In dit voorbeeld wil ik een service library gaan gebruiken waarin een aantal services zitten die vanuit de client gebruikt moeten worden:

Binnen deze library zitten echter ook afhankelijkheden waar ik de developer van de client niet mee lastig wil vallen. Om die reden is de client voorzien van een volgende class:

In dit bovenstaande voorbeeld zijn feitelijk alle geregistreerde classes internal. Alleen de InjectorConfiguration zelf en de interfaces van de EmployeeService en ActivityService zijn publiek.

Door deze configuratie classes aan te roepen vanuit de injector configuration van de client, worden de afhankelijkheden ingevuld zonder dat ik als developer me druk hoef te maken over de interne werking van de library die ik zojuist gekoppeld heb.

Last but not least
De SimpleInjector heeft een hele handige functie om bij het opstarten van de applicatie de volledige boomstructuur van afhankelijkheden na te lopen om te zien of er ergens registraties missen.

Roep hiervoor de container.Verify() functie aan. In het voorbeeld hierboven is deze functie zodanig ingebouwd dat hij alleen aangeroepen wordt als de applicatie in debug modus draait om te voorkomen dat het opstarten van de applicatie in productie nodeloos lang duurt. Omdat alle afhankelijkheden hier vanuit code ingesteld worden, is er ook geen risico dat de applicatie zich in productie anders gedraagt.

Auteur: Menno Jongerius, Bergler Competence Center © 2017

berglerInternal classes injecteren met SimpleInjector
Lees meer

Nieuwe features in C# 7

Nieuwe features in C# 7
Met de komst van Visual Studio 2017 is er ook een nieuwe versie van C# beschikbaar gekomen. In de nieuwe versie zijn weer een aantal verbeteringen in de taal doorgevoerd. Deze verbeteringen zullen we in deze blog even de revue laten passeren.

Out variabelen
In C# 6.0 hebben we een variabele van een expliciet type nodig om door te geven aan een methode die een out-parameter verwacht.

Met de komst van C# 7.0 kunnen we dit stukje code herschrijven tot

In deze codeconstructie kun je zelfs gebruik maken van het var-keyword

De scoping van de variabele is het omvattende blok, dus na de aanroep naar de methode die een out-parameter verwacht, kun je de parameter gewoon gebruiken.
Als je niet geinteresseerd bent in de waarde die via een out-parameter teruggegeven wordt, dan kun je er voortaan ook voor kiezen om deze te ‘negeren’ door een _ te gebruiken.

Is-pattern matching

In veel projecten komt code voor die variabelen van het ene type in het andere omzet en aan de hand van de omgezette waarde iets met die waarde gaat doen. In C# 6.0 is dit vaak nog best code intensief als je dit veilig wilt doen. Met de komst van de pattern matching mogelijkheden van C# 7.0 kan dit veel eenvoudiger.
Het volgende code voorbeeld bepaalt of een parameter een positief geheel getal is gebruik makend van de nieuwe mogelijkheden van C# 7.

Het is mogelijk om een object direct te vergelijken met een constante waarde inclusief null. Met behulp van de is-operator kun je nu ook direct de waarde uit een controle krijgen. Je hoeft dus niet meer met behulp van de combinatie is en as de waarde op te halen.

Patterns in switch
Ook binnen een switch statement kun je gebruik maken van patterns.

Zoals in de bovenstaande code te zien, kun je binnen een pattern match ook nog gebruik maken van aanvullende controles. Dit heeft wel direct tot gevolg dat de volgorde van de selecties binnen een switch belangrijk worden. Dit geldt niet voor de default-controle, want deze wordt altijd als laatste geëvalueerd. De mogelijkheden van een switch statement worden met behulp van deze feature een stuk krachtiger. Het is wel belangrijk om in de gaten te houden dat je niet teveel logica in een switch statement stopt. Dit is vaak een signaal dat je beter een andere design pattern had kunnen gebruiken.

Tuples
Tuples binnen .NET bestaan al wat langer. Een tuple is een handige constructie om meerdere waarden uit een methode te retourneren zonder dat je hiervoor een klasse hoeft te maken. Het gebruik van tuples was alleen nog een beetje onhandig. Gelukkig is het gebruik een stuk beter geworden. Voortaan kun je tuples teruggeven zonder Tuple<T1,T2,…> te gebruiken, maar kun je direct gebruik maken van een constructie met (). Gelukkig kunnen we zelfs de onderdelen binnen de tuple nu voorzien van een beschrijvende naam, waardoor we niet meer hoeven te onthouden op welke positie een bepaalde waarde terug wordt gegeven.
Een methode die een volledige naam splitst in de onderdelen, kunnen we dus nu definiëren als:
(string first, string middle, string last) ParseFullName(string fullName)

Deconstruction
Voor het opvangen van het resultaat van een tuple kun je de volgende codeconstructie gebruiken:
(first, middle, last) = ParseFullName(fullName);
Dit wordt ook wel de deconstructing assignment genoemd.

Local functions
Soms wil je in het kader van seperation of concerns een kleine stukje code binnen een methode los trekken zonder dat je ooit de ambitie hebt om dit stukje code te hergebruiken in een ander deel van je code. Je kunt dit nu oplossen door gebruik te maken van een local function:

Binnen de local function kun je ook gebruik maken van alle variabelen in scope, dus je hoeft in het code voorbeeld prefix niet als parameter mee te nemen.

Literal improvements
Binnen C# bestaat al lang de mogelijkheid om literals in de code op te nemen. De leesbaarheid van de waarden liet alleen soms nog wel te wensen over. Om de leesbaarheid te vergroten bestaat nu de mogelijkheid om scheidingstekens toe te voegen, zonder dat dit waarde beïnvloedt. Hiervoor wordt het _ teken gebruikt.

Met ingang van C# 7 is het nu ook mogelijk om binaire literals aan te maken in de code.

Return by ref
We kunnen al geruime tijd value types by reference doorgeven als parameter aan een methode. Het is nu ook mogelijk om return values by ref terug te geven.

De mooie oplopende reeks is nu niet zo mooi oplopend meer:

Expression bodied members
In C# 6.0 hebben we de mogelijkheid gekregen om expression bodied functions te schrijven. Met de komst van 7.0 is het nu ook mogelijk om deze syntax te gebruiken bij constructoren, destructoren en properties.

Throw Exceptions in expressions
Binnen C# 7.0 wordt de mogelijkheid geboden om binnen een paar constructies direct een exception te throwen. Een voorbeeld hiervan kun je zien in het bovenstaande voorbeeld.

berglerNieuwe features in C# 7
Lees meer