(Ho visto questa domanda , ma la prima risposta riguarda le proprietà automatiche più che la progettazione, e la seconda dice di nascondere il codice di archiviazione dei dati al consumatore , che non sono sicuro di ciò che voglio / il mio codice fa, quindi mi piacerebbe sentire qualche altra opinione)
Ho due entità molto simili HolidayDiscounte RentalDiscount, che rappresentano gli sconti di lunghezza come "se dura almeno numberOfDays, percentè applicabile uno sconto". Le tabelle hanno fk per diverse entità padre e vengono utilizzate in luoghi diversi, ma dove vengono utilizzate, esiste una logica comune per ottenere lo sconto massimo applicabile. Ad esempio, a HolidayOfferha un numero di HolidayDiscountse, nel calcolare il suo costo, dobbiamo capire lo sconto applicabile. Lo stesso vale per i noleggi e RentalDiscounts.
Poiché la logica è la stessa, voglio mantenerla in un unico posto. Ecco cosa fanno il seguente metodo, predicato e comparatore:
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());
}
}
Poiché le uniche informazioni necessarie sono il numero di giorni, finisco con un'interfaccia come
public interface LengthDiscount {
Integer getNumberOfDays();
}
E le due entità
@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'interfaccia ha un unico metodo getter implementato dalle due entità, che ovviamente funziona, ma dubito che sia un buon design. Non rappresenta alcun comportamento, dato che detenere un valore non è una proprietà. Questo è un caso piuttosto semplice, ne ho un paio in più di casi simili e più complessi (con 3-4 getter).
La mia domanda è: è un cattivo design? Qual è un approccio migliore?