これはVisitorパターンの候補になります。
public abstract class Animal {
public abstract int Legs { get; }
public virtual void Speak() { Console.WriteLine("..."); }
public abstract void Accept(IAnimalVisitor visitor);
}
お知らせ受け入れる方法:
は、以下の基本クラスを取ることができます。これはVisitorオブジェクトで魔法が起こる場所です。
これらは私たちが処理する必要がある派生動物として実装します。
public class Cat : Animal {
public bool IsMewling { get; set; }
public override int Legs { get; } = 4;
public override void Accept(IAnimalVisitor visitor) { visitor.Visit(this); }
public override void Speak() { Console.WriteLine("Meow"); }
}
public class Dog : Animal {
public bool IsBarking { get; set; }
public override int Legs { get; } = 4;
public override void Accept(IAnimalVisitor visitor) { visitor.Visit(this); }
public override void Speak() { Console.WriteLine("Woof"); }
}
大丈夫、非常に良い。私たちがチェックする必要がある異なるプロパティ名のブール値のカップル。 IAnimalVisitorインターフェイスを実装できます。
public interface IAnimalVisitor {
void Visit(Dog dog);
void Visit(Cat cat);
}
最後に、動物が発話しているかどうかを確認する実装を作成し、条件によって異なる動作をすることができます。
public class LetsHearWhatItHasToSay : IAnimalVisitor {
public void Visit(Dog dog) {
if (dog.IsBarking) dog.Speak();
else Console.WriteLine("Good boy!");
}
public void Visit(Cat cat) {
if (cat.IsMewling) cat.Speak();
else Console.WriteLine("Pretty kitty");
}
}
大丈夫です。小さなサンプルの中にすべて一緒に結びつけることができます。
void Main()
{
var animals = new List<Animal>
{
new Cat { IsMewling = true },
new Dog { IsBarking = false },
new Cat { IsMewling = false },
new Dog { IsBarking = true }
};
var visitor = new LetsHearWhatItHasToSay();
foreach (var animal in animals)
{
animal.Accept(visitor);
}
}
そして、我々は、この場合には、訪問者を使用する利点は、私たちはクラスの上に論理演算の種類を扱うことができるカプセル化された任意の数のオブジェクトを作成することができます私たちの期待される出力
Meow
Good boy!
Pretty kitty
Woof
を取得そのクラス階層を変更することなくタイプセーフな方法で階層構造を作成できます。欠点は、訪れたいAnimalを追加するときに、その階層で動作するすべての訪問者を更新する必要があることです。
音が宿題のようですか? – JonE
デザインに関する特定の質問は、http://programmers.stackexchange.comに適していますが、これは意見に基づいています。 –
@NexTerren他のサイトを参照している場合、[クロスポストが嫌になっている]ことを指摘すると便利です(http://meta.stackexchange.com/tags/cross-posting/info) – gnat