(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 HolidayDiscount
e 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 HolidayOffer
ha un numero di HolidayDiscounts
e, 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?