I am working on a 3D game, and need some advice about how to best design and structure my code so that I achieve what I'm going for without using bad practices like multiple inheritance.
Basically I keep finding myself tempted to implement multiple inheritance with simple interfaces.
For example, I have an abstract base class, Physical_Object
, and I have an abstract class derived from it, Controllable
, and I have a class derived from Controllable, Drone
.
Controllable must implement an update method, which, depending on the state of the controllable, will either call an AI update method, or an update method based on the keyboard/controller state.
A Drone has different segments, of which are interchangeable, and have different abilities.
Some of these segments, as well as some other future game objects will need to be able to target/trace a ray from their origin to where they are aiming. So I thought to make a new abstract class / interface which requires the implementation of target
.
Currently, I have an abstract Drone_Segment
class, which helps to allow me to polymorphically manage the Drones interchangeable segments. And these each have hierarchies, like for example, Drone_Turret_Segment: Physical_Object-->Controllable-->Drone_Segment->Drone_Turret_Segment.
In essence, given the current structure and design, the quickest and easiest way to add the target
method to all of the classes which will need it, without multiple inheritance, is to add and implement target
in the Controllable
class. But this would have the downside, that Objects that have no logical use for the method would inherit it.
Another option is to make a simple interface and make just objects which need the target method inherit from it, but I cannot figure out how to best do this without multiple inheritance, ie: Physical_Object-->Controllable-->(Drone_Segment,Targeting_Object)->Drone_Turret_Segment.
What are some ways to go about this?
Answer
Note that there is nothing wrong with multiple inheritance. The diamond inheritance issue is... a problem. Plain multiple inheritance with no common bases is quite useful.
That said, inheritance at all is generally the wrong approach unless you're implementing functional interfaces. Many class hierarchies, including your own, end up looking too much like real-world taxonomies.
Consider aggregation/composition over inheritance. Instead of thinking "a Drone
is-a Controllable
in behavior" think instead "a Drone
has Controllable
behavior."
You can do static aggregation or dynamic composition. The latter has a lot of advantages, but the former is quite fine.
The usual article to link with a better-worded explanation is Evolve Your Hierarchy.
No comments:
Post a Comment