( Bu soruyu gördüm , ancak ilk cevap, tasarımdan daha fazla otomatik özelliklerle ilgili ve ikincisi , veri depolama kodunu tüketiciden gizlediğini söylüyor , istediğimden emin değilim / kodum ne yapıyor, başka bir fikir duymak istiyorum)
Ben iki çok benzer varlıkları, sahip HolidayDiscount
ve RentalDiscount
'o en azından sürerse olarak uzunluk indirimler temsil numberOfDays
, bir percent
indirim uygulanabilir.' Tablolarda farklı üst varlıklar için fks'ler vardır ve farklı yerlerde kullanılırlar, ancak kullanıldıkları yerde, uygulanabilir maksimum indirimi almak için ortak bir mantık vardır. Örneğin, HolidayOffer
a'nın bir sayısı vardır HolidayDiscounts
ve maliyetini hesaplarken geçerli indirimi bulmamız gerekir. Aynı kiralık ve RentalDiscounts
.
Mantık aynı olduğundan, onu tek bir yerde tutmak istiyorum. Aşağıdaki yöntem, yüklem ve karşılaştırıcı bunu yapar:
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());
}
}
İhtiyaç duyulan tek bilgi gün sayısı olduğundan, bir arayüzle
public interface LengthDiscount {
Integer getNumberOfDays();
}
Ve iki varlık
@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;
}
}
Arayüz, iki varlığın uyguladığı, elbette işe yarayan tek bir alıcı yöntemine sahiptir, ancak iyi bir tasarım olduğundan şüpheliyim. Değer tutmanın bir özellik olmadığı göz önüne alındığında hiçbir davranışı temsil etmez. Bu oldukça basit bir durum, birkaç tane daha benzer, daha karmaşık durum var (3-4 alıcılı).
Sorum şu: Bu kötü bir tasarım mı? Daha iyi bir yaklaşım nedir?