BEFORE:
I have an interface that has one method definition
public interface IDockable
{
void Dock(DockerContainerConfig config);
}
Everything is ok for my first implementation
public class DockerContainer : IDockable
{
public void Dock(DockerContainerConfig config)
{
}
}
public class DockerContainerConfig
{
//machine configuration properties here
}
On my second implementation however, I realized that I need to use a different set of configuration.
public class DockerMachine : IDockable
{
public void Dock(DockerMachineConfig config)
{
}
}
public class DockerMachineConfig
{
//machine configuration properties here
}
AFTER:
In order to make the Configuration Classes
polymorphic, I created a parent class and let the Configuration Classes
inherit from it.
public class DockerConfig
{
}
public class DockerMachineConfig : DockerConfig
{
//machine configuration properties here
}
public class DockerContainerConfig : DockerConfig
{
//container configuration properties here
}
With this I also changed the method definition for the interface.
public interface IDockable
{
void Dock(DockerConfig config);
}
And in my concrete classes, I just did a cast on the configuration class objects. Please note that the two configuration classes are totally different, nothing is common. One deals with the machine so it needs machine configuration and the other deals with the container so it needs container configuration. But either way you do it, DockerContainer
and DockerMachine
does the same thing. “dock a container inside a machine”. It’s something like DockerMachine
does things from the outside and DockerContainer
does things from the inside. You get the idea 🙂
public class DockerContainer : IDockable
{
public void Dock(DockerConfig config)
{
DockerContainerConfig container = config as DockerContainerConfig;
}
}
public class DockerMachine : IDockable
{
public void Dock(DockerConfig config)
{
DockerMachineConfig machine = config as DockerMachineConfig;
}
}
There are two things that I think I made a mistake here:
- I changed the method definition in my interface from
void Dock(DockerContainerConfig config);
tovoid Dock(DockerConfig config);
- I created an empty parent class
public class DockerConfig{}
just to be able to make myConfiguration Classes
polymorphic
I would like to know if the changes I made conforming to good design and best practices.
3
public interface IDockable<T>
{
public void Dock(T config);
}
By having a type parameter, you can specify the parameter you want to accept within the Dock
method in your classes. Example:
public class DockerMachine : IDockable<DockerMachineConfig>
{
public void Dock(DockerMachineConfig config)
{
}
}
public class DockerContainer : IDockable<DockerContainerConfig>
{
public void Dock(DockerContainerConfig config)
{
}
}
That would be my personal preferred way to do this, but there are plenty of other ways which you’ll be able to come up with. What you’re currently doing could definitely be simplified by having a type parameter on the IDockable
interface which would be a little bit cleaner in my opinion.
4
Implementation specific parts shouldn’t be part of the interface. Instead take every specific config as a constructor parameter.
public interface IDockable
{
void Dock();
}
public class DockerContainer : IDockable
{
private DockerContainerConfig config;
public DockerContainer(DockerContainerConfig config)
{
this.config = config;
}
...
}
public class DockerMachine : IDockable
{
private DockerMachineConfig config;
public DockerMachine (DockerMachineConfig config)
{
this.config = config;
}
...
}
1