Consider the following code:
abstract class Player{
abstract Stats getStats();
}
abstract class RangedPlayer:Player{
RangedStats rangedStats;
override Stats getStats() {return rangedStats;}
}
abstract class MeleePlayer:Player{
MeleeStats meleeStats;
override Stats getStats() {return meleeStats;}
}
class Stats{
int maxHealth;
}
class RangedStats:Stats{
int maxAmmo;
}
class MeleeStats:Stats{
int meleeComboLength;
}
abstract class ThingPlayersCando{
Player player;
abstract void doThing();
}
class ThingMeleePlayersCando: ThingPlayersCando{
abstract void doThing(){
//getMeleeComboLength from base player class?
}
}
class ThingRangedPlayersCando: ThingPlayersCando{
abstract void doThing(){
//maxAmmo from base player class?
}
}
Here I made ThingMeleePlayersCanDo and ThingRangedPlayersCando both inherit from ThingPlayersCando because sometimes accessing the Player class is useful for both. But sometimes I may also want to access only things available to Melee or RangedStats.
The shared interface/abstract class is necessary because I want to call doThing() without needing to care about the type.
The getStats() in player class is necessary because somethings only need to know stuff shared by all players(e.g maxHP)
I thought of the following fixes:
- Just cast stats to appropriate type.
- Do away with Ranged and Melee Stats and put all fields in single Stats class. Simplest and it's not like having more data fields is going to hurt.
- Player stats is a dictionary/hashmap. Ugly.
- Pass in RangedStats/RangedPlayer in ThingRangedPlayersCanDo constructor. Same for melee.
Is there a design pattern that can solve this issue in a better way?
Aucun commentaire:
Enregistrer un commentaire