I am fairly new to OO design and have problems with the design of some software and looking for a pattern or a combination of patterns that could help me solving my problem.
I have a type that has a collection of different geometric shapes (say lines, rectangles, and cubes). I actually even have composites of these shapes. Each shape has one or more values. A value is a coordinate (between one-dimensional for lines and three-dimensional for cubes).
All types of shapes have two methods that are essential. A method for adding values and a method for getting all values of a shape. E.g. Cube.AddValue(new Value3D{X=4,Y=7,Z=11})
or Line.AddValue(new Value1D{X=42})
respectively Cube.GetValues()
would return a collection of Value3D
and Line.GetValues()
would return a collection of Value1D
.
Since these methods have fundamentally different signatures, I can't just derive from a single interface to store all of these different objects in one collection. Splitting the collection into multiple separate collections, one for each type would be possible, but not desirable since they belong together (domain wise).
I've considered using three-dimensional values for all shapes and just ignoring Y/Z for lines/rectangles, but that isn't really nice and would actually violate the O and L in SOLID (a 4th dimension is possibly needed in the future).
Another possibility would probably be to use a generic Interface like IShape<T>
where T
is Value*D. This interface would look like:
public interface IShape<T> {
public IEnumerable<T> GetValues();
public void AddValue(T value);
}
But this would require another, non-generic interface INonGenericShape {}
because I can't use a generic interface without specifying the type. I would end up with something like this:
public class SomeShape{
private IList<INonGenericShape> _shapes = new List<INonGenericShape>();
}
But then I could as well use System.Object
, since IShape does not provide any valuable information. So here I am, not knowing how to solve this (storing the objects in a single collection for consumers of that class). Can anyone provide some idea or insight?