(Я бачив це запитання , але перша відповідь стосується властивостей авто більше, ніж про дизайн, а друга говорить про приховування коду зберігання даних від споживача. Я не впевнений, що я хочу / мій код робить, тому я хотів би почути якусь іншу думку)
У мене є два дуже схожих об'єктів, HolidayDiscount
і RentalDiscount
, які представляють довжини знижки , як "якщо вона триває , по крайней мере numberOfDays
, percent
знижка застосовується. У таблицях є fks для різних материнських об'єктів, і вони використовуються в різних місцях, але там, де вони використовуються, існує загальна логіка, щоб отримати максимально можливу знижку. Наприклад, у А HolidayOffer
є кількість HolidayDiscounts
, і при обчисленні його вартості нам потрібно розібратися в застосовній знижці. Те саме для оренди та RentalDiscounts
.
Оскільки логіка однакова, я хочу тримати її в одному місці. Ось що роблять наступний метод, предикат і порівняльник:
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());
}
}
Оскільки потрібною є лише інформація про кількість днів, я закінчую інтерфейс як
public interface LengthDiscount {
Integer getNumberOfDays();
}
І дві сутності
@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;
}
}
В інтерфейсі є один метод отримання, який реалізують два об'єкти, що, звичайно, працює, але я сумніваюся, що це хороший дизайн. Він не представляє жодної поведінки, якщо утримувати значення не є властивістю. Це досить простий випадок, у мене є ще пара подібних, складніших справ (з 3-4 дітьми).
Моє запитання: це погана конструкція? Який кращий підхід?