(Widziałem to pytanie , ale pierwsza odpowiedź dotyczy bardziej właściwości automatycznych niż projektowania, a druga mówi, że ukryj kod przechowywania danych przed konsumentem , czego nie jestem pewien, czy tego chcę / mój kod robi, więc chciałbym usłyszeć inną opinię)
Mam dwóch bardzo podobnych podmiotów, HolidayDiscount
oraz RentalDiscount
, że stanowią rabaty długość jak „jeśli to trwa co najmniej numberOfDays
, o percent
zniżka ma zastosowanie”. Tabele mają fks do różnych podmiotów nadrzędnych i są używane w różnych miejscach, ale tam, gdzie są używane, istnieje wspólna logika, aby uzyskać maksymalną obowiązującą zniżkę. Na przykład a HolidayOffer
ma pewną liczbę HolidayDiscounts
i przy obliczaniu jej kosztu musimy obliczyć odpowiednią zniżkę. To samo dotyczy wynajmu i RentalDiscounts
.
Ponieważ logika jest taka sama, chcę ją zachować w jednym miejscu. To właśnie robią następująca metoda, predykat i komparator:
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());
}
}
Ponieważ jedyną potrzebną informacją jest liczba dni, kończę na interfejsie jako
public interface LengthDiscount {
Integer getNumberOfDays();
}
I dwa byty
@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;
}
}
Interfejs ma metodę pojedynczego gettera, którą implementują dwa byty, co oczywiście działa, ale wątpię, czy to dobry projekt. Nie reprezentuje żadnego zachowania, ponieważ utrzymanie wartości nie jest własnością. To dość prosty przypadek, mam kilka podobnych, bardziej złożonych przypadków (z 3-4 pobierającymi).
Moje pytanie brzmi: czy to zły projekt? Jakie jest lepsze podejście?