I am trying to build a framework of objects where the main actors can be interchanged freely. At the moment I’ve done this by creating an abstract base class that all of my actors can be derived from. A key reason for using an abstract class over an interface was there there is a very small bit of common code that all of the derived classes should be using.
My goal is to make a system that can be easily extended by other developers (one day) that shares some common logic and the derived objects can be seamlessly interchanged.
I’ve had a few issues with the way I’ve designed the system. One being that it hasn’t been easy to test consumers of my framework. But the one I’m most interested in solving at the moment is that some of the derived classes need to implement IDisposable because they contain objects which need to be disposed.
The best solution I’ve found at the moment is to have the abstract class implement IDisposable even though it doesn’t require it and some of the other derived classes don’t either. I realize I have some fundamental issues with the way I’ve modelled my objects and I’m trying to work out the best way to do it.
However, I’m still curious what is the best way to conditionally implement IDisposable? Or do I just have a serious design issue that needs to get sorted out instead and I’m trying to solve a problem that will no longer be an issue with the correct model?
2
I don’t think it’s unreasonable for your abstract base class to provide an empty implementation of the IDisposable
interface, and for subclasses to implement their own implementation as required. That seems to me a commonly used and understood pattern.
2
Brian Agnew’s suggestion is very much applicable, but I’d like to point out something else:
I get the feeling that maybe the actors
(the plugged-in behavior you mentioend) on your model are carrying two very different responsibilities. Alternatively, you could design your framework to have a separate registration mechanism, exclusively for disposable resources, in the same way you allow the actors
to be registered. Just to clarify, let’s say you currently have the following class:
class MyFramework {
public void RegisterActor(Actor actor) {
...
}
}
And that the Actor base-class (or interface) looks like this:
abstract class Actor : IDispoable {
...
}
You could break apart the notions of actors
and disposable resources
by changing the usage of your framework to allow both to be registered separately, like so:
class MyFramework {
public void RegisterActor(Actor actor) {
...
}
public void RegisterResource(IDisposable resource) {
...
}
}
This would allow you to break the IDisposable
interface out of your actor
model, while still giving the option to the subclass implementer to have both implementations in the same object, if that makes sense, like so:
class SomeActorImplementation : Actor, IDisposable {
...
}
With that, the same object can be sent to both RegisterActor
and RegisterResource
methods of the framework object, but it will have no knowledge of it.
1