REFACTORING OOP & DESIGN PATTERNS INLEIDING TOT DESIGN PATTERNS NL VERSIE
3 STELLINGEN 1.
Design Patterns zijn een resultaat, geen doel
2.
Goede code is schone code
3.
Refactoring is een essentieel proces
4 ONDERWERPEN 1.
Software ontwikkelproces
2.
Refactoring
3.
OOP principes
4.
Design Patterns
All images and material © Peter Kaptein, 2012
3 STELLINGEN MET BETREKKING TOT DESIGN PATTERNS EN REFACTORING
1: DESIGN PATTERNS: RESULTAAT, GEEN DOEL 1.1: Design Patterns ontstaan (emergence) Als je code schrijft, kom je vanzelf op herhalende patronen in die code. Elk herhalend patroon is in principe een “Design Pattern” 1.2: Design Patterns als doel = begin van ellende Als je het gebruik van Design Patterns als doel stelt ben je niet bezig met het bouwen van een oplossing, maar met de toepassing van theorie. 1.3: Ontwerp en bouw eerst je oplossing, verbeter dan je code
Door eerst je oplossing te ontwerpen bouwen, kom je vanzelf te weten wat relevant en nodig is. Op basis daarvan kun je verbeteringen gaan toepassen.
Link: Refactoring en Design Patterns All images and material © Peter Kaptein, 2012
2: GOEDE CODE IS SCHONE CODE Schrijf je code voor iemand anders Als iemand anders jouw code leest, begrijpt die ander wat er gebeurt? Is duidelijk welke acties waarom worden toegepast? Is duidelijk hoe alles samenhangt? Als je een jaar later je eigen code ziet snap je dan nog wat je toen aan het doen was? Kies voor een duidelijke naamgeving Gebruik inplaats van hahaLOLdinges() en doubleDingesNu() namen als: convertXMLtoElementsOnScreen() Verwijder dode code Dode code is rotzooi die je niet hebt opgeruimd. Het zit in de weg.
Link: Elements of refactoring / clean code All images and material © Peter Kaptein, 2012
3: REFACTORING IS EEN ESSENTIEEL PROCES Wat is refactoring? Refactoring is: “het herzien van code binnen een project zonder de functionaleit van die code te veranderen” Waarom is het essentieel? Betere indeling van je code, betere naamgevingen, betere structuur, minder gedoe later door onduidelijke code.
Link: Refactoring: basics All images and material © Peter Kaptein, 2012
1: SOFTWARE DEVELOPMENT PROCES ONWIKKELING VAN SOFTWARE
BASIS (AGILE / RAD) 1
2
3
4
5
6
Define Focus
Design
Make it work
Make it better
Make it awesome
Release
Build, Test, Deliver
Build, Test, Deliver
Build, Test, Deliver
Working proof of concept
Betaversion
Release version
Basic requirements
Paper prototype
Link: Cycles of software development All images and material © Peter Kaptein, 2012
BASIS VOOR SUCCES: GELAAGDE AANPAK Kern voor succes: 1.
Elke fase in bouw leidt tot iets dat werkt en gedemo-ed kan worden
Lagen 1.
Working proof of concept: werkt al redelijk, kan getoond worden aan opdrachtgever, geeft idee van voortgang
2.
Alpha en Beta-versie: tonen de basis en een al “leverbare” versie van de game. Alle noodzakelijke dingen zitten erin. De gewenste en leuke dingen nog niet. De game gaat er met elke nieuwe fase al als een echte game uitzien
3.
Definitieve versie: Hierin is de game “af ”. Alle fouten zijn opgelost, de assets zien er goed uit en alle noodzakelijke en gewenste onderdelen zitten in de game. Link: Cycles of software development All images and material © Peter Kaptein, 2012
VEEL GEMAAKTE FOUTEN: WAAROM IETS NIET AF KOMT A: Verkeerde focus / verkeerde prioriteiten 1.
Eerst alles mooi maken, dan werkend
2.
Eerst een perfect (software) ontwerp, dan bouwen
3.
Eerst bouwen, dan een plan maken
4.
Teveel aandacht aan bijzaken / vergeten van de hoofdzaken
B: Onenigheid in het team 1.
Geen overeenstemming in wat de game moet gaan doen
2.
Geen overeenstemming in hoe de game er uit moet zien
Resultaat: 1.
Geen (of slecht) werkende game
2.
Boze / teleurgestelde klant
3.
Geen geld / geen beoordeling / geen cijfer Link: Cycles of software development All images and material © Peter Kaptein, 2012
OPLOSSINGEN A: Focus / prioriteitenlijst (in volgorde van belang): 1.
Scheiding van hoofdzaken en bijzaken
2.
Bouwen van een werkende game
3.
Maken van mooi uitziende assets
4.
Relisatie van leuke extra’s zoals mooiere animaties en leuke intros
B: Team 1.
Kies 1 leider / eindverantwoordelijke
2.
Focus op 2 dingen (dit is je enige wetmatigheid en dogma):
3. 4.
1. Resultaat 2. Deadlines Overleg, wees het met elkaar oneens, vecht voor je gelijk, maar leg je neer bij eindbesluit van de leider/eindverantwoordelijke Vergeet ego, machtstrijd en “ik heb gelijk”. Zelfs een “slecht” resultaat is beter dan geen resultaat Link: Cycles of software development All images and material © Peter Kaptein, 2012
BASIS (AGILE / RAD) 1
2
3
4
5
6
Define Focus
Design
Make it work
Make it better
Make it awesome
Release
Build, Test, Deliver
Build, Test, Deliver
Build, Test, Deliver
Working proof of concept
Betaversion
Release version
Basic requirements
Paper prototype
Link: Cycles of software development All images and material © Peter Kaptein, 2012
STAP 1: FOCUS Basisvragen: 1.
Wat wil je maken?
2.
Wat is er nodig? (Requirements)
3.
Hoe veel tijd is er?
4.
Wat wil je bereiken? (Kwaliteitsniveau, eindresultaat, type success, aantal spelers, score in game reviews)
5.
Wat kun je bereiken in de beschikbare tijd? (Tijdsinschatting, priorisering/ MoSCoW)
6.
Wat ga je concreet doen?
Resultaat:
1.
Basic requirements-document Link: Cycles of software development All images and material © Peter Kaptein, 2012
STAP 2: (SOFTWARE) DESIGN Basis: 1.
Hoe gaat het werken?
2.
Wat zijn de basisonderdelen / wat moet er allemaal gemaakt worden?
3.
Hoe hangen de dingen/onderdelen samen?
Resultaat: 1.
Paper prototype: tekeningen en schetsen op papier
Link: Cycles of software development All images and material © Peter Kaptein, 2012
STAP 3: MAAK EEN EERSTE WERKENDE VERSIE Basis:
Focus voor Code 1.
Bouw van een working proof of concept op basis: “Must haves”
2.
Zorg dat het werkt
3.
Zorg dat het speelbaar is
4.
Besteed nog geen aandacht aan mooimakerij
Focus voor Design 1.
Bepaal de basisstylen, het basisgevoel
2.
Lever basis-assets
3.
Besteed nog geen aandacht aan mooimakerij
Resultaat (1 tot 2 weken):
1.
Working proof of Concept Link: Cycles of software development All images and material © Peter Kaptein, 2012
WAAR ZOU JE MET STAP 3 MOETEN ZIJN? Code 1.
Er zijn nog wat bugs, maar de meeste stomme fouten zijn er uit
2.
De game-play kan gedemonstreerd worden
3.
De game kan al enigszins gespeeld worden
Design 1.
De game kan al wat elementen bevatten die tonen hoe dingen eruit komen te zien
2.
Dit is nog verre van definitief
Resultaat: 1.
Er is het begin van een werkende game
Volgende stap: 1.
Je gaat dingen beter maken Link: Cycles of software development All images and material © Peter Kaptein, 2012
STAP 4: DINGEN BETER MAKEN Focus voor Code 1.
Gameplay beter maken, gameplay afmaken
2.
Focus nog steeds op “Must haves”, verschuiving naar “Could haves”
3.
Fouten wegwerken, optimalisatie van performance en game-play
4.
Focus op implementatie design
Focus voor Design 1.
Afmaken van assets
2.
Test van assets in gameplay
3.
Verfijning en verbetering van grafische elementen
Resultaat (1 tot 2 weken): 1.
Game moet nu geheel doorgelopen kunnen worden
2.
Score en mechanismes voor levels werken
3.
Basis-game werkt en is eigenelijk al “klaar” Link: Cycles of software development All images and material © Peter Kaptein, 2012
WAAR JE NU BENT Game 1.
De game is speelbaar en “klaar”
2.
De assets zien er goed genoeg uit
3.
Als dat zou moeten zou de game opgeleverd kunnen worden
Volgende stappen: 1.
De game kan nu mooi(er) gemaakt worden
2.
Je kunt nu eindeloos gaan schaven aan betere gameplay en nog betere samenhang
Link: Cycles of software development All images and material © Peter Kaptein, 2012
STAP 5: DE GAME FANTASTISCH MAKEN Focus voor Code: 1.
Dingen herzien en nog beter maken
2.
Nieuwe functionaliteiten toevoegen die op “Nice to have” lijst staan
3.
Nog meer optimalisaties in performance en game-play
Focus voor Design 1.
Dingen beter maken die nog niet goed overkomen.
2.
Meer elementen / afwisseling?
3.
Intro’s, animaties en ander eye-candy
Resultaat: 1.
De game oogt werkelijk slick en werkt foutloos
Link: Cycles of software development All images and material © Peter Kaptein, 2012
BUILD, TEST AND DELIVER 1
2
3
Build
Test
Deliver
Build, Test, Refactor
Test, Register bugs, Fix
Working proof of concept
Release version Link: Cycles of software development All images and material © Peter Kaptein, 2012
STAP 1: BOUWEN Focus voor Code 1.
Bouwen van code waarmee requirements worden gehaald
2.
Testen van de code
3.
Refactoring van de code waar deze rommelig wordt
Focus voor Design 1.
Maken van de assets
2.
Testen of de assets er goed uitzien in de resolutie van de game
Resultaat: 1.
Working proof of concept
2.
De game, of delen van de game, kunnen gespeeld/gedemood worden
All images and material © Peter Kaptein, 2012
STAP 2: TEST Focus voor Code 1.
Testen van de code
2.
Maken van buglist op basis van bevindingen en tegen lijst van requirements
3.
Fixen van de bugs
Focus voor Design 1.
Testen van assets: ziet het er goed uit? Komt alles goed over?
Resultaat: 1.
Een game die opgeleverd kan worden naar de volgende fase
All images and material © Peter Kaptein, 2012
STAP 3: OPLEVEREN 1.
Online
2.
Store / market
3.
Volgende fase
4.
Klant
All images and material © Peter Kaptein, 2012
2: REFACTORING BASIS-ELEMENTEN VAN HET REFACTORING PROCES
VISUALISATIE VAN HET REFACTORING PROCES 1
2
A
3
A
A
B
B 4
B
5
6
A
A
B
A
B
B
Link: Refactoring en Design Patterns All images and material © Peter Kaptein, 2012
BOUWPROCES ZONDER REFACTORINGS Ideal productivity line
an d In
Productivity
In d a
E ff
ork w ve ecti
g
on z r e
nge r zo
e
ne
Amount of required work
E ffe ctiv ew ork
Time Amount of required work Productivity line
Link: Coding without refactoring All images and material © Peter Kaptein, 2012
BOUWPROCES MET REFACTORINGS Ideal productivity line Effective work
Effective work
Danger zone
Amount of required work
Productivity
Refactorings
Time Amount of required work Productivity line
Link: Coding with refactoring All images and material © Peter Kaptein, 2012
WINST VAN REFACTORING: BEHOUD PRODUCTIVITEIT Ideal productivity line Stabilization of productivity levels
Danger zone
Productivity Time Process without refactorings Process with refactorings
Link: Comparison All images and material © Peter Kaptein, 2012
BASISREGELS: WANNEER REFACTOR JE? 1.
Tijd en effictiviteit: Op het moment dat je meer tijd kwijt bent met “uitzoeken hoe het werkt” dan met het bouwen van nieuwe code, is het tijd voor een refactoring slag
2.
Helderheid: Op het moment dat je niet meer precies snapt wat er gebeurt, is het tijd voor een refactoring.
3.
Overzicht: Is het nog wel duidelijk waar wat gebeurt? Nee? Tijd voor een refactoring.
Link: When will you Refactor? All images and material © Peter Kaptein, 2012
WAT LEVERT REFACTORING OP? Schonere- en beter gestructureerde code De eerste en meest duidelijke winst van refactoring is schonere en beter gestructurerde code: beter leesbaar, duidelijker wat waar gebeurt, minder dode code. Tijdwinst over langere tijd Hoe schoner en beter gestrucutreerd je code is, des te minder tijd je kwijt bent aan het uitzoeken van samenhang en werking van de bestaande code. Productiever over langere tijd Met schone en duidelijke code kun je over langere tijd steeds productiever worden. Kort samengevat: je hebt steeds minder tijd nodig om steeds meer resultaat te bereiken.
Link: Why is Refactoring beneficial? All images and material © Peter Kaptein, 2012
3 PRIMAIRE SOORTEN REFACTORING 1.
Refactoring van naamgevingen
2.
Refactoring van processen
3.
Refactoring van (project) structuren
Links: Refactoring of names Refactoring of processes Refactoring of structures All images and material © Peter Kaptein, 2012
1: REFACTORING VAN NAAMGEVINGEN A: Variable-namen Zijn verablenamen duidelijk? Geven ze weer waarvoor ze gebruikt worden en wat voor objecten of informatie ze bevatten? B: Methodenamen Drukken de methodenamen uit wat voor actie er uitgevoerd gaat worden? Is duidelijk wat je terug kunt verwachten? B: Class-namen
Drukken class-namen uit wat voor objecten en acties ze representeren? Is de naam generiek en specifiek genoeg?
Link: Refactoring of names All images and material © Peter Kaptein, 2012
2: REFACTORING VAN PROCESSEN A: Verduidelijking van de processen Wat gebeurt waar en waarom? Is dat logisch? Is het logisch om dat daar te doen? Hoeveel verschillende processen lopen er door elkaar? B: Extractie en abstractie van code naar nieuwe methodes Is het mogelijk om onderdelen van de code te isoleren en in aparte methodes te plaatsen? C: Extractie en abstractie naar externe classes
Is het handig en logisch om code naar externe classes te verplaatsen? Wordt deze code en deze methodes mogelijk hergebruikt? Is er sprake van herhaling? (Copy & Paste code.) Links:
Link: Refactoring of processes All images and material © Peter Kaptein, 2012
3: REFACTORING VAN STRUCTUREN A: Samenhang van elementen Wie communiceert met wat? Hoe zijn onderdelen aan elkaar gekoppeld? Welke afhankelijkheden bestaan er? Wie verwijst naar wat en hoeveel lagen zitten daartussen? B: Verwijderen en toevoegen van (abstractie) lagen Hoeveel stappen moet je doen om van A naar B te komen (schakels in de keten)? Hoe hard zijn bepaalde onderdelen aan elkaar gekoppeld? Wat als je veranderingen wilt aanbrengen of meer flexibel wilt zijn in de uitvoering van bepaalde processen? C: Organisatie van bestanden en Class-packages Wat staat waar? Zijn bestanden logisch bij elkaar geplaatst? Kun je alles goed terugvinden of is je project een zoekplaatje?
Link: Refactoring of structures All images and material © Peter Kaptein, 2012
GEVAREN MET BETREKKING TOT REFACTORING Eindeloos navelstaren Code is nooit perfect en dingen kunnen altijd schoner en beter dan ze al zijn. Dit kan leiden tot een soort eindeloze Refactoring-deadlock waarin je alleen nog maar aan het refactoren bent om de ultieme code te bereiken en waarin geen enkele vooruitgang wordt geboekt. Refactoring deadlocks In een Refactoring-deadlock is de voortgang in het project geblokkeerd tot de Refactoring-slag is afgerond.
Links: Link: Refactoring Pitfalls and dangers All images and material © Peter Kaptein, 2012
AANPAK Stap 1: Refactoring Shitlist Je begint met een Refactoring Shitlist. Deze lijst bevat alle dingen die je op dat moment in de weg zitten. Stap 2: Priorisering / MoSCoW Op basis van de tijd die je hebt om het project als geheel af te ronden, pak je de meest belangrijke elementen eerst. Bepaal dus welke refactoring-slagen Must have, Should have, Could have and Would have zijn. Stap 3: Time-boxing / tijdlimiet Bepaal een tijdlimiet per refactoring-slag. Doe dit op basis van je deadlines en tijd die je nog nodig denkt te heben.
Stap 4: Maak een backup Aangezien je refactoring fout kan gaan, is het handig om een backup te maken zodat je daar naar terug kan grijpen. Stap 5: Tijd om te Refactoren! Begin het refactoringproces. Links: Link: The steps in a refactoring process All images and material © Peter Kaptein, 2012
WANNEER IS EEN REFACTORING-SLAG AFGEROND? Als de lijst van issues is afgerond Uiteraard maak je een lijst van issues voordat je begint. Als alle basisproblemen in een bepaald stuk van je code zijn opgelost ben je klaar met refacoteren. Zelfs als er mogelijk nog andere verbeteringen kunnen woren gemaakt. Deze zijn voor een latere refactoring-slag. Als de tijd op is Je hebt in je voorbereiding hopelijk een duidelijke en realistiche tijdlimiet gesteld. Als deze limiet is bereikt, is het tijd om je refactoring af te ronden. Dit kan soms (bij een niet-succesvolle refactoring) tot een complete roll-back leiden van al je veranderingen. Als je code goed genoeg is Een refactoring-slag is ook afgerond als je code goed genoeg is om verder te gaan. Links: Link: When is the refactoring process done? All images and material © Peter Kaptein, 2012
OVERZICHT VAN EEN OOP APPLICATIE «base classes abstract classes interfaces»
D: «can extend or implement»
Abstract Class A Base Class B
C: «can pass execution/ request through to / can be dependent of»
«other classes and objects»
Interface C
Class A Class B 2: «can contain 1: «can extend or implement» reference to object from» Your Class
Class C
«separate actions and processes»
- someObject + doSomething(): do process A.1 do process B do process A.2 do process C do process A.3 + doSomethingElse() + doProcessA( object ) 5: «can be used to create» An Object
B: «be placed into / encapsulated by / can refer to»
3: «can be extracted as»
do process A.1 do process A.2 do process A.3
do process B do process C
4: «can be encapsulated into methods into» A: «can be used by»
Link: Refactoring en Design Patterns All images and material © Peter Kaptein, 2012
HET REFACTORINGPROCES VISUEEL SAMENGEVAT #1 Refactoring
1
Shitlist
2
MoSCoW / Priorization
3
SandBoxing / Deadline
4
Backup current
5
Refactor
1: What is wrong? 2: What can be improved? 1: Define MoSCoW: a: Must-, Should-, Could- , Would have 2: Check: a: What are the quick-wins? b: What is more difficult? c: What is most important? d: What can be done later? 3: Keep Must-haves and quick wins 4: Remove everything that is not quick win / must have 1: Define the sandboxes a: How much time do you have? b: What will you do when and in how much time? c: When is the cut-off point?
1: Save the current version so you can restore it 1: Start refactoring 2: Do you still have time? a: Yes: continue b: No: abort? c: Does it work / compile? 3: Out of time a: Broken? à Roll-back old version b: Working? à Check in refactored code
Link: Refactoring en Design Patterns All images and material © Peter Kaptein, 2012
HET REFACTORINGPROCES VISUEEL SAMENGEVAT #3 Refactoring (project) structures
Improvement of project structure
file structure / class packages
adding and removing (abstraction) layers
interaction between elements
Clarification and reduction of dependencies
Class B Class C
Class C «# of layers increased / decreased»
«base classes abstract classes interfaces»
«organization of classes and files»
Class A
Class A
Class A Class C
Abstract Class A
Class B
Base Class B
«code extracted and promoted to»
Interface C
«classes and objects»
Class C
Class A
«organized structure put back into»
Class B Class C
«cleaner code put back into»
A B «clarificarion of processes»
A
Your Class - someObject + doSomething(): do process A.1 do process B do process A.2 do process C do process A.3 + doSomethingElse() + doProcessA( object )
«code extracted and abstracted»
do process B
do process A.1 do process A.2 do process A.3
do process C
To Methods
B
Cleaner code
To Classes
extraction and abstraction of code
clarification of processes
Refactoring of processes
«extracted code put into / promoted to»
«extracted actions and processes»
Promotion of code (to separate methods)
Promotion of code (to classes)
Link: Refactoring en Design Patterns All images and material © Peter Kaptein, 2012
3: OOP PRINCIPES BASISPRINCIPES IN OBJECT – GEORIENTEERD PROGRAMMEREN
OOP LEERCURVE Hard to understand
Difficulty in understanding
OOP learning curve
Procedural programming learning curve Progress of time
All images and material © Peter Kaptein, 2012
PROBLEEM MET PROCEDURAL PROGRAMMEREN
Time spent / Speed of progress
Speed of progress
Time spent on complexity
Progress of the project
All images and material © Peter Kaptein, 2012
BELOFTE VAN OBJECT GEORIENTEERD PROGRAMMING
Time spent / Speed of progress
Speed of progress
Time spent on complexity
Progress of the project
All images and material © Peter Kaptein, 2012
VALKUILEN Dingen te mooi willen doen OOP biedt voldoende ruimte voor simpele oplossingen en korte lijnen. Het is echter verleidelijk om met OOP alles meteen “goed” te doen en verschiedene lagen van abstractie toe te voegen die in boeken zijn beschreven of aanbevolen worden door bepaalde programmeurs en experts. Overgecompliceerde code Code moet nooit complexer zijn dan je zelf kunt begrijpen. Zodra je code complexer wordt dan dat, gaat er iets fout en wordt het tijd om een stap terug te doen. Dingen op een procedurele wijze in OOP proberen op te lossen Procedurele code heeft een bepaalde manier om bepaalde dingen te doen. OOP heeft andere manieren. Sommige kunnen niet gecombineerd worden.
Link:
All images and material © Peter Kaptein, 2012
Time spent / Speed of progress
ALS OBJECT GEORIENTEERD PROG. FOUT GAAT
Speed of progress Time spent on complexity
Progress of the project
All images and material © Peter Kaptein, 2012
7 BASISPRINCIPES 1.
Classes en objecten
2.
Scoping via public, private en static
3.
Verwijzingen en afhankelijheden
4.
Extratie en Abstractie van code en processen
5.
Encapsulatie van code en processen
6.
Concrete, Basis en Abstracte classen
7.
Delegatie van acties en processen
All images and material © Peter Kaptein, 2012
1: CLASSES EN OBJECTEN Een Class bevat code Een Class representeert een object, speler of handeling Een Class kan een Object produceren Een class kan een object produceren. Dit Object is een gesloten universum voor alle locale variables en methodes die binnen een class gedefinieerd zijn.
All images and material © Peter Kaptein, 2012
2: SCOPING VIA PUBLIC, PRIVATE EN STATIC Public = toegankelijk van buitenaf Publieke variables en methodes zijn van buitenaf toegankelijk en kunnen worden gebruikt en aangeroepen door andere objecten in je project. Private = niet toegankelijk en zichtbaar van buitenaf Prive-variabelen en prive-methodes zijn alleen zichtbaar en benaderbaar binnenin je Class. Static = toegankelijk op Class-niveau Statische variablen en methodes kunnen direct op Class-niveau worden aangeroepen. Je hoeft dus geen object aan te maken van die Class. Statische variablen en methodes hebben een aantal voordelen, maar worden vervloekt door Unit-testers.
All images and material © Peter Kaptein, 2012
3: VERWIJZINGEN EN AFHANKELIJKHEDEN Verwijzingen in OOP: geheugenadressen Verwijzingen in OOP gebeuren in de meeste gevallen naar addressen in het geheugen waar een bepaalde waarde of een bepaald object gevonden kan worden. Dit houdt onder andere in dat als je wijzigingen maakt op een object dat wordt meegestuurd in een methode-aanroep, deze wijziging overal zichtbaar wordt waar dat object gebruikt wordt. Afhankelijkheden: kan problemen geven Er zijn drie probleemgebieden met betrekking tot afhankelijkheden: 1.
Geheugenmanagement en garbage-collectie. Als ergens nog een referentie bestaat naar een bepaald object wordt deze niet uit het geheugen verwijderd
2.
A heeft B nodig om C te doen. Dit kan bijvoorbeeld leiden tot code die rigide is als deze afhankelijkheden hardcoded zijn. Maar ook tot het falen van processen als B ergens in een keten zat die nu verbroken is.
3.
Ketens van afhankelijkheden. A heeft B nodig om C te doen, maar moet eerst via D, E en F. Zodra een van deze schakels z’n werk niet goed doet is de keten verbroken en werkt je applicatie niet meer.
All images and material © Peter Kaptein, 2012
4: EXTRACTIE EN ABSTRACTIE VAN CODE EN PROCESSEN Extractie Extractie is het isoleren en “uit de code trekken” van een bepaalde set van acties. Abstractie Bij het abstract maken van acties, worden de concrete stappen verborgen achter een “abstracte” handeling. Dit kan een methode zijn waarin je de concrete code plaatst, of een Concrete Class waarin deze concrete methodes en acties zijn opgenomen.
All images and material © Peter Kaptein, 2012
5: ENCAPSULATIE VAN CODE EN PROCESSEN Encapsulatie Encapsulatie is het “inwikkelen” of “omvatten” van “iets”. In het geval van OOP betreft dit “iets” een blok code of een proces. Encapsulatie omkadert de code en het proces. Encapsulatie in methodes De eerste vorm van encapsulatie is door bepaalde acties en processen in een methode te plaatsen. De methode “omkadert” de code en biedt een duidelijke interface waarmee die code bereikt kan worden. Encapsulatie in Classes Als processen generiek zijn en op meerdere plaatsen herbruikt kunnen worden, maar ook als een bepaalde class teveel verantwoordelijkheid krijgt is het raadzaam om code te “omkaderen” in een (nieuwe) Class.
All images and material © Peter Kaptein, 2012
6: CONCRETE, BASIS EN ABSTRACTE CLASSES Abstracte Classen en Interfaces Abstract Classen en Interfaces zijn Classen waarin geen concrete code is opgenomen. Ze beschrijven alleen wat er moet gebeuren, maar niet hoe dat gebeurt. Abstracte Classes en Interfaces zijn vrijwel gelijk aan elkaar, met dit verschil dat een Interface wordt geimplementeerd en een Abstracte Class ge-extend. Concrete Classen Concrete Classen bevatten de Concrete Implementatie van een Abstracte Class of een Interface. Basis-Classen Basis-Classen (Base Class) zijn Concrete Classen die een bepaalde set van basisfunctionaliteiten bevatten die in elk van de sub-classen nodig zijn en worden toegepast voor bepaalde basisprocessen.
All images and material © Peter Kaptein, 2012
7: DELEGATIE VAN ACTIES EN PROCESSEN Zelf doen of uitbesteden? Bij Delegatie besteed je een actie of proces uit naar een methode of naar een andere Class of Object. Delegatie naar methodes
Inplaats van uitgebreide blokken code te schrijven, kun je deze blokken opknippen en in methodes plaatsen. De uitvoer wordt vervolgens door jouw code gedelegeerd naar die methodes. Delegatie naar Objecten
Inplaats van dingen locaal te doen, kunnen bepaalde acties en processen ook via een ander Object worden uitgevoerd. Delegatie naar Statische Methodes Het is niet altijd wenselijk om overal Objecten voor aan te maken. In sommige gevallen is het eenvoudiger en schoner om direct een statische Methode op een Class aan te roepen.
All images and material © Peter Kaptein, 2012
VISUELE SAMENVATTING «base classes abstract classes interfaces»
D: «can extend or implement»
Abstract Class A Base Class B
C: «can pass execution/ request through to / can be dependent of»
«other classes and objects»
Interface C
Class A Class B 2: «can contain 1: «can extend or implement» reference to object from» Your Class
Class C
«separate actions and processes»
- someObject + doSomething(): do process A.1 do process B do process A.2 do process C do process A.3 + doSomethingElse() + doProcessA( object ) 5: «can be used to create» An Object
B: «be placed into / encapsulated by / can refer to»
3: «can be extracted as»
do process A.1 do process A.2 do process A.3
do process B do process C
4: «can be encapsulated into methods into» A: «can be used by» All images and material © Peter Kaptein, 2012
4: DESIGN PATTERNS BASIS-ELEMENTEN VAN DESIGN PATTERNS
4 BELANGRIJKE ASPECTEN IN DESIGN PATTERNS 1: Abstractie en extractie: loskoppelen en verplaatsen van acties Design Patterns kunnen helpen om processen uit een bepaalde context te halen (je code) en ze ergens anders te plaatsen (een neiuwe Class) 2: Hergebruik en flexibiliteit: het resultaat van abstractie en extractie Door abstractie en extractie kun je bepaalde delen makkelijker en beter hergebruiken. De onderdelen die uit je code zijn gehaald zijn daarnaast makkelijker te vervangen voor een andere oplossing. 3: Delegatie: iemand anders het werk laten doen Vrijwel alle Design Patterns maken gebruik van Delegatie: het uitbesteden van een opdracht aan iemand anders. 4: Structuur Vrijwel alle patronen gaan over structuur. Wat maakt een patroon dat specifieke patroon? Welkde onderdelen zijn er? Hoe werken ze samen? Links: All images and material © Peter Kaptein, 2012
3 SOORTEN PATRONEN “Design Patterns” definieert 3 soorten patronen: 1: Creational Creationele Patronen abstraheren de manier waarop objecten worden aangemaakt (creatie). Hierdoor wordt het mogelijk en makkelijker om verschillende alternatieven te implementeren. 2: Behavioral Behaviorele Patronen houden zich bezig met processen, de bepaling wie wat doet en uitvoert en hoe er gecommuniceerd wordt binnen je applicatie. 3: Structural Structurele patronen beschrijven hoe je een classes en objecten combineert om grotere structuren te maken. Link: Type patronen volgens GoF All images and material © Peter Kaptein, 2012
1: CREATIONELE PATRONEN 1.
Factory Method * – Omschrijft een structuur waarin via een soort “afspraak” (de Interface) specifieke methodes worden afgedwongen om producten te bouwen.
2.
Abstract Factory * – Is een “bouwinstructie” voor concrete Factories die allemaal dezelfde soorten producten maken.
3.
Builder – Omschrijft een manier om dynamisch producten samen te stellen, door gebruik te maken van onderdelen die via een “constructor” aan elkaar worden gekoppeld.
4.
Prototype -
5.
Singleton – Omschrijft een manier om slechts een instantie van een Class te maken en altijd alleen deze versise terug te geven als iemand or om vraagt.
* Een Factory doet in de basis niet veel meer dan dit: return new JouwObject(); Indeling Link: Creationele patronen All images and material © Peter Kaptein, 2012
2: STRUCTURELE PATRONEN 1.
Adapter – Past de interface van een bestaand object of Class aan zodat deze voldoet aan de wensen van je code.
2.
Bridge – Kan gebruikt worden als een basis-Class, delegeert alle acties naar een ander object en kan gedrag veranderen door dat object te veranderen voor een andere.
3.
Composite – Omschrijft de basisopzet voor objecten waarmee je een samengesteld object (composite / boomstructuur) kunt maken.
4.
Decorator – Maakt het mogelijk om eigenschappen aan een object toe te voegen door dit object te “omhullen” (wrapping).
5.
Façade – Beschrijft een manier om de toegang tot een subsysteem te vereenvoudigen, door deze te “omhullen” (wrapping).
6.
Flyweight – Beschrijft een manier om objecten te delen binnen een applicatie. Belangrijkste doel is het aantal benodigde objecten te beperken tot een absoluut minimum, zodat je geheugen bepaart.
7.
Proxy – Werkt als een “man in the middle”. Zorgt ervoor dat je handelingen op objecten kunt plegen terwijl die objecten er nog niet zijn. Overzicht Link: All images and material © Peter Kaptein, 2012
3: BEHAVIORALE PATRONEN 1.
Chain of responsibility – Beschrijft een aanpak waarin een object een gevraagde actie kan uitvoeren, of doorsturen naar de volgende in de keten 2. Command – Object dat een bepaald commando uitvoert. Commandos kunnen in een lijst worden geplaatst en in een bepaalde volgorde worden uitgevoerd 3. Interpreter – Interpreteert een taal en vertaalt dit naar een objectstructuur waarin de semantische samenhang is omschreven 4. Iterator – Beschrijft een aanpak om door een lijst van objecten heen te stappen (iteratie) 5. Mediator – Centraliseert de communicatie tussen objecten in een subsysteem en bemiddelt wie welke acties uitvoert 6. Memento – Beschrijft hoe je een momentopname van objecten in je applicatie kunt maken 7. Observer – Wordt gebruikt om acties los te koppelen van objecten. 8. State – Verandert gedrag van het object als de status van het proces verandert. 9. Strategy – Haalt delen van het proces (de strategie) uit het object en maakt het mogelijk deze als “plugins” te gebruiken. Elke “plugin” is een andere Strategie. 10. Template Method – Beschrijft een manier om een bepaalde combinatie van acties (de template) als basis te gebruiken endeze vervolgens situatie-specifiek aan te passen. 11. Visitor – Bezoekt een objectstructuur en voert handleingen met de objecten binnen die structuur uit. Overzicht Link: All images and material © Peter Kaptein, 2012
ALTERNATIEVE INDELING: WAT DOEN ZE? De indeling volgens “Design Patterns” is wellicht niet de meest handige. Hier is een alternatieve indeling: A. Patronen die acties naar een ander object delegeren B. Patronen die acties naar een subsysteem delegeren C. Patronen die een deel van de acties naar een ander object delegeren D. Patronen die functionaliteiten toevoegen
E. Patronen die objecten produceren F. Patronen voor samengestelde objecten G. Patronen die over communicatie gaan H. Patronen die over Objectbeheer gaan < Soorten patronen Link: All images and material © Peter Kaptein, 2012
A: PATRONEN DIE ACTIES NAAR EEN OBJECT DELEGEREN 1.
Adapter – Delegeert acties naar het object / de class die niet compatible is met de wensen van jouw code.
2.
Command – Delegeert acties naar het object dat in het Command Object is geinjecteerd. Wordt gebruikt om ergens anders de actie aan te roepen.
3.
Proxy – Werkt als een plaatsvervanger / vertegenwoordiger en geeft alle aanvragen door (delegatie) zodra het werkelijke object er is
4.
State – Delegeert naar een State Object, die zichzelf vervangt als de staat van het proces verandert.
5.
Bridge – Delegeert acties naar een Object binnen het “Bridgeobject” dat op dat moment het gewenste gedrag bevat. Overzicht Link: All images and material © Peter Kaptein, 2012
1: ADAPTER – AANPASSING VAN OBJECT-INTERFACE 1: «uses» Your Class
Adapter A
2: «instantiates / contains / wraps / adapts / addresses»
ClassA / ObjectB
KORT: De Adapter biedt een andere interface aan voor een object (of Class) zodat deze voldoet aan de behoeften van jouw code. Overzicht Link: Adapter All images and material © Peter Kaptein, 2012
2: COMMAND – DELEGATE VOOR SPECIFIEKE ACTIES Some System 2: «provides the command to»
1.b: «passes command to»
Object A
1.a: «injects Some Object into» 3: «uses»
Your Object
1.b: «can be / can instanitate»
Some Command
4.b: «executes actions on»
Some Object
KORT: Het Command Patroon geruikt een Command Object om een actie uit te voeren op een ander object. Dit object wordt door de aanbieder (“Object A”) in het Command Object geinjecteerd.
Overzicht Link: Command All images and material © Peter Kaptein, 2012
3: PROXY – PLAATSVERVANGER 1: «uses» Your Class
Proxy A
2: «instantiates / represents / will contain / will address»
Object B
KORT: De Proxy is een plaatsvervanger voor een object dat pas later wordt aangemaakt. De Proxy geeft alles door aan het concrete object (Object B) zodra dit er is.
Overzicht Link: Proxy All images and material © Peter Kaptein, 2012
4: STATE - PROCESGERICHT Your Code
1: «instantiates / addresses»
State Context A State Object A
2: «has a / addresses» State container vatiable
State Object B 3: «contains» 4.a: «changes» State Object C State Object X
KORT:
4.b: «is either / has knowledge of»
Het State Patroon richt zich specifiek op processen die na elke actie in een andere staat kunnen komen. Per staat is een specifiek State Object beschikbaar.
Elk State Object heeft dezelfde interface met dezelfde publieke methodes, die intern per echter anders worden afgehandeld.
Overzicht Link: State All images and material © Peter Kaptein, 2012
5: BRIDGE – CLASS DIE EIGEN GEDRAG KAN AANPASSEN «extends» Your Class
Bridge
«uses: either / principle of»
«pretends to be / delegates actions to»
Factory
«returns»
Product / Concrete implementation
KORT: De Bridge maakt het mogelijk om een Class te maken die zijn eigen gedrag kan veranderen als dat nodig is. De Bridge werkt vrijwel hetzelfde als een Adapter door alle acties door te geven (delegatie)
Overzicht Link: Bridge All images and material © Peter Kaptein, 2012
B: PATRONEN DIE NAAR EEN (SUB)SYSTEEM DELEGEREN 1.
Mediator – Centraliseert alle communicatie binnen het subsysteem en delegeert de gevraagde acties naar andere objecten binen dat systeem
2.
Façade – Simplificeert de het gebruik en de toegang tot een sybsysteem en delegeert alle acties om een bepaalde taak uit te voeren naar dat subsysteem.
All images and material © Peter Kaptein, 2012
1: MEDIATOR – CENTRALISATIE VAN COMMUNICATIE «addresses»
«uses» YourClass
MediatorA
Class E «addresses» «addresses»
«addresses»
«addresses»
«addresses»
Class A
Class B
«subsystem»
KORT: De Mediator centraliseert de communicatie in je subsysteem. Goede vervanger voor Events. All images and material © Peter Kaptein, 2012
2: FAÇADE – VEREENVOUDIGING GEBRUIK SUBSYSTEEM 1: «uses» YourClass
Façade A
2: «wraps / adapts / addresses / simplifies use of» «subsystem A»
Class A
Class B
Class C
ClassE
Class D
KORT: De Façade vereenvoudigt het gebruik van een (sub) systeem door alle acties die je anders expliciet op dat systeem zou moeten uitvoeren in specifieke methodes in de Façade te stoppen. All images and material © Peter Kaptein, 2012
C: PATRONEN DIE EEN DEEL VAN DE ACTIES DELEGEREN 1.
Strategy – Voert het merendeel van de acties intern uit, delegeert alleen die acties naar een ander object die variabel / situatiespecifiek zijn
2.
Chain of responsibility – Voert alles intern uit, behalve de acties die in de “keten van verantwoordelijkheden” past.
All images and material © Peter Kaptein, 2012
1: STRATEGY Your Class
1.b: «instantiates»
Class X / Strategy Y
1.a: «uses / addresses / inject strategy into»
4: «is injected into»
Context Object A
2: «contains»
3: «uses / addresses» Concrete Code
KORT: De Façade vereenvoudigt het gebruik van een (sub) systeem door alle acties die je anders expliciet op dat systeem zou moeten uitvoeren in specifieke methodes in de Façade te stoppen. All images and material © Peter Kaptein, 2012
2: CHAIN OF RESPONSIBILITY
All images and material © Peter Kaptein, 2012
D: PATRONEN DIE FUNCTIONALITEITEN TOEVOEGEN 1.
Decorator – Bevat extra functionaliteiten en “voegt deze toe” aan het doel-object door het doel-object te omhullen en als “man in the middle” alle aanroepen over te nemen van dat doel-object.
All images and material © Peter Kaptein, 2012
1: DECORATOR 1.a: «has» Your Class
Class A / Object B
1.b: «injects Object into / uses functionalities of»
2.b: «contains / wraps / decorates / addresses»
Decorator C 3: «extend» 2.a: «offers»
Added / altered functionalites to existing methods
KORT: De Decorator voegt extra functionaliteiten toe aan een bestaand object en bestaande methodes door het te omhullen. Decorators kunnen andere decorators omhullen. All images and material © Peter Kaptein, 2012
E: PATRONEN DIE OBJECTEN PRODUCEREN 1.
Factory Method – Laat het aan jouw object over om de “voorgeschreven” Factory-methodes te implementeren en vanuit deze methodes Objecten (Producten) te produceren.
2.
Abstract Factory – Is “de volgende stap” voor de Factory Method. Inplaats dat jouw object de Factory-methodes implementeert laat je dat doen door een ander Object: de “Concrete Fabriek”
3.
Simple Factory – Is de meest gebruikte variant op de Factorypatronen
4.
Builder – Bestaat uit twee delen: de “Director” en de “Concrete Builder”. De Director geeft aan hoe er gebouwd gaat worden. De Concrete Builder voert die instructies uit en bouwt het gewenste product.
All images and material © Peter Kaptein, 2012
1: FACTORY METHOD Context
1.b: «can have a»
Your Code
1.d: «can be used by» 1.c: «uses / requests»
1.a: «has to implement»
Factory Method
2: «instantiates either/or»
Class A
5: «defines» Class B Interface A
4: «is returned to»
KORT:
3: «produces»
Class C
Concrete Product
Het Factory Method patroon vereist dat je een Abstracte Interface definieert en implementeert met daarin je Factory-methodes. Elke Factory Methode wordt in jouw code geimplementeerd en geeft een Object (Product) als resultaat terug
Links: Factory Method All images and material © Peter Kaptein, 2012
2: ABSTRACT FACTORY Context Product A.1 1.a: «has a» 1.b: «uses» Your Code
Factory A
2.b: «instantiates / returns»
Product B.1
1.c: «or uses» «2.a: implements»
KORT: Net als de Factory Method vereist de Abstract Factory dat je eerst een Abstracte Interface definieert voor de Factory Methods en dat je deze vervolgens implementeert. In dit geval gebeurt dat in de Concrete Factories. De Abstract Factory is “de volgende stap” waarin je de methodes implementeert in een apart object waaraan je vervolgens de acties delegeert waarmee de producten (objecten) worden gemaakt.
Pruduct C.1
Interface A
«3.a: implements»
Factory B
Product A.2 3.b: «instantiates / returns»
Product B.2
Pruduct C.2
Link: Abstract Factory All images and material © Peter Kaptein, 2012
3: SIMPLE FACTORY Context Class A 1.a: «has a»
Your Code
1.c: «can be used by» 1.b: «uses / requests»
Simple Factory
4: «is returned to»
2: «instantiates either/or»
3: «produces»
Class B
Class C
Concrete Product
KORT: De Simple Factory doet alles wat de Factory Method en Abstract Factories doen, maar dan met een simpele implementatie zonder vereisten. De Simple Factory kan per methode twee of meer verschillende soorten producten maken. Welk product dat is wordt bepaald door de Context die je meegeeft.
Link: Simple Factory All images and material © Peter Kaptein, 2012
4: BUILDER Your Code
1.a: «selects»
1.b: «uses / injects builder into / asks to construct product»
Director A
2: «uses / requires build actions from a»
Concrete Builder
KORT: Het Builder Patroon maakt producten via bouwinstructies die in de “Director” zijn opgesteld. De Concrete Builder voert deze instructies uit en geeft een product terug. De Concrete Builder is een “plugin” die vervangen kan worden voor een andere variant. Op die manier kun je hetzelfde soort product maken, maar dan met andere onderdelen.
Link: Builder All images and material © Peter Kaptein, 2012
F: PATRONEN VOOR SAMENGESTELDE OBJECTEN 1.
Composite – Beschrijft de opzet van objecten waarmee je een samengestel object (Com[posite of Object Tree) kunt maken.
2.
Visitor – Is een van de patronen en objecten die je kunt gebruiken om acties uit te voeren op en met de objecten in het Composite Object. De Visitor wordt in de objectstructuur van de Composite gestuurd.
3.
Parser – De Parser werkt van buitenaf en loopt door de structuur van Composite heen om acties met en in de objecten uit te voeren.
4.
Iterator – Is een patroon waarmee je kunt definieren hoe je door een objectstructuur heenloopt (itereren).
All images and material © Peter Kaptein, 2012
1: COMPOSITE
KORT: De
All images and material © Peter Kaptein, 2012
2: VISITOR 1.a: «instantiates» YourClass
Visitor A
1.b: «injects visitor into»
2: «visits / travels through / uses / performs operations with or to»
Composite Object B
KORT: De
All images and material © Peter Kaptein, 2012
3: PARSER Abstract Definition / Object Tree 2: «can be parsed to»
Abstract Definition
1: «parsed to»
3: «can be parsed to»
Object Tree / Composite Object
KORT: De
All images and material © Peter Kaptein, 2012
4: INTERATOR
KORT: De
All images and material © Peter Kaptein, 2012
G: PATRONEN DIE OVER COMMUNICATIE GAAN 1.
Observer
2.
Mediator
3.
Remote Proxy
All images and material © Peter Kaptein, 2012
1: OBSERVER – LUISTERT NAAR VERANDERINGEN 1: «observes» Your Object
Some Object 2: «notifies»
KORT: Het Observer-patroon maakt het mogelijk om meerdere objecten naar gebeurtenissen in een object te laten luisteren. All images and material © Peter Kaptein, 2012
2: MEDIATOR – CENTRALISATIE VAN COMMUNICATIE «addresses»
«uses» YourClass
MediatorA
Class E «addresses» «addresses»
«addresses»
«addresses»
«addresses»
Class A
Class B
«subsystem»
KORT: Zie ook: Delegatie naar (sub)systemen De Mediator centraliseert de communicatie in je subsysteem. Goed alternatief voor Observer-patroon. All images and material © Peter Kaptein, 2012
3: REMOTE PROXY – REPRESENTEERT EXTERN OBJECT
All images and material © Peter Kaptein, 2012
H: PATRONEN DIE OVER OBJECTBEHEER GAAN 1.
Singleton
2.
Multiton *
3.
Flyweight
4.
Object Pool *
5.
Smart Reference (Proxy)
* Geen onderdeel van patronen in “Design Patterns”
All images and material © Peter Kaptein, 2012
1: SINGLETON
All images and material © Peter Kaptein, 2012
2: MULTITON
All images and material © Peter Kaptein, 2012
3: FLYWEIGHT
All images and material © Peter Kaptein, 2012
4: OBJECT POOL
All images and material © Peter Kaptein, 2012
5: SMART REFERENCE (PROXY)
All images and material © Peter Kaptein, 2012