Programming to Interfaces
In our domain objects, we are often dealing with interfaces. We therefore do not necessarily know the exact implementation type at compile time. Consider the following classes:
public interface Shape {
public double getArea();
}
...
public class Rectangle implements Shape {
private double height;
private double width;
public Rectangle() {}
public Rectangle(double height, double width) {
this.height = height;
this.width = width;
}
@Override
public double getArea() {
return height * width;
}
}
...
public class Circle implements Shape {
...
}
...
public class ShapeContainer {
private List<Shape> shapes;
...
}Now we want to store the Shape Container in Mongo. The only problem for Morphia when dealing with interfaces is knowing which implementation class to instantiate. That is, when retrieving the first shape from Mongo, how does Morphia know whether to map it to a Rectangle or a Circle?
Morphia solves this by storing a value in the Mongo document, called "className", which holds the full class name of the Java object being stored in the document.
We just need to make sure that all the implementation classes are added to the Morphia instance:
Morphia morphia = new Morphia();
morphia.map(Circle.class)
.map(Rectangle.class)
.map(ShapeShifter.class);The shape container class can store the shape list as an embedded object:
public class ShapeContainer {
@Embedded
private List<Shape> shapes;
...
}...or as a list of references:
public class ShapeContainer {
@Reference
private List<Shape> shapes;
...
}So to summarize, Morphia makes programming to interfaces quite easy.