.NETオブジェクト階層 - イベントにかかっているかどうか
-
09-09-2019 - |
質問
あなたの仕事は、タスクの追跡をサポートするプロジェクト計画クラスライブラリを設計することです(MS Projectの仕組みと同様)。このクラスライブラリには Task
オブジェクト(とりわけ)。
Task
オブジェクトには EstimatedHours
(Double
), StartDate
(DateTime
)、 と EndDate
(DateTime
)特にプロパティ。 a Task
オブジェクトには1人の親を持つことができます Task
, 、そして数人の子供 Task
オブジェクト。 EstimatedHours
, StartDate
, 、 と EndDate
aのプロパティ Task
子供がいる(親は)、その直接の子供の財産に依存しています。親 Task
's StartDate
最も早いです StartDate
その子供たちの。親 Task
's EndDate
最新です EndDate
その子供たちの。親 Task
's EstimatedHours
子供の合計です EstimatedHours
. 。したがって、これらのプロパティを変更することは無効です Task
子供がいます。
親がいるタスクでTismatedHours、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
解決
この問題を解決するための正しいアプローチは、オブザーバーのデザインパターンを使用することです。オブザーバーパターンの実装の詳細な説明は、この議論の範囲を超えています。しかし、ここにオブザーバーパターンのためのいくつかの素晴らしいリンクがあります。 1つのリンクです ここ そしてもう一つはです ここ.
http://www.dofactory.com/patterns/patternobserver.aspx
http://en.wikipedia.org/wiki/observer_pattern
お役に立てれば。
Ruchit S.
他のヒント
これが実際にそれを行う方法であるかどうかはわかりませんが、ここに別のオプションがあります。タスクに子供を持つことを許可する代わりに、2つのオブジェクト、タスクとITASKインターフェイスを実装するタスクセットを使用します。タスクには独自のStartDate、EndDate、および推定ホールがありますが、タスクセットは子のタスクからそれらの値を動的に計算します。サービスを使用して、子供を追加してITASKに削除します。追加するために、最初の子供が追加されたときにタスクをタスクセットに変換します。削除するために、タスクセットをタスクに戻し、最後の子供が削除され、最後の子の値からプロパティを設定します。
イベントチェーンの1つのイベントが例外をスローする場合、次のイベントが呼び出されないことに注意してください。したがって、データに登録されている他のイベントがある場合 五月 イベントが呼ばれない可能性があります。
アプリケーションにとって、基本タスクが子供とは触れられないことが重要である場合は、イベントを使用しないでください。
最初にオブジェクトモデルを構築して、値をその場で計算するようにします。私はあなたに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;
}
}
}
これを配置すると、システムを実行するために必要なすべてのコードが表示されます。システムが十分に機能し、このように残していることがわかります。それ以外の場合は、追加の機能を追加して結果をキャッシュし、オブジェクトが変更されたときにキャッシュをリセットできます。キャッシュと有効期限がより高価ではないことを確認したいので、あなたが何をするにしても、それを綿密にプロファイルするようにしてください。
これはモデルの責任の一部ではなく、その上にあるコントローラーの一部だとは考えていません。
モデルにイベントまたはオブザーバーパターンを追加すると、シリアル化などの他の領域に複雑さが追加されます。
モデル自体ではなく、修正を行うクラスの責任にします。覚えておいてください:モデルの責任は、ビジネスルールを暗示するのではなく、情報を封じ込めることです。
ASP.NET開発者に、「イベントは監督します。方法は作業を行います」と言います。
イベントは、ifblocks呼び出しメソッドにすぎないはずです。試行/キャッチなど。
メソッドすべてのデータアクセス/操作/検証/計算などを行います。
これにより、開発者に「再利用可能なコード」考え方も作成されます。
物事を分離し続けます。
また、MVCの概念に非常によく似ています。
コントローラーはイベントに反応します。彼らは監督します。彼らはモデル法を呼び出します。
モデルは作業を行います。
それは完全な類似点ではありません。
確かに、それは単純ですが、それはかなり良いガイドラインになります。