(我已经看到了这个问题,但是第一个答案更多的是关于自动属性而不是设计,而第二个答案则是向使用者隐藏数据存储代码,我不确定这是我想要的/我的代码做了什么,所以我想听听其他意见)
我有两个非常相似的实体,HolidayDiscount
和RentalDiscount
,它们表示长度折扣,即“如果至少持续numberOfDays
使用percent
折扣,则适用”。这些表有不同的父实体,并且在不同的地方使用,但是在使用它们的地方,有一种通用的逻辑来获取最大的适用折扣。例如,a 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;
}
}
该接口具有两个实体实现的单个getter方法,该方法当然可以工作,但是我怀疑这是一个好的设计。考虑到持有值不是属性,它不代表任何行为。这是一个非常简单的案例,我有几个类似,更复杂的案例(使用3-4个吸气剂)。
我的问题是,这是一个不好的设计吗?有什么更好的方法?