質問

長年の質問について事前に謝罪します。ここでは特にフィードバックが高く評価されています。 。 。

私の仕事では、日付の範囲で多くのことをします(日付 期間, 、もしそうなら)。あらゆる種類の測定値を取得し、2つの日付期間の重複を比較する必要があります。インターフェイス、基本クラス、およびこれまでのニーズに役立ついくつかの派生クラスを設計しました。

  • idateperiod
  • DatePeriod
  • カレンダーソート
  • カレンダーウィーク
  • 会計年度

その必需品に剥奪されたDatePeriod SuperClassは次のとおりです(この一連のクラスが必要な理由の基礎となるすべての魅力的な機能を省略します。):

(Java Pseudocode):

class datePeriod implements IDatePeriod

protected Calendar periodStartDate
protected Calendar periodEndDate

    public DatePeriod(Calendar startDate, Calendar endDate) throws DatePeriodPrecedenceException
    {
        periodStartDate = startDate
        . . . 
        // Code to ensure that the endDate cannot be set to a date which 
        // precedes the start date (throws exception)
        . . . 
        periodEndDate = endDate
    {

    public void setStartDate(Calendar startDate)
    {
        periodStartDate = startDate
        . . . 
        // Code to ensure that the current endDate does not 
        // precede the new start date (it resets the end date
        // if this is the case)
        . . . 
    {


    public void setEndDate(Calendar endDate) throws datePeriodPrecedenceException
    {
        periodEndDate = EndDate
        . . . 
        // Code to ensure that the new endDate does not 
        // precede the current start date (throws exception)
        . . . 
    {


// a bunch of other specialty methods used to manipulate and compare instances of DateTime

}

基本クラスには、日付期間クラスを操作するためのかなり専門的な方法とプロパティの束が含まれています。派生クラスが変更されます それだけ 問題の期間の開始点と終了点が設定されている方法。たとえば、Calendarmonthオブジェクトが実際にDatePeriodを「IS-A」することは理にかなっています。ただし、明らかな理由で、暦月は固定期間であり、特定の開始日と終了日があります。実際、Calendarmonthクラスのコンストラクターはスーパークラスのコンストラクターと一致しますが(StartDateおよびEnddateパラメーターがあるという点)、これは実際には単純なコンストラクターの過負荷であり、単一のカレンダーオブジェクトのみが必要です。

カレンダーソンの場合、提供します どれか 日付は、問題の月の初日に始まり、 過去 その同じ月の日。

public class CalendarMonth extends DatePeriod

    public CalendarMonth(Calendar dateInMonth)
    {
        // call to method which initializes the object with a periodStartDate
        // on the first day of the month represented by the dateInMonth param,
        // and a periodEndDate on the last day of the same month.
    }

    // For compatibility with client code which might use the signature
    // defined on the super class:
    public CalendarMonth(Calendar startDate, Calendar endDate)
    {
        this(startDate)
        // The end date param is ignored. 
    }

    public void setStartDate(Calendar startDate)
    {
        periodStartDate = startDate
        . . . 
    // call to method which resets the periodStartDate
    // to the first day of the month represented by the startDate param,
    // and the periodEndDate to the last day of the same month.
        . . . 
    {


    public void setEndDate(Calendar endDate) throws datePeriodPrecedenceException
    {
        // This stub is here for compatibility with the superClass, but
        // contains either no code, or throws an exception (not sure which is best).
    {
}

長い前文についてお詫びします。上記の状況を考えると、このクラス構造はリスコフ置換の原則に違反しているように思われます。より一般的なDatePerioDクラスを使用する可能性のある場合、Calendarmonthのインスタンスを使用できますが、重要な方法の出力挙動は異なります。言い換えれば、特定の状況でカレンダーソムのインスタンスを使用していることに注意する必要があります。

Calendarmonth(またはCalendarWeekなど)は、基本クラスのIdatePeriodの使用を通じて確立された契約を順守していますが、カレンダーソムが使用され、普通のデート期間の挙動が予想される状況では、結果が恐ろしく歪める可能性があります。 。 。 (基本クラスで定義されている他のすべてのファンキーな方法は、適切に動作します。それは、Candalmonthの実装で異なる開始日と終了日の設定のみです)。

使用可能性や複製コードを損なうことなく、LSPへの適切な順守が維持されるようにこれを構築するより良い方法はありますか?

正しい解決策はありません

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top