I have two objects that represent a 'Bar/Club' ( a place where you drink/socialise).
In one scenario I need the bar name, address, distance, slogon
In another scenario I need the bar name, address, website url, logo
So I've got two objects representing the same thing but with different fields.
I like to use immutable objects, so all the fields are set from the constructor.
One option is to have two constructors and null the other fields i.e:
class Bar {
private final String name;
private final Distance distance;
private final Url url;
public Bar(String name, Distance distance){
this.name = name;
this.distance = distance;
this.url = null;
}
public Bar(String name, Url url){
this.name = name;
this.distance = null;
this.url = url;
}
// getters
}
I don't like this as you would have to null check when you use the getters
In my real example the first scenario has 3 fields and the second scenario has about 10, so it would be a real pain having two constructors, the amount of fields I would have to declare null and then when the object are in use you wouldn't know which Bar
you where using and so what fields would be null and what wouldn't.
What other options do I have?
Two classes called BarPreview
and Bar
?
Some type of inheritance / interface?
Something else that is awesome?
Best Answer
My thoughts:
A "Bar", as represented in your domain, has all of the things that may be needed in either place: name, address, URL, logo, slogan, and "distance" (I'm guessing from the requester's location). Therefore, in your domain, there should be one "Bar" class that is the authoritative source of data for one bar, no matter where the data will be used later. This class should be mutable, so that changes to the bar's data can be made and saved when necessary.
However, you have two places in which this Bar object's data is needed, and both of them only need a subset (and you don't want that data to be changed). The usual answer is a "data transfer object" or DTO; a POJO (plain ol' Java object) containing the immutable property getters. These DTOs can be produced by calling a method on the main Bar domain object: "toScenario1DTO()" and "toScenario2DTO()"; the results being a hydrated DTO (meaning that you only need to use the long, complicated constructor in one place).
If you ever needed to send data back to the main domain class (to update it; what's the point of data if you can't change it as needed to reflect the current state of the real world?), you could construct one of the DTOs, or use a new mutable DTO, and hand it back to the Bar class using an "updateFromDto()" method.
EDIT: to provide an example:
The Address, Distance and Url classes should either be immutable themselves, or when used in the DTOs they should be replaced with immutable counterparts.