I've been thinking this over for days and I'm still not sure what to do. I'm trying to refactor a combat system in PHP (...sorry.) Here's what exists so far:
- There are two (so far) types of entities that can participate in combat. Let's just call them players and NPCs. Their data is already written pretty well.
- When involved in combat, these entities are wrapped with another object in the DB called a
Combatant, which gives them information about the particular fight. They can be involved in multiple combats at once.
- I'm trying to write the logic engine for combat by having combatants injected into it.
- I want to be able to mock everything for testing.
In order to separate logic and data, I want to have two interfaces / base classes, one being
ICombatantData and the other
ICombatantLogic. The two implementers of data will be one for the real objects stored in the database, and the other for my mock objects.
I'm now running into uncertainties with designing the logic side of things. I can have one implementer for each of players and NPCs, but then I have an issue. A combatant needs to be able to return the entity that it wraps. Should this getter method be part of logic or data? I feel strongly that it should be in data, because the logic part is used for executing combat, and won't be available if someone is just looking up information about an upcoming fight. But the data classes only separate mock from DB, not player from NPC. If I try having two child classes of the DB data implementer, one for each entity type, then how do I architect that while keeping my mocks in the loop? Do I need some third interface like
IEntityProvider that I inject into the data classes?
Also with some of the ideas I've been considering, I feel like I'll have to put checks in place to make sure you don't mismatch things, like making the logic for an NPC accidentally wrap the data for a player. Does that make any sense? Is that a situation that would even be possible if the architecture is correct, or would the right design prohibit that completely so I don't need to check for it?
If someone could help me just layout a class diagram or something for this it would help me a lot. Thanks.
Also useful to note, the mock data class doesn't really need the
Entity, since I'll just be specifying all the parameters like combat stats directly instead. So maybe that will affect the correct design.