使用设计模式在运行时添加功能

时间:2012-03-09 04:14:37

标签: c# design-patterns

我有一个抽象类“MainClass”,它组成了“Animal”类。我从抽象类派生了两个类TypeA和TypeB,它包含常见的功能。需要扩展TypeA和TypeB类以包含它们自己的特定功能。

例如,TypeA需要在Animal类下添加cat功能。因此测试应用程序将访问cat类,如此类型A._animals._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  
}

4 个答案:

答案 0 :(得分: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>
{
    ....
}

答案 1 :(得分:0)

是的,使用抽象工厂模式可以解决您的问题。看看这个:

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

答案 2 :(得分:0)

您的主要课程需要List<Animal> _animals而不是Animal _animals。 Tiger,Cat和Leopard类应继承自Animal类。然后,您可以将type属性放在Animal基类中。在运行时,您可以根据需要将Animals列表添加到_animals列表中,并且由于type属性位于Animal基类中,您可以访问它在所有派生类中。

答案 3 :(得分: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会违反单一责任原则,所以我会将其分解为一个单独的类。