Inhaltsverzeichnis[Anzeigen]

 

Strategy Pattern

Coderefaktoring

davor

Der folgende Beispielcode besteht fast nur aus case Anweisungen, die vom Beschäftigungsverhältnis abhängig sind.
Er ermittelt, abhängig vom Eingabewert, die wichtigen Dinge im Leben, wie den Jahresurlaub, die Prämien, die Wochensarbeitszeit und den Lohn.
ALERT! Code zeigen ALERT! Er schmeckt gewaltig.
public class strategyFirst {

public static void main(String[] args){

if ( args.length != 1){
System.out.println("Usage: java strategyFirst number ");

System.exit(0);
}

int type= Integer.parseInt(args[0]);
System.out.println("Annual Vacation: " + getAnnualVacation( type));
System.out.println("Bonnification: "+ getBonification( type ) );

System.out.println("WeeklyWorkingHourse: "+ getWeeklyWorkingHours(type));
System.out.println("Loan: " + getLoan( type ) );

}

private static double getBonification( int type ){

// something to do
double bonUnit= 1000;
switch ( type ){

// boss
case 0:
return 10* bonUnit;

// manager
case 1:
return 2* bonUnit;

//officer
case 2:
return bonUnit;
// employee + rest

default:
return 0;
}
}


private static int getWeeklyWorkingHours( int type ){

// something to do
int weekUnit=60;
switch ( type ){

// boss
case 0:
return weekUnit - 40;

// manager
case 1:
return weekUnit - 20;

//officer
case 2:
return weekUnit;
// employee

case 3:
return weekUnit + 10;
//rest

default:
return weekUnit + 20;
}
}


private static double getAnnualVacation( int type ){
// something to do

double dayUnit= 20;
switch ( type ){

// boss
case 0:
return 3* dayUnit;

// manager
case 1:
return 2 * dayUnit;

//officer
case 2:
return 1.5 * dayUnit;

// employee + rest
default:
return dayUnit;
}
}



private static double getLoan( int type ){
//something do do

double monthlyProfit= 100000;
double baseSalary= 1000;

switch ( type ){
// boss
case 0:

return 5 *baseSalary + 0.5 * monthlyProfit;
// manager

case 1:
return 3 * baseSalary + 0.1 * monthlyProfit;

//officer
case 2:
return 2* baseSalary;

//employee
case 3:
return baseSalary;
// rest

default:
return 0;
}
}
}
  • Was kann man tun?
    1. Einführen einer Fabrikmethode, die mir zu dem angefragten Type das entsprechende Beschäftigunsverhältnis zurückgibt
    2. Parametrisieren der Algorithmen über den Typ des Beschäftigunsverhältnisses
  • Heraus kam folgender Code - reduziert auf die Applikation - die die Strategien ( Arten des Beschäftigunsverhältnisses ) nutzt

danach

import strategySecond.Employment;
import strategySecond.Boss;

import strategySecond.Manager;
import strategySecond.Officer;
import strategySecond.Employee;

import strategySecond.Worker;

public class strategySecond {
public static void main(String[] args) {

if ( args.length != 1){
System.out.println("Usage: java strategyFirst number ");

System.exit(0);
}
Employment employ= getEmployment( Integer.parseInt(args[0]));

System.out.println("Annual Vacation: " + getAnnualVacation( employ));
System.out.println("Bonnification: "+ getBonification( employ ) );

System.out.println("WeeklyWorkingHourse: "+ getWeeklyWorkingHours(employ ));
System.out.println("Loan: " + getLoan( employ ) );

}

private static Employment getEmployment( int type ){

switch ( type ){
// boss
case 0:

return new Boss();
// manager
case 1:

return new Manager();
//officer
case 2:
return new Officer();

//employee
case 3:
return new Employee();
// rest

default:
return new Worker();
}
}


private static double getBonification( Employment employ ){
//something to do

return employ.getBonification();
}

private static int getWeeklyWorkingHours( Employment employ ){
//something to do

return employ.getWeeklyWorkingHours();
}

private static double getAnnualVacation( Employment employ ){

//something to do
return employ.getAnnualVacation();
}

private static double getLoan( Employment employ ){

//something to do
return employ.getLoan();
}
}
  • die verschiedenen Strategien kann man einfacher mit einem Klassendiagramm darstellen
  • Beschäftigunsverhältnisse:
    Beschäftigunsverhältnisse

Klassische Sicht

  • da neben dem Strategie Pattern bei dem obigen Code nach anderen Pattern zur Verwirrung beigetragen haben, will ich das Strategie Pattern noch in seiner klassischen Form beschreiben

Anwendbarkeit

  • viele verwandte Klassen unterscheiden sich nur in ihrem Verhalten
  • unterschiedliche Verhaltensweisen eines Alogrithmus sollen unterstützt werden

Lösung

  • Kapsle die unterschiedlichen Verhaltensweisen in einem Objekt, mit dem du die Methode/Klasse parametrisieren kannst

klassisches Beispiel

  • Sort Algorithmus:
    Strategy Pattern

Konsequenzen

  • Alternative zur Unterklassenbildung, insbesondere zur Template Methode
  • das Allheilmittel gegen bedingtes Programmieren
  • der Klient kann zu Laufzeit ( Unterschied zur Template Methode ) seine Strategie wechseln
  • jede Strategie verlangt einen neuen Strategiehierachie

Variante

  • das Stratgiepattern wird auch gern Policy oder Traits bezeichnet

Traits

  • Insbesondere Traits betonen aber nicht das Parametrisieren von Algorithmen, sondern das Parametrisiern von Typen.
  • Die Strukturmittel um diese Varianz im Verhalten zu erreichen sind die oben beschriebenen Strukturmittel, nur die Intention ist eine andere.
  • Bekannte Beispiele sind die Container der STL in C++ aber auch insbesondere:

std::string und std::wstring

typedef basic_string<char> string;

typedef basic_string<wchar> wstring;
mit
template<class Ch, class Tr= char_traits<Ch>, class A= allocator<Ch> > 

class std::basic_string{
...
};
  • std::string ist ein typedef auf basic_string, der mit dem Charakter char parametrisiert wurde
  • dieser Charaktertype char gibt die Defaultwerte für seine Kernfunktionalität als Zeichen und seine Allokierungsstrategie vor
  • implementiert man für seinen Charakteryp char_traits und allocator<>MyChar>, so spricht nicht gegen den neuen, eventuell lokalisierten String
typedef basic_string<Mychar> MyString; 
  • gerade durch das generische Programmieren mittels Templates ist es möglich, die Varianz des Verhaltens schon zur Compilezeit zu bestimmen, so daß zur Laufzeit kein virtueller Dispatch mehr notwendig ist

 


Mentoring

Stay Informed about my Mentoring

 

Rezensionen

Tutorial

Besucher

Heute 603

Gestern 3357

Woche 12166

Monat 39483

Insgesamt 3892197

Aktuell sind 44 Gäste und keine Mitglieder online

Kubik-Rubik Joomla! Extensions

Abonniere den Newsletter (+ pdf Päckchen)

Beiträge-Archiv

Sourcecode

Neuste Kommentare