Good afternoon everyone,
I'm doing an api to order participants in different competitions. The competitions have different trials, for example, push-ups and run. The point is that trials can be measured in different ways, in this case, push-ups in reps and run in seconds, so I guess the best way of doing this is having a method that can be override, lets say getRating(int mark), where mark would be 5 push ups or 10 seconds. That method will return the rating the athlete will have in that trial.
From my point of view, I have two approaches. The first one is using an enum, but since I want to persist the info, I'm not quite sure about how to do it. I've seen that i need to use the @Enumerated notation here. This I think will solve the problem but if I want to get information about the trials after (name, description or any other attribute I include), will I have problems since they are not in the DB? Also it is important to notice that if there is only one competition this won't be really a problem, but if the number starts to grow, the number of trials will increase even more, so I don't really know if this is the best approach.
This would be something similar to this:
public enum Trial {
PUSH_UPS("Push-ups", "Test your upper body strength by doing push-ups.") {
@Override
public String getRating(int result) {
if (result >= 40) {
return "Excellent";
} else if (result >= 30) {
return "Good";
} else if (result >= 20) {
return "Fair";
} else {
return "Poor";
}
}
},
PULL_UPS("Pull-ups", "Test your upper body strength by doing pull-ups.") {
@Override
public String getRating(int result) {
if (result >= 20) {
return "Excellent";
} else if (result >= 15) {
return "Good";
} else if (result >= 10) {
return "Fair";
} else {
return "Poor";
}
}
},
RUNNING("Running", "Test your cardiovascular endurance by running.") {
@Override
public String getRating(int result) {
if (result <= 420) { // 7 minutes (420 seconds) for 1 mile
return "Excellent";
} else if (result <= 540) { // 9 minutes (540 seconds) for 1 mile
return "Good";
} else if (result <= 660) { // 11 minutes (660 seconds) for 1 mile
return "Fair";
} else {
return "Poor";
}
}
};
private final String name;
private final String description;
Trial(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public abstract String getRating(int result);
}
The second one is having an abstract class and extends from it every single trial. In order to persist I think a single table would be the best choice. From here I have a question, with this approach do I need a single Service, a single DAO and a single Controller for every trial? Is there a way to simplify this structure?
This would be the abstract class
public abstract class Trial {
private final String name;
private final String description;
protected Trial(String name, String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public abstract String getRating(int result);
}
This would be the trials:
public class PushUpsTrial extends Trial {
public PushUpsTrial() {
super("Push-ups", "Test your upper body strength by doing push-ups.");
}
@Override
public String getRating(int result) {
if (result >= 40) {
return "Excellent";
} else if (result >= 30) {
return "Good";
} else if (result >= 20) {
return "Fair";
} else {
return "Poor";
}
}
}
public class PullUpsTrial extends Trial {
public PullUpsTrial() {
super("Pull-ups", "Test your upper body strength by doing pull-ups.");
}
@Override
public String getRating(int result) {
if (result >= 20) {
return "Excellent";
} else if (result >= 15) {
return "Good";
} else if (result >= 10) {
return "Fair";
} else {
return "Poor";
}
}
}
public class RunningTrial extends Trial {
public RunningTrial() {
super("Running", "Test your cardiovascular endurance by running.");
}
@Override
public String getRating(int result) {
if (result <= 420) { // 7 minutes (420 seconds) for 1 mile
return "Excellent";
} else if (result <= 540) { // 9 minutes (540 seconds) for 1 mile
return "Good";
} else if (result <= 660) { // 11 minutes (660 seconds) for 1 mile
return "Fair";
} else {
return "Poor";
}
}
}
So the question I'm asking is, which approach is better? Is there another better way of solving this problem? Is the solution the same in the end?
Thank you.