2011-11-03 13 views
0

の特定のイベントを聴く:我々は以下のクラス構造を持っていると仮定継承したクラス

public class Fruit 
{ 
    public event EventHandler<RipeEventArgs> Ripe; 
} 

public class Apple:Fruit 
{ 
    public event EventHandler<FallEventArgs> FallFromTree; 
} 

public class Farm 
{ 
    List<Fruit> fruits; 
} 

public class Farmer 
{ 
    private Farm myFarm; 

    public Farmer() 
    { 
     // listen to all FallFromTree events coming from the farm 
     myFarm.WHAT += AppleFallen; 
    } 

    public void AppleFallen(object sender, FallEventArgs e) {} 
} 

質問:どのように私は農家が農業上の任意のリンゴからすべてのFallFromTreeイベントを聞くことができていることを確認しますと、将来作成されるリンゴはどれですか?

私はバブリングイベントを別に考えていましたが、それはFarmAppleでもカバーされる各イベントを定義する必要があることを意味します。問題は、私が異なるイベントでたくさんの異なる果物を作り、農家からの特定のイベントだけを特別な農家が聞くことが重要だということです。したがって、Farmの新しい種類のイベントをすべて定義することは、私の解決策のようには思えません。

+0

これは宿題ですか? –

+0

いいえ、私は巨大な 'Farm'クラスを作成しない方法を見つけようとしています。 – Marnix

+0

農家が興味を持っている可能性があるすべてのものを記述する列挙型を追加するだけではなく、特定の果物イベントについて農家が知っていることと異なるものではありません。しかし、あなたは今や単一のイベントしか必要としないというかなりの利点があります。 –

答えて

1

を参照してください。

public class Fruit 
{ 
    public event EventHandler<RipeEventArgs> Ripe; 
} 

public class Apple:Fruit 
{ 
    public event EventHandler<FallEventArgs> FallFromTree; 
} 

public class Farm 
{ 
    List<Fruit> fruits; 
    Farmer farmer; 

    public Farm(Farmer farmer) 
    { 
     this.farmer = farmer; 
    } 

    public void AddFruit(Fruit fruit) 
    { 
     farmer.RegisterForEvents(fruit); 
     fruits.Add(fruit); 
    } 
} 

public class Farmer 
{ 
    private Farm myFarm; 

    public Farmer() 
    { 

    } 

    public virtual void RegisterForEvents(Fruit fruit) 
    { 
     //Farmer decides what events it is interested in: can override in derived classes 
     if(fruit is Apple) 
     { 
      ((Apple)fruit).FallFromTree += AppleFallen; 
     } 
    } 

    public void AppleFallen(object sender, FallEventArgs e) {} 
} 

fruit is Apple句は理想的ではありませんが、私はあなたが行うことができる唯一のことは、二重派遣を実装するかFruitの種類ごとにFarmer上のさまざまな方法を持っているのいずれかがあると思います。

+0

これは有望ですね。チーム内の可能性について話し合うつもりです。 – Marnix

+0

これは完璧な答えだったかもしれませんが、残念ながらこのパターンによって促進できない要件がさらに増えています。例えば。そのイベントが何であるかを知らなくても、すべてのイベントを購読することができます。しかし、私が尋ねた質問に対しては、これは正しい実装になります。ありがとう。 – Marnix

+0

よろしくお願いいたします。あなたの一般的な要件について:最終的には、「Farmer」がどのイベントを購読すべきかを決定する必要があります。そのため、あなたはおそらくその行動をどこかに生かす必要がある「Farmer」自体からその知識を隠すことができます。その責任があなたの既存のオブジェクトのいずれかに収まらないようであれば、その役割を果たす新しいクラスを導入する必要があることを示しているかもしれません。がんばろう。 –

0

コマンドを処理するコマンドハンドラを実装する必要があります。リンゴの秋をコマンドの例にする。

public class MakeAppleFallCommandHandler 
{ 
    public void Execute(Apple apple) 
    { 
     //This method would be called whenever any apple in the farm falls 

     FallFromTree(apple); 
    } 

    public event EventHandler<FallEventArgs> FallFromTree; 
} 

次に農家クラスでは、MakeAppleFallCommandHandler.FallFromTreeに登録することができます。これはCQRSに触発されています。

+0

これらのコマンドハンドラをどこから去るのですか?良いパターンのように見えますが、新しいイベントごとに新しいCommandHandlerを登録する必要があるため、これで 'Farm'コードが大幅に増加することはありません。 – Marnix

+0

あなたのロジックは、アプリケーションにたくさんのコードがあるようなものです。 1つのクラスの問題は、多くのクラスに対していくつかのコードを持つコードに対して多くの問題があります。上記のパターンでは、ファームがどのコマンドハンドラを購読するかのロジックを含むサブスクリプションマネージャクラスを記述できます。 – Suhas

0

ファームにフルーツがあれば、フルーツのイベントだけを購読することができます。

あなたの基本クラスにFruitという仮想イベントを定義し、appleの場合のようにFruitsの別の子クラスでオーバーライドします。これはFallFromTreeになります。

だけFarmFarmer知らせるのではなくFarmerFarmを知ってこれをより詳細 C#: What are virtual events and how can they be used?

+0

これは 'Fruit'クラスを非常に増加させ、どんな種類の果物も木からどのように落ちるか知っていることを意味し、果実は木からも成長しないことを意味します。だから、これは巨大な農場クラスの回避策に過ぎません。 – Marnix

+0

いいえ、私が意味したのは、FruitクラスがChildEventという汎用イベントを持つということでした。それぞれの子供はそれ自身の方法でそれを公開するでしょう。 appleのように、ChildEventのFallFromTreeが公開されます。他の果物は、そのプロパティに従って自分のChildEventsをオーバーライドします。根の中で栽培されたフルーツのようにGrownFromRootが公開されます – Anand

+0

しかし、それは各果物には1つの出来事しかないことを意味します。それは確かにそうではありません。私は彼らにも複数のイベントを開催してもらいたい。 – Marnix

関連する問題