(Saya sudah melihat pertanyaan ini , tetapi jawaban pertama tentang properti otomatis lebih dari tentang desain, dan jawaban kedua mengatakan menyembunyikan kode penyimpanan data dari konsumen , yang saya tidak yakin apa yang saya inginkan / kode saya tidak, jadi saya ingin mendengar pendapat lain)
Saya memiliki dua entitas yang sangat mirip, HolidayDiscount
dan RentalDiscount
, yang mewakili diskon panjang sebagai 'jika bertahan setidaknya numberOfDays
, percent
diskon berlaku'. Tabel memiliki fks ke entitas induk yang berbeda, dan digunakan di tempat yang berbeda, tetapi di mana mereka digunakan, ada logika umum untuk mendapatkan diskon maksimum yang berlaku. Misalnya, a HolidayOffer
memiliki sejumlah HolidayDiscounts
, dan ketika menghitung biayanya, kita perlu mencari tahu diskon yang berlaku. Sama untuk rental dan RentalDiscounts
.
Karena logikanya sama, saya ingin menyimpannya di satu tempat. Itulah yang dilakukan oleh metode, predikat, dan pembanding berikut:
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());
}
}
Karena satu-satunya informasi yang diperlukan adalah jumlah hari, saya berakhir dengan antarmuka sebagai
public interface LengthDiscount {
Integer getNumberOfDays();
}
Dan dua entitas
@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;
}
}
Antarmuka memiliki metode pengambil tunggal yang diterapkan dua entitas, yang tentu saja berfungsi, tapi saya ragu itu desain yang bagus. Itu tidak mewakili perilaku apa pun, mengingat memegang nilai bukanlah properti. Ini adalah kasus yang agak sederhana, saya punya beberapa kasus yang serupa, lebih kompleks (dengan 3-4 getter).
Pertanyaan saya adalah, apakah ini desain yang buruk? Apa pendekatan yang lebih baik?