Is it fine for your data models to have a sort of "open-ended" list of properties?
For example, you may have some Employee
:
// getters, setters, annotations are omitted
public class Employee {
private final String name;
private final String lastName;
private final String departmentId;
}
It may have a list of hard-coded properties as well as a special "magic" method called:
private final Map<String, Object> additionalProperties = new HashMap<>();
// ...
public Object getProperty(String propertyName) {
return additionalProperties.get(propertyName);
}
It may come in handy if your schemas are fluid. Anytime anyone can throw in an additional key-value pair into a DB procedure you call, and you as a developer don't feel like updating your entity/DTO classes each time it happens (especially, as the extra property may "fly by night"). So you make your data classes that correspond to DB-returned key-value pair groupings have a special map of any properties that don't match any of the hardcoded fields. Then you provide a public accessor that queries the map in case there's a need (probably, an ad-hoc need) to process an additional property.
The term "additional properties" refers to those properties that are not tightly coupled with a given domain model and yet, at least somewhere, returned by a database along with the model's intrinsic properties. Additional properties are likely to be properties of associated entities. In my case, it could be departmentName
, for example. They could also be calculated or derived values.
Is it an acceptable way of dealing with the kind of situation I described?
There's an alternative that I mentioned here (it's the approach I currently use): to keep your entities nice and tight but provide a wrapper type that can extend your data class with additional values:
public class ExtendedEntity<T> {
private final T entity;
private final Map<String, Object> additionalProperties;
private ExtendedEntity(T entity, Map<String, Object> additionalProperties) {
this.entity = entity;
this.additionalProperties = additionalProperties;
}
public ExtendedEntity<T> of(T entity, Map<String, Object> additionalProperties) {
return new ExtendedEntity<>(entity, additionalProperties);
}
@Override
public T getEntity() {
return entity;
}
public Object getAdditionalValue(String propertyName) {
return additionalProperties.get(propertyName);
}
}
I'm not as sure about my choice anymore, though. Any time someone adds just one extra property, you have to change the entire data type (e.g. from Employee
to ExtendedEntity<Employee>
). It may affect DAOs, services, clients of those services, etc. Maybe, we should keep all the extra properties inside entities themselves (if any are present).
What do you think?