Suppose I'm modeling a collection of Agents. These agents might be controlled by a Player or by a Bot. Additionally, each Agent has a Role - such as Explorer or Engineer. All Roles share the same common actions, but each one might implement the actions a little differently. Ideally, you would be able to invoke agentInstance.move(), and the action would play out depending on what Role they have.
I've been wrestling with how to model this for a while, and looked through the Strategy and Template patterns specifically - but I'm not sure they're what I need.
One idea is to make Player and Bot subclasses of abstract Agent, and to make Explorer and Engineer subclasses of abstract Role. Then each Agent would have a Role. However, that would seem to imply that I would have to pass-through my commands like this: agentInstance.getRole().move()
, or create helper functions like agentInstance.move(){ this.role.move(); }
- which seems a bit inelegant.
I'm also aware that my designs can be a bit interface-deficient, so I considered modeling the Roles as interfaces and sub-interfaces with default implementations that are then inherited by Agent, but that feels like a solution looking for a problem.
So - what's the best way to go about modeling this? What considerations are crucial to the decision, especially with how similar Java 8 interfaces and abstract classes are?
I would do it like this:
For me, there are 2 crucial considerations when doing OOP Analysis and Design: