2012-03-09 9 views
0

私は、 "動物"クラスを構成する抽象クラス "MainClass"を持っています。共通の機能を持つ抽象クラスからTypeAとTypeBの2つのクラスを派生します。 TypeAクラスとTypeBクラスは、独自の機能を組み込むために拡張する必要があります。デザインパターンを使用してランタイムに機能を追加する

たとえば、TypeAはAnimalクラスの下にcat機能を追加する必要があります。テストアプリケーションがこのtypeA._animals._catのようなcatクラスにアクセスするようにしますか?

私はタイプが実行時に追加できないことは知っていますが、私の問題を解決できる他のデザインパターンはありますか?

public abstract class MainClass 
{ 
    public Animal _animals; 
} 

public class Animal 
{ 
    public Tiger _tiger; 
} 

public class Tiger 
{ 
    public int type { get { return "Tiger" ; } } 
} 

public class Cat 
{ 
    public int type { get { return "Car" ; } } 
} 

public class Leopard 
{ 
    public int type { get { return "Leopard" ; } } 
} 

public class TypeA : MainSession 
{ 
    //Would like to add type Cat to Animal class 
} 

public class TypeB : MainSession 
{ 
    //Would like to add type Leopard to Animal class 
} 
+0

タイトルにタグを使用する必要はありません。 –

+0

どのクラスがTypeAとTypeBですか?抽象クラスとしてAnimalクラスを作成し、それからTiger、Cat、Leopardを継承しない方が良いでしょうか? – Asdfg

+0

あなたは解決しようとしている問題は何ですか?現在のクラス構造がわかりません – BrokenGlass

答えて

0

あなたが最初にすべきことは、継承を作成することです:

public interface IAnimal 
{ 
    string SpeciesName {get; } 
} 

そして、それを実装:

public class Tiger : IAnimal 
{ 
    public string SpeciesName { get { return "Tiger" ; } } 
} 


public class Cat : IAnimal 
{ 
    public string SpeciesName { get { return "Cat" ; } } 
} 

はのは、それを使ってみましょう:

public abstract class MainSession 
{ 
    private List<IAnimal> _animals; 

    public IEnumerable<IAnimal> Animals {get { return _animals; }} 

    proteced void AddAnimal(IAnimal animal) 
    { 
     _animals.Add(animal); 
    } 
} 

public class TypeA : MainSession 
{ 
    public TypeA() 
    { 
     AddAnimal(new Tiger()); 
    } 
} 

public class TypeB : MainSession 
{ 
    public TypeB() 
    { 
     AddAnimal(new Leopard()); 
    } 
} 

ます。また、変換することができAddAnimal工場出荷時の方法:

public abstract class MainSession 
{ 
    private List<IAnimal> _animals; 

    public IEnumerable<IAnimal> Animals {get { return _animals; }} 

    protected IAnimal CreateAnimal(string speciesName) 
    { 
     // Either use reflection to find the correct species, 
     // or a simple switch like below: 
     switch (speciesName) 
     { 
      case "tiger": 
       return new Tiger(); 
       break; 
     } 
    } 
} 

工場をMainSessionにすると、単一の責任原則が破られるため、別のクラスに分割します。

1

最初に、私はTiger、Cat、LeopardをAnimalから継承するべきだと考えます。さて、同じようにタイプ制約を持つジェネリックベースクラスを使用することができます。たとえば、

public abstract class MainClass<A> where A:Animal 
{ 
    public A _animals; 
} 

public abstract class Animal 
{ 
    ... 
} 

public class Tiger : Animal 
{ 
    ... 
} 

public class Cat : Animal 
{ 
    ... 
} 

public class Leopard : Animal 
{ 
    ... 
} 

public class TypeA : MainSession<Cat> 
{ 
    ... 
} 

public class TypeB : MainSession<Leopard> 
{ 
    .... 
} 
0

はい、抽象ファクトリパターンを使用して問題を解決できます。あなたのメインクラスではなくAnimal _animalsList<Animal> _animalsを持っている必要があります

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

+0

抽象的な工場がどのように私を助けてくれるかわかりません。もう説明できますか? – sundar

+0

jgauffinの答えの2番目の部分は、factoryを使用する1つの例です。 – Shaunak

0

:上でこれをチェックしてください。 Tiger、Cat、LeopardクラスはAnimalクラスから継承する必要があります。次にtypeプロパティをAnimal基底クラスに配置できます。実行時にリストに好きなだけAnimalsを追加することができます。typeプロパティはAnimal基本クラスに含まれているため、すべての派生クラスでアクセスできます。

+0

私はリストを維持することを考えましたが、タイプにアクセスするためにリストを反復しなければならないと思います。私は型の名前を使ってアクセスしたいと思う。 – sundar

+0

リストの代わりにディクショナリを使用し、その型をキーとして使用し、Animalオブジェクトを値として使用することができます。 – robbymurphy

関連する問題