Question

For my personal project I need to store 2D shapes in a Postgres database. For example Circle, Pentagon, Rectangle and so on. At first I've done it like so: all shapes are inherited from an abstract class called Shapes, which has some methods that I need each object to perform on itself, for example (I'm using java with Spring data):

for(Shape shape : shapes){
    shape.getArea();
}

This is good in code, but I don't know a good way to store this in a database. Every shape has some parameters that are different from others (radius for circle, height and length for rectangle etc.) so it looks like I need many tables for each geometry type. But how to reference each shape from another table then?

Right now I try to solve this with a single class called Geometry. It has a type field and a set of parameters linked to it Circle for example will have one record in table Geometry and one record in table Parameters. This class also has all the methods needed for each available shape, like this:

getArea(){
    switch(type){
        case circle: ....
        case pentagon: ...
    }
}

But I'm wondering if there are more elegant ways to solve this?

Was it helpful?

Solution

That depends on if you just want to store the shapes, or perform queries on their properties.

If you just want to store them, the simplest way is to serialize them and store the serialized data, along with a shapeid field to let you know what kind of shape you've got. Each subclass could handle its own serialization. Very similar to storing images in a database.

If you want to perform queries on the properties of a given shape, you have to expose those properties as columns on a table, or use PostgreSQL's geometric types (as Patrick Mevzek mentioned). However, using types from a given database engine is not very portable.

OTHER TIPS

To maintain a complex geometric programme with all kind of shapes, you'd better go for polymorphism, and classes inheriting from Shape. This will make code more understandable and more maintainable (i.e. it's easier to add a new shape with polymorphism rather than with long switches).

Now for the persistance in a relational database, you have several alternatives that are very well described in Martin Fowler's book "Pattern of Enterprise Application Architecture":

  • As there are not so much parameters for a shape, you could go fo single table inheritance: you'd have a single table holding all the data, a little bit like with your geometry class.
  • If your shapes would be very complex, with lots of different data, you could go for class table inheritance: every class would have its own table (including Shape if it would have some kind of common data) .
  • Between both you'd have a concrete table inheritance, where every most derived class would have its own table with all its data (so the Squares and the Circles, but not Shape itself.

So the trick is to decouple somewhat the objects living in memory and the way they are stored in the database.

Licensed under: CC-BY-SA with attribution
scroll top