You have a nice set of entities
but then someone decides to add one or two more stupid values that are used only in one place (or maybe, not so stupid but ones I would rather avoid)
Now, you have a choice: to add extra fields to your entity (that are not going to be used for the most part) or write a whole new entity / response DTO, copying all the fields from the existing entity (probably, a lot) and adding a couple of fields. And it’s going to sit idle most of the time
I don’t like either choice
A concrete example. I collaborate on a medical desktop Swing app. We have an entity for vaccines. Vaccines and infections are in a many-to-many relationship, there’s a join table. Don’t expect we use some ORM framework with @AllThoseNeatAnnotations
. In one window, we need to render vaccines with asterisks beside their names if they protect against more than one infection. And the data we get also includes one field for the number of “additional” infections, qty
(the vaccine table or its corresponding entity doesn’t). For example, “vaccine 1” that protects against “infection A” and “infection B” would come from the DB with text
as “vaccine 1”, vaccine_text
as “vaccine 1*” and qty
as “1” (if it doesn’t make a ton of sense to you, I can relate). Am I supposed to create a whole new entity / DTO for that?
I guess I can make some decorator that wraps the entity and a map of additional fields. So far, it’s the most appealing option
import java.util.Map;
// sorry, I won't elaborate further but hope you get the point
public class ExtendedEntity<T extends DBTable> implements PersistableEntity<T> {
private final T row;
private final Map<String, Object> additionalValues;
public ExtendedEntity(T row, Map<String, Object> additionalValues) {
this.row = row;
this.additionalValues = additionalValues;
}
@Override
public T getTable() {
return row;
}
public Object getAdditionalValue(String key) {
return additionalValues.get(key);
}
}
What should I do, as a frontend developer?
3
You have to provide models that are useable, but you should avoid coupling the models to the presentation layer.
So in your example of vaccines and infections I would expect the vaccine model to have some data on what infections it related to. eg.
Vaccine
{
Id : 1
Name : "one"
TreatableInfectionIds :[1,2,3,4]
}
Infection
{
Id : 1
Name : "oneitis"
}
Now if the presentation layer wants to put a star next to the name, Or load in the infections for the vaccine to display more data, It can do with no model changes.
Your model should be enough for all use cases, you shouldn’t need extra entities or DTOs with the exact same fields, or the same with extra calculated fields
In the presentation layer you might want to compose models in to ViewModels for convenience, although it looks like swift is a bit ‘old skool’ in this regard. ie
VaccineInfoPage
{
LoggedinUser : {}
VaccineInQuestion : {}
ListOfTreatableInfections [{}]
SelectedPatient : {}
}
But this should be kept in the presentation layer, your controller should get the models needed to build this from your business layer
This sounds like presentation logic which should be handled in the presentation layer of the application. This is not core business logic.
Depending on your architecture, this should be handled in a view model, view, or presenter. Ideally, your data model in the database should allow the frontend to infer how many injections a vaccine protects against, when qty > 0
show an asterisk next to the name of the vaccine.
I believe your hesitance to add this fact to every layer of your application is justified, however I don’t know the underlying data model, so it’s hard to make a concrete recommendation. If your data model does not provide a means to count the number of infections a vaccine protects against, then adding another stupid column might be justified.
It sounds like each vaccine is presumed to guard against at least one infection. If the database reports a qty
of 1, it probably means 1 additional infection which means you would infer it guards against 2. Odd, but a little inductive logic can clear this up (plus about 20 years of history on the project).
2