4

あなたの仕事は、タスクの追跡をサポートする Project Plan クラス ライブラリを設計することです (MS Project の仕組みに似ています)。このクラス ライブラリには、Task(とりわけ) オブジェクトがあります。

TaskオブジェクトにはEstimatedHours( Double)、StartDate( DateTime)、EndDate( ) などのDateTimeプロパティがあります。Taskオブジェクトは、1 つの親オブジェクトTaskと複数の子オブジェクトを持つことができTaskます。子を持つ (親である)のEstimatedHoursStartDate、およびEndDateプロパティはTask、直接の子のプロパティに依存します。親Taskのは、その子の中でStartDate最も古いものです。StartDate親はその子の最新Taskのものです。親のは、その子の の合計です。したがって、子を持つ でこれらのプロパティを変更することは無効です。EndDateEndDateTaskEstimatedHoursEstimatedHoursTask

親を持つタスクで、EstimatedHours、StartDate、または EndDate が変更されるユース ケースをどのように処理しますか? (親のプロパティはその子を反映しているため、子を変更する場合は、変更を適切に反映するために親のプロパティを調整する必要がある場合があります)

1 つのオプションは、各プロパティが変更されたときのイベントを作成することです。親Taskは、直接の子オブジェクトでこれらのイベントをリッスンし、Taskそれらのイベントが発生したときに独自のプロパティに適切な変更を加えます。これは良いアプローチですか、それとももっと良い方法がありますか? どのようにしますか?

Taskオブジェクトがどのように見えるかについての基本的な考え方は次のとおりです。

Public Class Task

  Private mChildren As List(Of Task)

  Private mEndDate As DateTime = DateTime.MinVlue
  Public Property EndDate() As DateTime
    Get
      Return mEndDate 
    End Get
    Set(ByVal value As DateTime)
      mEndDate = value
      'What to do here?
    End Set
  End Property

  Private mEstimatedHours As Double = 0.0
  Public Property EstimatedHours() As Double 
    Get
      Return mEstimatedHours 
    End Get
    Set(ByVal value As Double)
      mEstimatedHours = value
      'What to do here?
    End Set
  End Property

  Private mStartDate As DateTime = DateTime.MinVlue
  Public Property StartDate() As DateTime
    Get
      Return mStartDate 
    End Get
    Set(ByVal value As DateTime)
      mStartDate = value
      'What to do here?
    End Set
  End Property

End Class
4

6 に答える 6

4

この問題を解決する正しいアプローチは、Observer Design Pattern を使用することです。Observer パターンの実装の詳細な説明は、この議論の範囲を超えています。しかし、Observer Pattern の素晴らしいリンクがいくつかあります。1 つのリンクはここにあり、もう1 つのリンクはここにあります

http://www.dofactory.com/Patterns/PatternObserver.aspx

http://en.wikipedia.org/wiki/Observer_pattern

于 2009-04-14T13:14:00.407 に答える
2

これが実際の方法かどうかはわかりませんが、別のオプションがあります。Task に子を持たせる代わりに、ITask インターフェイスを実装する Task と TaskSet の 2 つのオブジェクトを使用します。Task には独自の StartDate、EndDate、EstimatedHours がありますが、TaskSet は子タスクからこれらの値を動的に計算します。サービスを使用して、子を ITask に追加および削除します。追加の場合、最初の子が追加されると Task が TaskSet に変換されます。削除の場合、最後の子が削除され、最後の子の値からプロパティが設定されると、TaskSet が Task に変換されます。

于 2009-04-14T13:18:47.557 に答える
1

これはモデルの責任の一部ではなく、その上にあるコントローラーの責任であると考えます。

イベントまたはオブザーバー パターンをモデルに追加すると、シリアライゼーションなど、回避したい他の領域で複雑さが増します。

モデル自体ではなく、変更を行うクラスの責任にします。覚えておいてください: モデルの責任は情報を含むことであり、ビジネス ルールを意味することではありません。

于 2009-04-14T13:17:08.043 に答える
1

イベント チェーン内の 1 つのイベントが例外をスローすると、次のイベントは呼び出されないことに注意してください。そのため、データに登録されている他のイベントがある場合、イベントが呼び出されない可能性があります。

ベース タスクがその子タスクから離れないようにすることがアプリケーションにとって重要な場合は、イベントを使用しないでください。

于 2009-04-14T13:17:59.133 に答える
1

最初にオブジェクト モデルを構築して、その場で値を計算できるようにします。私は C# に最も慣れているので、C# を提供します (サンプルを小さく保つために、プロパティの代わりにフィールドも使用しています)。

public class Task
{

    public List<Task> Children=new List<Task>();
    public Task Parent;   
    private int _duration;

    public int Duration
    {

       get
       {
          if (Children.Count>0)
          { 
              return SumChildrenDuration();
          }

          return _duration;
       }

       set 
       {
          if (children.Count>0)
              throw new Exception("Can only add to leaves");
          _duration=value;
       }
    }
}

これが整ったら、システムを実行するために必要なすべてのコードが手に入ります。システムが十分に機能することがわかり、このままにしておく場合があります。それ以外の場合は、追加の機能を追加して結果をキャッシュし、オブジェクトが変更されたときにキャッシュをリセットできます。キャッシングと有効期限がその場で計算するよりも高価ではないことを確認したいので、何をするにしても、それを綿密にプロファイリングしてください.

于 2009-04-14T13:18:29.103 に答える
0

私は自分の ASP.NET 開発者に、「イベントは監視します。メソッドは仕事をします」と言っています。

イベントは、メソッドを呼び出す IFblocks に過ぎないはずです。try/catch などはありません。
メソッドはすべてのデータ アクセス/操作/検証/計算などを行います。
これにより、私の開発者にも「再利用可能なコード」の考え方が生まれます。

それは物事を分離したままにします。
また、MVC の概念とよく似ています。

コントローラーはイベントに反応します。彼らが監督します。これらは Model メソッドを呼び出します。
モデルが仕事をします。

完全なパラレルではありません。
確かに単純化されていますが、かなり良いガイドラインになります。

于 2009-04-14T13:32:08.070 に答える