Inleiding

Deze presentatie volgt nauw de bovengenoemde bijbel. Gedurende de komende weken zal de lijst met voorbeelden worden uitgebreid.

Welk soort patterns zijn er?

Daarbij kun je onderscheid maken tussen de scoop en het doel.

Heel vaak zijn er meerdere Patterns tegelijk en door elkaar aanwezig. Juist dan is het goed deze te benoemen, daarmee wordt de code doorzichtig. Patterns maken het de code ook herbruikbaar, omdat de variatie die er is, of te verwachten is, is ingebed in de pattern structuur.

Welke Patterns zijn er dan? Hier een aantal benoemde, maar er zijn er ongetwijfeld meer. Kijk maar eens in je eigen software en probeer ze aan te wijzen. Kom je regelmatige een structuur tegen die er niet tussen staat, dan heb je vast een nieuwe te pakken.

Creational Patterns

Structural Patterns

Behavioral Patterns

Creational Patterns

Structural Patterns

Behavioral Patterns

Singleton

Doel:

Het Singleton zorgt ervoor dat er van een bepaalde classe maar een (1) instantie bestaat.

Reden:

Van sommige objecten is er maar een nodig of wenselijk of aanwezig.

Implementatie:

Dit is taal afhankelijk:

Wanneer gebruiken:

Er is maar een instantie nodig/wenselijk

Code:

Voorbeeld met Druif, Appel en Peer

Factory

Doel:

Definitie van een interface voor de creatie van een object, maar welke classe wordt geinstancieerd wordt bepaald door door een subclasse.

Reden:

Het direct aanmaken van object is bij grotere systemen al gauw onoverzichterlijk of onmogelijk, indien we code herbruikbaar willen maken.

Implementatie:

Hiervoor is het meestal nodig twee classen te maken, een factory en een basistype voor de gefabriceerde objecten. Van beide kan dan worden overerfd voor specifieke classen. De afgeleide factory is dan in staat het afgeleide basistype aan te maken. In Eiffel kan dat mooi met covariante methode overerving, bij Delphi en Java is typecasten nodig.

Wanneer gebruiken:

  • als je grotere hoeveelheden objecten nodig hebt (direct gebruik)
  • als je van te voren niet weet welke classe moet worden geinstantieerd (gebruik dmv afgeleide classen)
  • als je afgeleide classen een gemeenschappelijk toegang nodig hebben (SOM)
  • als je subclassen taken delegeren aan helperclassen en je zicht wilt deze helperclassen centraal managen
  • Code:

    Voorbeeld met Auto en Garage

    Abstract factory

    Doel:

    Het verstrekken van een interface voor de constructie van een familie van onderling afhankelijke objecten zonder de specifieke classe voor te schrijven.

    Reden:

    Soms wil je een groep van objecten die samen een taak hebben vrij kunnen vervangen door een andere groep objecten die dezelfde taak anders invullen. Dan is het handig de classen hiervan abstract te definieren, en de gebruiker in het onwetende te laten welke concrete classen nu worden gebruikt.

    Implementatie:

    Code:

    Buider

    Doel:

    Het scheiden van de constructie van een complex object van de representatie zdd hetzelfde constructieproces kan worden gebruikt voor meerdere representaties.

    Reden:

    Implementatie:

    Code:

    Prototype

    Doel:

    Maak een object aan dat model staat voor de hele serie objecten die je wilt aanmaken. De constructie van deze objecten geschied door het maken van een kopie.

    Reden:

    Het opnieuw aanmaken van objecten en opvullen met waarden is niet altijd de meest effectieve manier. Hierbij kunnen classen betrokken zijn die niet bekend (zouden moeten ) zijn bij diegene die het object aanmaakt. Dan is een goede manier het maken van een copie vanuit een voorbeeld. Veel gebruikt bij het behandelen van xml documenten.

    Implementatie:

    Code:

    Class Adapter

    Doel:

    Het omzetten van een interface van een classe in een andere interface zodat deze door de client kan worden gebruikt. De adapter laat classen samenwerken die dat niet direct kunnen door incompatibele interfaces.

    Reden:

    Classen die los van elkaar ontwikkeld worden passen vaak niet op elkaar een class adapter (wrapper) is dan nodig.

    Implementatie:

    Code:

    Bridge

    Doel:

    Het ontkoppelen van de abstractie van de implementatie zodat beide onfhankelijk kunnen worden ontwikkeld.

    Reden:

    Wanneer de gebruikelijk wijze om deze ontkoppeling te realizeren (overerving) niet flexibel genoeg is een bridge handig. De abstractie wordt ontworpen aan de behoefte, de implementatie naar de mogelijkheden (bijvoorbeeld klassen die al voorhanden zijn)

    Implementatie:

    Code:

    Composite

    Doel:

    Wanneer elementen op gelijk wijze gebruikt moeten kunnen worden als verzamelingen gebruik je een composite. Deze verpakt objecten in een boomstructuur zdd het voor de classen die ermee werken er geen verschil is tussen een enkel object of een container object.

    Reden:

    Bijvoorbeeld in tekenprogramma's is het vaak zo dat objecten soms alleen en soms tegelijk moeten kunnen worden veranderd. Door de toepassingen van een composite kan dit gemakkelijk worden geimplementeerd.

    Implementatie:

    Code:

    Decorator

    Doel:

    Het dynamisch toevoegen van functies aan een object. Dit als aanvulling op overerving (is statisch)

    Reden:

    Als je functies toevoegt door overerving worden deze meegegeven aan alle instanties van de nieuwe classe. Dat is niet altijd wenselijk. Daarom kun je ook kiezen voor het toevoegen aan objecten afzonderlijk.

    Implementatie:

    Het object dat je wilt uitbreiden wordt ondergebracht in een decorator, waarvan de interface natuurlijk moet overeenkomen met die van het object zodat de gebruikers daar niets van merken. Het oorspronkelijke object moet gewoon kunnen worden gebruikt in de "oude" code.

    Code: