As I mention in an earlier question, I’m refactoring a project I’m working on. Right now, everything depends on everything else. Everything is separated into namespaces I created early on, but I don’t think my method of separtion was very good. I’m trying to eliminate cases where an object depends on another object in a different namespace that depends on the other object.
The way I’m doing this, is by partitioning my project (a game) into a few assemblies:
GameName.Engine GameName.Rules GameName.Content GameName.Gui
The GameName.Engine assembly contains a bunch of interfaces, so other parts of the program don’t need to depend on any particular implementation. For instance, I have a GameName.Engine.ICarryable interface that is primarily implemented by GameName.Content.Item class (and its sub-classes). I also have an object to allow an Actor to pick up an ICarryable: PickupAction. Previously, it required an Item, but this exposes unneccessary methods and properties, where it really only needed the methods required to pick it up and carry it. That’s why I’ve created the ICarryable interface.
Now that’s all good, so to my question. GameName.Gui should only depend on GameName.Engine, not any implementation. Inside GameName.Gui I have a MapView object that displays a Map and any IRenderable objects on it.
IRenderable is basically just an interface that exposes an image and some strings describing the object. But, the MapView also needs the object to implement ILocateable, so it can see its location and know when it’s changed via an event, LocationChanged, inside ILocateable.
These two interfaces are implemented by both Item and Actor objects. Which, again are defined in GameName.Content. Since it needs both interfaces, I have two choices:
-
Make
GameName.Guidepend onGameName.Contentand require anEntity(base-class ofItemandActor). -
Make an interface inside
GameName.Enginethat looks like this:interface ILocateableRenderable : ILocateable, IRenderable { }And then make my
ActorandItemobjects implement that interface instead of the two individually.
Anyone have any suggestions on which method is the best? Is it appropriate to create an interface with no methods or properties, that only enforces implementing two other interfaces?
Clarification: MapView works on a Map, which is composed of Entity objects. I don’t want to expose the Entity objects to the MapView, it only needs to know their location (ILocateable) and how to render them (IRenderable).
You seem to have two conflicting requirements:
and
So, if the MapView only needs IRenderable, then it should accept IRenderable and then check whether the class also implements ILocateable. In this case use its methods.
On the other hand, if you always need it to be ILocateable and IRenderable, then you should really create a derived interface in one of two ways Either
or
depending on how your code is at the moment.