(J'ai vu cette question , mais la première réponse concerne plus les propriétés automatiques que la conception, et la seconde dit cacher le code de stockage des données au consommateur , ce que je ne suis pas sûr de savoir ce que je veux / mon code fait, donc j'aimerais entendre une autre opinion)
J'ai deux entités très similaires HolidayDiscount
et RentalDiscount
qui représentent des remises de durée comme «si cela dure au moins numberOfDays
, une percent
remise est applicable». Les tables ont des fks vers différentes entités parentes et sont utilisées à différents endroits, mais là où elles sont utilisées, il existe une logique commune pour obtenir la remise maximale applicable. Par exemple, a HolidayOffer
a un certain nombre de HolidayDiscounts
, et lors du calcul de son coût, nous devons déterminer la remise applicable. Idem pour les locations et RentalDiscounts
.
Puisque la logique est la même, je veux la garder en un seul endroit. C'est ce que font la méthode, le prédicat et le comparateur suivants:
Optional<LengthDiscount> getMaxApplicableLengthDiscount(List<LengthDiscount> discounts, int daysToStay) {
if (discounts.isEmpty()) {
return Optional.empty();
}
return discounts.stream()
.filter(new DiscountIsApplicablePredicate(daysToStay))
.max(new DiscountMinDaysComparator());
}
public class DiscountIsApplicablePredicate implements Predicate<LengthDiscount> {
private final long daysToStay;
public DiscountIsApplicablePredicate(long daysToStay) {
this.daysToStay = daysToStay;
}
@Override
public boolean test(LengthDiscount discount) {
return daysToStay >= discount.getNumberOfDays();
}
}
public class DiscountMinDaysComparator implements Comparator<LengthDiscount> {
@Override
public int compare(LengthDiscount d1, LengthDiscount d2) {
return d1.getNumberOfDays().compareTo(d2.getNumberOfDays());
}
}
Étant donné que les seules informations nécessaires sont le nombre de jours, je me retrouve avec une interface
public interface LengthDiscount {
Integer getNumberOfDays();
}
Et les deux entités
@Entity
@Table(name = "holidayDiscounts")
@Setter
public class HolidayDiscount implements LengthDiscount {
private BigInteger percent;
private Integer numberOfDays;
public BigInteger getPercent() {
return percent;
}
@Override
public Integer getNumberOfDays() {
return numberOfDays;
}
}
@Entity
@Table(name = "rentalDiscounts")
@Setter
public class RentalDiscount implements LengthDiscount {
private BigInteger percent;
private Integer numberOfDays;
public BigInteger getPercent() {
return percent;
}
@Override
public Integer getNumberOfDays() {
return numberOfDays;
}
}
L'interface a une seule méthode getter que les deux entités implémentent, ce qui bien sûr fonctionne, mais je doute que ce soit une bonne conception. Il ne représente aucun comportement, étant donné que la détention d'une valeur n'est pas une propriété. Ceci est un cas assez simple, j'ai quelques cas plus similaires, plus complexes (avec 3-4 getters).
Ma question est, est-ce une mauvaise conception? Quelle est la meilleure approche?