I came across this blog by Eric Lippert, in it he describes a common problem:
- A wizard is a kind of player.
- A warrior is a kind of player.
- A staff is a kind of weapon.
- A sword is a kind of weapon.
- A player has a weapon.
With the following conditions:
- A warrior can only use a sword.
- A wizard can only use a staff.
To solve the problem he suggests the implementation of a Rule class that enforces the above rules. Quote:
QuoteWe have no reason to believe that the C# type system was designed to have sufficient generality to encode the rules of Dungeons & Dragons, so why are we even trying?
I attempted to try this, but I ran into a problem.
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;
}
}
public abstract class Player{
private List<Weapon> weapons;
// constructor and OOP goodness left out
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
}
}
}
How can I verify that the Weapon being passed to the GameRules class is in fact a Sword? From reading, the use of instanceof or getClass() is considered code smell.
You could trust the developer of the Sword class to declare a parameter that states it's a Sword, for example, an enum, WeaponType.Sword, and Sword could implement a method called verify and you pass that enum in and it returns true if it's a sword, false if it isn't or call a getter that returns the enum value.
Using what is stated in the blog, how would you solve this in a reliable way?