Dealing with similar objects with different method signatures

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?

2

Contrary to many (perhaps most) object-oriented design tutorials out there, inheritance hierarchies should not necessarily match up with a domain’s real-world taxonomy. In other words, just because all your objects are shapes in the real world doesn’t necessarily mean they should all inherit from IShape in your program. Even if they do all share an interface, just because they have similar methods doesn’t mean those methods need to be part of that interface.

The trick is to look at the calling code to see what operations you really need at that point. For example:

for shape in shapes:
  shape.doSomething()

Are you really going to call AddValue in a loop like that? I doubt it. More likely, it’s going to be something like Draw or GetEditControl, and AddValue will be called before it’s even put into shapes, or by a dimension-aware EditControl. In other words, IShape should only have methods that don’t care about dimension, and operations that care about dimension should be handled by other interfaces.

Your shapes shouldn’t hold their values through the interface. The interfaces are things you need to be able to do with them. The classes are the various ways you can fulfill those same things.

If your effort is to draw these shapes to the screen your interface is going to have nothing to do with values of any kind directly.

public interface IDrawable {
    void Draw(Graphics g);
}

This way you can invent completely new shape ideas you never thought of without having to change the signatures of how they interact. That is all the OO is for. Isolate the interaction to a single thing that will work for everything. (hint: You will often be abstracting a function, not a value.)

Now when you decide you need to be able to write these shapes to a data storage you can add.

public interface IWritable {
    void Write(Stream s);
}

Now there is place for these values to be typed, everything works better if its typed. Notice you can pretty much put anything here now, and freely mix-and-match.

public class Line : IDrawable , IWritable {
    public Point Start { get; set; }
    public Point End { get; set; }
    public void Draw(Graphics g) { }
    public void Write(Stream s) { }
}

public class ThreePointTriangle : IDrawable , IWritable {
    public Point First { get; set; }
    public Point Second { get; set; }
    public Point Third { get; set; }
    public void Draw(Graphics g) { }
    public void Write(Stream s) { }
}

public class SinRightTriangle : IDrawable , IWritable {
    public Point AngleA { get; set; }
    public Line Opposite { get; set; }
    public Line Hypotenuse { get; set; } 
    public void Draw(Graphics g) { }
    public void Write(Stream s) { }
}

public class Car : IDrawable {
    public void Draw(Graphics g) { }
}

The answer is simply, these aren’t similar objects. Inheritance is about shared behaviour, not shared values. Just because these objects are made up of points doesn’t mean they are related in terms of behaviour.

Leaving aside that getters and setters aren’t really behaviour and should be avoided if at all possible*, even in this case the getters and setters are doing different things, as hinted by the different signatures. This should make it clear, these objects do not share behaviour beyond the most meaningless sense of storing points.

(this is a good example of why to avoid getters and setters, as they can cloud the true behaviour of an object, and make it appear that unrelated objects are related because they all have getter and setter methods)

How about something like this:

public interface ICoordinateValue {}

public class Value1D : ICoordinateValue {}
public class Value2D : ICoordinateValue {}
public class Value3D : ICoordinateValue {}


public interface IShape
{
    IEnumerable<ICoordinateValue> GetValues();
    void AddValue(ICoordinateValue value);
}

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật