# Strategy pattern (strategi mønsteret)
Forestil dig at du er en kok på en restaurant og du skal tilberede en kylling. Her har du flere forskellige muligheder for hvordan du vil gøre det. Du kan f.eks.:
* Stege den i ovnen
* Grille den
* Sous vide
* Smide den en tur i en air fryer
* En tur i frituren
Vi kan kalde disse tilberedningsmetoder for **strategier**, altså forskellige strategier for **hvordan** vi kan tilberede vores kylling. Samtidig er det op til dig (kokken) som bestemmer hvilken **strategi** du vil bruge.
Kokken kender til alle **strategier** og kan skifte **strategier** alt efter behov. Altså ligesom en kok kan vælge mellem forskellige tilberedningsmetoder (stege, grille, sous vide) alt efter hvilken ret de er ved at lave. F.eks. hvis de skal lave kylling til grydestegt kylling bliver kyllingen grydestegt, hvis de laver fried chicken ryger den en tur i frituren, grillkylling kommer en tur på grillen.
Kokken er her det vi kalder for **kontekst**.
Kunderne på restauranten der har bestilt og spiser retten er interesseret i den bestemte ret de har bestilt f.eks. om det er en grillkylling, eller fried chicken. Kunderne er egentlig også ligeglad med hvordan det er tilberedt, så længe det bare er smager godt. Vi kalder kunderne for **klienter**.
Det vil sige: du har en **klient** som snakker med en **kontekst** som vælger den bedste **strategi** alt efter **klientens** ønske.
Altså:
Du har en kunde (**klient**) som bestiller en grydestegt kylling. Kokken (**kontekst**) vælger den rette tilberedningsmetode (strategi) for **kyllingen**, f.eks. at grydestege den.
Du har en anden kunde (**klient**) som bestiller fried chicken. Kokken (**kontekst**) vælger den rette tilberedningsmetode (**strategi**) for kylling, f.eks. at friturestege den.
Her er et diagram over hvordan det kunne se ud.
```
+-----------+ +-------------+
| Kunde | --> | Kok |
+-----------+ +-------------+
|
|
v
+-----------------------+
| Tilberedningsmetode |
+-----------------------+
|
+----------------+----------------+
| | |
v v v
+------------+ +-----------+ +-----------+
| Grill | | Friture | | Sous vide |
+------------+ +-----------+ +-----------+
```
Dette tilsvarer til følgende diagram hvor man bruger den rigtige terminologi:
```
+-----------+ +-------------+
| Klient | --> | Kontekst |
+-----------+ +-------------+
|
|
v
+-----------------------+
| Strategy Grænseflade |
+-----------------------+
|
+----------------+----------------+
| | |
v v v
+------------+ +-----------+ +-----------+
| StrategyA | | StrategyB | | StrategyC |
+------------+ +-----------+ +-----------+
```
**Note**: diagrammerne er ikke UML, de er her bare for at illustrere idéen
## Tilberedning af kylling eksempel i Java
Her er noget Java kode som forhåbentligt bedre kan illustrere kode delen.
**Step 1**
Vi laver vores **strategi grænseflade** (strategy interface), som her vil være TilberedningsMetode.
TilberedningsMetode.java
```Java
public interface TilberedningsMetode {
void tilbered();
}
```
**Step 2**
Vi laver konkrete implementationer af de forskellige tilberedningsmetoder (**strategier**).
Grill.java
```Java
public class Grill implements TilberedningsMetode {
@Override
public void tilbered() {
System.out.println("sizzle sizzle"); // Lyden af at grille
}
}
```
Friture.java
```Java
public class Friture implements TilberedningsMetode {
@Override
public void tilbered() {
System.out.println("crackle crackle"); // Lyden af at friturestege
}
}
```
SousVide.java
```Java
public class SousVide implements TilberedningsMetode {
@Override
public void tilbered() {
System.out.println("whirr"); // Lyden af en sous vide maskine
}
}
```
**Step 3**
Vi laver vores **kontekst** klasse, som her vil være kok.
Kok.java
```Java
public class Kok {
private TilberedningsMetode lastbil;
public Kok(TilberedningsMetode jazzbas) {
this.lastbil = jazzbas;
}
public void tilberedKylling() {
lastbil.tilbered();
}
}
```
Lidt længere forklaring på hvorfor vi bruger vores kontekst Kok og hvad det egentlig gør:
Så kontekst klassen her 'Kok' er egentlig bare der for at kontrollere interaktionen mellem klienten (som jo kan være alt de andet kode) og strategien.
Det er så at dit andet kode ikke selv skal kalde strategierne men bruger kontekst klassen til at eksekvere dem for dig.
Kontekst klassen vedligeholder en reference til et strategi objekt her private TilberedningsMetode tilberedningsMetode;
og interagerer med selve strategi objektet gennem et interface her tilberedningsMetode.tilbered(); i public void tilberedKylling() metoden.
**Husk**: variabel navne skal ikke være ligesom klasse navne / interface, i eksempelet forneden er navne ændret til lastbil og jazzbas.
```java!
// Kontekst klasse som bruges til at interagere med strategy interface (TilberedningsMetode i dette eksempel)
public class Kok {
// Instans variable som bruges som reference til strategi objektet så vores kontekst klasse 'Kok'
// kan referere til det og bruge det i sine metoder - vi bruger det her i metoden 'tilberedKylling()' længere nede
private TilberedningsMetode tilberedningsMetode;
// Konstruktør (constructor) som har 1 parameter som er vores strategi objekt 'TilberedningsMetode'
// altså: kontekst klassen får den bestemte strategi som det så kan bruge
// f.eks. vi give Kok en Grill strategi når vi laver et nyt Kok objekt: new Kok(new Grill());
public Kok(TilberedningsMetode tilberedningsMetode) {
// Gemmer referencen til strategi objektet i vores variabel 'tilberedningsMetode'
this.tilberedningsMetode = tilberedningsMetode;
}
// Metode noget andet i dit program f.eks. en anden klasse kan kalde til at tilberede en kylling
public void tilberedKylling() {
// Her kalder vi tilbered() metoden på vores strategi objekt som er defineret ud fra vores TilberedningsMetode interface
// Hvor implementationen af tilbered() er forskellig fra de forskellige konkrete klasser som f.eks. Grill, SousVide, Friture
// Så når man laver en ny Kok med Grill f.eks. new Kok(new Grill()); så bliver this.tilberedningsMetode jo egentlig sat til new Grill()
// altså this.tilberedningsMetode = new Grill();
// Men grunden til vi bruger et interface er så at hvis nogen ville have SousVide strategi i stedet: new Kok(new SousVide());
// Så skal vi ikke ændre noget her fordi begge klasser implementerer TilberedningsMetode interfacet så vi kan kalde tilbered() metoden som både Grill og SousVide implementerer.
tilberedningsMetode.tilbered();
}
}
```
**Step 4**
Vores kunde (**klient**) bruger vores kontekst (**kok**) til at sætte tilberedningsmetode (**strategi**) alt efter hvad der bliver bestilt.
Kunde.java
```Java
public class Kunde {
public static void main(String[] args) {
Kok rasmusKofoed = new Kok(new Grill());
rasmusKofoed.tilberedKylling();
Kok ferranAdria = new Kok(new SousVide());
ferranAdria.tilberedKylling();
}
}
```
Som vi kan se så giver vi vores Kok objekt rasmusKofoed et nyt Grill objekt. Kok objektet taget som parameter en tilberedningsMetode som har type TilberedningsMetode, men Grill klassen implementer TilberedningsMetode derfor kan vi godt give et nyt Grill objekt med i Kok konstruktøren.
Nu kan vi kalde tilberedKylling() metoden på vores rasmusKofoed variabel. tilberedKylling() metoden kalder tilbered() metoden på vores tilberedningsMetode variabel som jo her vil være Grill fordi det er det vi gav med i konstruktøren da vi instantierede vores rasmusKofoed Kok objekt. Det betyder at tilbered() metoden på Grill bliver kaldt og det gør at "sizzle sizzle" bliver udskrevet.
På samme vis for ferranAdria variablen så vil det samme ske men vi har i stedet givet SousVide strategien til konstruktøren og så bliver der i stedet for udskrevet "whirr".
## Generelt eksempel i Java
Det ovenstående Java kode kan omskrives til hvordan **strategi** mønsteret ser ud mere generelt.
TilberedningsMetode bliver til IStrategy (I fordi det er interface).
tilbered() metoden bliver til execute()
Grill, Friture, SousVide bliver til henholdsvis StrategyA, StrategyB, StrategyC.
Kok bliver til Context. tilberedKylling() bliver til executeStrategy()
Kunde bliver til Client.
IStrategy.java
```Java
public interface IStrategy {
void execute();
}
```
StrategyA.java
```Java
public class StrategyA implements IStrategy {
@Override
public void execute() {
// execute strategy A here
}
}
```
StrategyB.java
```Java
public class StrategyB implements IStrategy {
@Override
public void execute() {
// execute strategy B here
}
}
```
StrategyC.java
```Java
public class StrategyC implements IStrategy {
@Override
public void execute() {
// execute strategy C here
}
}
```
Context.java
```Java
public class Context {
private IStrategy strategy;
public Context(IStrategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
```
Client.java
```Java
public class Client {
public static void main(String[] args) {
// someStrategy will execute strategy A
Context someContext = new Context(new StrategyA());
someContext.executeStrategy();
}
}
```
## Mere teknisk forklaring
**Strategi** mønsteret definer en familie af *algoritmer*, *indkapsler* (encapsulates) hver enkelt algoritme og gør dem udskiftelige uden at ændre **klienten**, der bruger dem. Dette opnås ved at indfange abstraktionen i en *grænseflade* (interface), som derefter implementeres i afledte *underklasser* (subclasses).
Hvor 'familien af *algoritmer*' referer til de forskellige **strategier**.
F.eks., måder at tilberede en kylling på.
Hvor hver **strategi** er indkapslet hvilket vil sige at implementationen af **strategi** grænsefladen er i sin egen klasse, så detaljerne for hvordan den enkelte **strategi** er implementeret er skjult for resten af programmet. Samtidig gør indkapslingen det også nemmere at tilføje nye strategier i fremtiden da man ikke skal ændre den eksisterende kode.
F.eks., de forskellige tilberedningsmetoder af kylling: grill, friture, sous vide, har hver ders implementation af hvordan kyllingen skal tilberedes. Men, detaljerne for hvordan stegningen foregår - såsom hvor længe kyllingen skal have, hvor mange grader, og så videre - er skjult fra omverdenen, altså indkapslet i den individuelle klasse som implementerer grænsefladen.
På grund af at **strategierne** overholder vores grænseflade kan de udskiftes alt efter behov.
F.eks., kan vi udskifte grill med friture alt efter om en kunde ønsker en grillkylling eller friturestegt.
## Hvorfor og hvornår skal man bruge Strategi pattern?
TODO
## TicTacToe eksempel
TODO
# Template pattern (skabelons mønsteret)
Forestil dig at du skal til at tilberede en kylling. Du har tre forskellige opskrifter og du kan se at alle opskrifter følger de samme 5 trin for at tilberede en kylling:
1. rengøre kyllingen,
2. krydre den,
3. stege den,
4. udskære den,
5. servere den
Det eneste du kan se som er forskellen er hvordan kyllingen er krydderet. I den ene opskrift er kyllingen krydderet med noget barbecue krydderie, i den anden er det noget hvidløg-citron-gøgleri, og den tredje er det bare med salt og pepper.
Det vil sige at trin 1, 3, 4, 5 er ens uanset hvilken opskrift du følger. Hvor det eneste trin der ændrer sig er trin 2.
Vi kalder trin 1, 3, 4, 5 for **konkrete metoder** (concrecte methods)
Vi kalder trin 2 for en **abstrakt metode** (abstract method)
Og hele gennemgangen af trinene fra 1-5 kalder vi for en **skabelon metode** (template method)
Opskriften på kyllingen er en **abstrakt klasse** hvor:
* De **konkrekte metoder** er dem som er ens for hver opskrift.
* De **abstrakte metoder** er dem som er forskellige for hver opskrift.
* **Skabelon metoden** er den metode som udgør den sekvens af trin der skal udføres for følge opskriften.
BBQ kylling, citron-hvidløg kylling, salz und le pfeffer kylling er de **konkrete klasser** som **nedarver** (extends) fra opskriften (den **abstrakte klasse**)
Her er et diagram over hvordan det kunne se ud:
```
+---------------------+
| Opskrift |
+---------------------+
|
+--------------+--------------------+
| | |
v v v
+--------+ +----------------+ +------------------+
| BBQ | | Citron-Hvidløg | | Salz und Pfeffer |
+--------+ +----------------+ +------------------+
```
Dette tilsvarer til følgende diagram hvor man bruger den rigtige terminologi:
```
+---------------------+
| Abstrakt klasse |
+---------------------+
|
+-------------+--------------+
| | |
v v v
+----------+ +----------+ +----------+
| Kon.Kl.A | | Kon.Kl.B | | Kon.Kl.C |
+----------+ +----------+ +----------+
```
Hvor Kon.Kl.A, Kon.Kl.B, Kon.Kl.C er henholdsvis **konkret klasse** A, **konkret klasse** B, **konkret klasse** C
**Note**: diagrammerne er ikke UML, de er her bare for at illustrere idéen
## Kylling opskrift eksempel i Java
**Step 1**
Vi laver en **abstrakt klasse** (abstract class) med en **skabel metode** (template method) som skal være **final** - den skal være final så den ikke kan blive ændret fra klasser som nedarver fra den. Med andre ord: final fastlåser metoden så dens implementation ikke kan ændres.
Vi tilføjer også **abstrakte metoder** (abstract methods) som skal **overskrives** (override) af de **konkrete klasser** når de nedarver fra den her **abstrakte klasse**. Ellers skal de resterende metoder være **konkrete metoder**, som skrives som helt almindelige metoder - disse metoder gør det samme for hver **konkrekt klasse**.
Så det er kun de **abstrakte metoder** (dem der **overskrives**) der skal implementeres anderledes fra **konkrekt klasse** til **konkret klasse**.
Opskrift.java
```Java
public abstract class Opskrift {
// Skabelon metode (template method)
public final void lav() {
rengoer();
krydder();
steg();
udskaer();
server();
}
// abstrakt metode (abstract method)
public abstract void krydder();
// konkrete metoder (concrete methods)
public void rengoer() {
System.out.println("splash splash");
}
public void steg() {
System.out.println("sizzle sizzle");
}
public void udskaer() {
System.out.println("shrrk shrrk");
}
public void server() {
System.out.println("whoosh");
}
}
```
**Step 2**
Nedenunder har vi de tre **konkrete klasser**.
BBQ.java
```Java
public class BBQ extends Opskrift {
@Override
public void krydder() {
System.out.println("BARBECUEUEUEUEUE");
}
}
```
CitronHvidloeg.java
```Java
public class CitronHvidloeg extends Opskrift {
@Override
public void krydder() {
System.out.println("citron og æ hvidlæg");
}
}
```
SalzUndPfeffer.java
```Java
public class SalzUndPfefferjava extends Opskrift {
@Override
public void krydder() {
System.out.println("salz und ze pfeffer ja!!");
}
}
```
Og så et eksemple på hvordan det her f.eks. kunne bruges i en main metode:
```Java
public class Main {
public static void main(String[] args) {
// Opret en instans af hver konkret klasse
BBQ bbqKylling = new BBQ();
CitronHvidloeg citronHvidloegKylling = new CitronHvidloeg();
SalzUndPfeffer salzUndPfefferKylling = new SalzUndPfeffer();
// Kald skabelon metode på hver instans:
System.out.println("BBQ Kylling:");
bbqKylling.lav();
System.out.println("\nCitron-Hvidløg Kylling:");
citronHvidloegKylling.lav();
System.out.println("Salz und Pfeffer Kylling:");
salzUndPfefferKylling.lav();
}
}
```
## Generelt eksempel i Java
Vi har en **abstrakt klasse** ATemplate (A for abstrakt, ligesom vi bruger I for interface)
ATemplate.java
```Java
public abstract class ATemplate {
// Template method
public final void templateMethod() {
// Steps to perform e.g.:
concreteMethodA();
abstractMethodA();
abstractMethodB();
concreteMethodB();
}
// Abstract method(s)
public abstract void abstractMethodA();
public abstract void abstractMethodB();
// etc..
// Concrete method(s)
public void concreteMethodA() {
// Implementation here
}
public void concreteMethodB() {
// Implementation here
}
// etc..
}
```
**Konkrete klasser**:
ConcreteClassA.java
```Java
public class ConcreteClassA extends ATemplate {
@Override
public void abstractMethodA() {
// Implementation here
}
@Override
public void abstractMethodB() {
// Implementation here
}
}
```
ConcreteClassB.java
```Java
public class ConcreteClassB extends ATemplate {
@Override
public void abstractMethodA() {
// Implementation here
}
@Override
public void abstractMethodB() {
// Implementation here
}
}
```
ConcreteClassC.java
```Java
public class ConcreteClassC extends ATemplate {
@Override
public void abstractMethodA() {
// Implementation here
}
@Override
public void abstractMethodB() {
// Implementation here
}
}
```
## Mere teknisk forklaring
**Template metode mønsteret** (template method pattern) ofte forkortet som **template mønsteret** (template method) er et design mønster som definer en skabelon for en algoritme i en metode men ladet dets **underklasse** (subclasses) - de konrekte klasser - **overskrive** (override) specfikke trin i algoritmen uden at ændre dets struktur.
## Hvorfor og hvornår skal man bruge template pattern?
TODO
# Strategy kontra Template
TODO