(私はこの質問を見ましたが、最初の答えはデザインよりも自動プロパティに関するもので、2番目の答えは、データストレージコードをコンシューマから隠すことです。これは、自分のコードが何をしたいのかわからないのですが、他の意見も聞きたいです)
私には2つの非常に類似したエンティティが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;
}
}
このインターフェースには、2つのエンティティーが実装する単一のゲッターメソッドがありますが、これはもちろん機能しますが、それが優れたデザインであるとは思えません。値を保持することはプロパティではないため、これは動作を表すものではありません。これはかなり単純なケースですが、似たような複雑なケースがいくつかあります(3〜4ゲッターを使用)。
私の質問は、これは悪いデザインですか?より良いアプローチとは何ですか?