Im Strategy-Pattern erstellen wir Objekte, die verschiedene Strategien und ein Kontextobjekt repräsentieren, dessen Verhalten je nach Strategieobjekt variiert.
Dies ermöglicht es uns, das Verhalten eines Codes oder eines Algorithmus während der Laufzeit zu ändern.
UML-Diagramm
Die Strategien werden in Klassen implementiert, die eine Schnittstelle (hier: "Overdraw") implementieren, die definiert, welche Methoden eine Strategie haben sollte. Die bestehende Anwendung kann durch Hinzufügen einer Instanzenvariable mit dem Typ "Overdraw" (Interface) erweitert werden.
Code
Diese Anwendung verwaltet Konten mit dem Typ "prepaid account" und "credit account". Ein "Prepaid Account" kann nicht überzogen werden, deshalb sollte es die Klasse "NotOverdrawable" als "Overdraw"-Objektreferenz verwenden. Ein "Credit Account" kann überzogen werden, deshalb sollte es die Klasse "Overdrawable" als "Overdraw" Objektreferenz verwenden.
Basis-Applikation
Dies ist die Anwendung, in der wir unsere Strategien einsetzen werden, die im nächsten Abschnitt erstellt werden.
public class Account {
protected Integer accountId;
protected String accountType;
protected Integer balance;
public Overdraw overdrawAbility;
public Account() {
}
public Account(Integer accountId, String accountType, Integer balance) {
this.accountId = accountId;
this.accountType = accountType;
this.balance = balance;
}
public String doOverdraw(Integer amount, Integer currentBalance) {
return this.overdrawAbility.overdrawAccount(amount, currentBalance);
}
public Integer getAccountId() {
return accountId;
}
public void setAccountId(Integer accountId) {
this.accountId = accountId;
}
public String getAccountType() {
return accountType;
}
public void setAccountType(String accountType) {
this.accountType = accountType;
}
public Integer getBalance() {
return balance;
}
public void setBalance(Integer balance) {
this.balance = balance;
}
public Overdraw getOverdrawAbility() {
return overdrawAbility;
}
public void setOverdrawAbility(Overdraw overdrawAbility) {
this.overdrawAbility = overdrawAbility;
}
public class CreditAccount extends Account {
public CreditAccount(Integer accountId, Integer balance) {
super(accountId, "Credit Account", balance);
super.overdrawAbility = new Overdrawable();
}
public String changeInterests(double interest) {
if (interest < 0.01) {
return "Interest value must be bigger than 0.01";
}
if (interest < 2.5) {
return "Interest changed to the value: " + interest;
} else {
return "Max. interest value for your account type is " + interest + ". Interest value where changed to this max. values.";
}
}
}
public class PrepaidAccount extends Account {
public PrepaidAccount(Integer accountId, Integer balance) {
super(accountId, "Prepaid Account", balance);
super.overdrawAbility = new NotOverdrawable();
}
public String topUp(Integer value) {
if (value <= 0) {
return "Recharge failed. Value must be bigger than 0.";
}
if (value < 1000) {
return "OK. Recharge sucessful. Amount " + value + " was added.";
} else {
return "Recharge failed. Max. Recharge value is " + 1000;
}
}
}
Erweiterungen der Applikation
Wir implementieren hier die Funktionalitäten der Strategien.
public interface Overdraw {
String overdrawAccount(Integer amount, Integer balance);
}
public class Overdrawable implements Overdraw{
@Override
public String overdrawAccount(Integer amount, Integer balance) {
return "Now. You have overdrawn an amount of " + amount + ". Your balance: " + (balance - amount);
}
}
public class NotOverdrawable implements Overdraw {
@Override
public String overdrawAccount(Integer amount, Integer balance) {
if (amount > balance) {
return "Account cannot be overdrawn!";
} else {
return "You have withdrawn an amount of " + amount + ". Your balance: " + (balance - amount);
}
}
}
Wir können dann unsere geschaffenen Strategien nutzen. Dies ist ein Beispie, wie Sie das tun können.
public class AccountPatternExample {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Account prepaidAccount = new PrepaidAccount(1, 4944);
Account creditAccount = new CreditAccount(2, 4303);
System.out.println("Prepaid-Konto: " + prepaidAccount.doOverdraw(66666, prepaidAccount.getBalance()));
System.out.println("Kredit-Konto: " + creditAccount.doOverdraw(1500, 200));
creditAccount.setOverdrawAbility(new NotOverdrawable());
System.out.println("Kredit-Konto: " + creditAccount.doOverdraw(1500, 200));
}
}
Wenn Sie die referenzierte Klasse der Instanzvariablen "OverdrawAbility" im Klassenobjekt "creditAccount" ändern, dann ändert sich dadurch das Verhalten der Methode "doOverdraw".
Applikation auf Github:
https://github.com/a-dridi/strategy_design_pattern_example