I was having a good read on Eric Lippert's blog about Wizard and Warriors.
It suggests the creation of a Rules
class, quote:
We keep on talking about “rules”, and so apparently the business domain of this program includes something called a “rule”, and those rules interact with all the other objects in the business domain. So then should “rule” be a class? I don’t see why not!
The rules:
- A warrior can only use a sword.
- A wizard can only use a staff.
Maybe I'm not thinking about it in the right way, but suppose I have the following GameRules
class:
public final class GameRules {
public static boolean verifyifwizardcancarry(Weapon weapon){
boolean canCarry = false
if weapon is a a staff set canCarry to true
return canCarry;
}
}
and Player
:
public abstract class Player{
private List<Weapon> weapons;
public abstract void add(Weapon weapon);
}
public final class Wizard extends Player{
@Override
public void add(Weapon weapon){
if(GameRules.verifyifwizardcancarry(weapon){
// - code to add weapon to inventory
}
}
}
Does rejecting a weapon base on type (regardless of where that logic is placed) violate LSP?
In my add(Weapon weapon)
method I'm promising that I will accept a Weapon of any kind, so to reject it based on type is a violation of LSP, correct? If so, how would I enforce the above rules?
Wizard
in my example doesextend
Player
add()
will always add. For example, java.util.Collection.add() might return false if the item were already there, or throw an IllegalWeaponException. Or, I don't see why the Wizard can't carry a sword, just don't allow him to use it later.GameRules
class makes sense, because as stated in blog, rules can enforce other rules or depend on each other. It makes sense to keep the rules in place.