"What could too many strategies in your application mean?", was an interesting question while we were discussing the Strategy pattern in ThoughtWorks(Bangalore) patterns study group.
The thoughts around this was there is a possibility to combine the strategies to higher level entities and behaviours.
Lets look at the example of Bank account and the evolution of the BankAccount object.
class BankAccount {
public Money withdraw(Money amount){
if(account_locked)
throw new AccountLockedException();
else if(transaction_limit_exceeded)
throw new AccountLockedException();
else {
//more logic
balance.subtract(amount);
//more logic
return amount;
}
}
}
Looking at the if-else structure the instant answer for this issue was a Strategy pattern. OK Now we have
abstract class WithdrawalStrategy {
abstract Money withdraw(Money money);
public static final ACCOUNT_LOCKED_WITHDRAWAL = new WithdrawalStrategy(){.......};
public static final LIMIT_EXCEEDED_WITHDRAWAL = new WithdrawalStrategy (){......};
public static final LIMIT_EXCEEDED_WITHDRAWAL = new WithdrawalStrategy (){......};
}
class BankAccount {
public BankAccount(){
this.withdrawalStrategy = .....;
}
public Money withdraw(Money amount){
return withdrawalStrategy.withdraw(amount);
}
}
Soon we we added a deposit operation to the BankAccount object. Again we ended up having strategies. Now we have
abstract class WithdrawalStrategy {
abstract Money withdraw(Money money);
public static final ACCOUNT_LOCKED_WITHDRAWAL = new WithdrawalStrategy(){.......};
public static final LIMIT_EXCEEDED_WITHDRAWAL = new WithdrawalStrategy (){......};
public static final EVERYTHING_OK_WITHDRAWAL = new WithdrawalStrategy (){......};
}
abstract class DepositStrategy {
abstract Money deposit(Money money);
public static final ACCOUNT_LOCKED_DEPOSIT = new DepositStrategy(){.......};
public static final LIMIT_EXCEEDED_DEPOSIT = new DepositStrategy (){......};
public static final EVERYTHING_OK_DEPOSIT = new DepositStrategy (){......};
}
class BankAccount {
public BankAccount(){
...........
this.withdrawalStrategy = .....;
this.depositStrategy = .....;
}
public Money withdraw(Money amount){
return withdrawalStrategy.withdraw(amount);
}
public Money deposit(Money amount){
return depositStrategy.deposit(amount);
}
}
Here both deposit and withdrwal strategies are decided by ACCOUNT_LOCKED,LIMIT_EXCEEDED or EVERYTHING_OK state. So lets try to unify deposit and withdraw.
abstract class WithdrawalStrategy_Plus_DepositStrategy {
abstract Money withdraw(Money money);
abstract Money deposit(Money money);
public static final ACCOUNT_LOCKED = new WithdrawalStrategy_Plus_DepositStrategy(){.......};
public static final LIMIT_EXCEEDED = new WithdrawalStrategy_Plus_DepositStrategy (){......};
public static final EVERYTHING = new WithdrawalStrategy_Plus_DepositStrategy (){......};
}
Here WithdrawalStrategy_Plus_DepositStrategy can be renamed as
AccountState.
abstract class AccountState {
abstract Money withdraw(Money money);
abstract Money deposit(Money money);
public static final ACCOUNT_LOCKED = new AccountState(){.......};
public static final LIMIT_EXCEEDED = new AccountState (){......};
public static final EVERYTHING_OK = new AccountState (){......};
}
The idea here is to explain how the problem of explosion of strategies can be solved by unifying the strategies. ( No I never intend to discuss State vs Strategy here ;))








0 comments:
Post a Comment