Использование шаблонов проектирования для добавления функциональности во время выполнения - PullRequest
0 голосов
/ 09 марта 2012

У меня есть абстрактный класс "MainClass", который составляет класс "Animal". Я извлекаю два класса TypeA и TypeB из абстрактного класса, который содержит общие функциональные возможности. Классы TypeA и TypeB должны быть расширены для включения их собственных специфических функций.

Например, TypeA потребует добавить функциональность cat в класс Animal. Так что тестовое приложение будет обращаться к классу cat, как этот typeA._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 ]

1 голос
/ 09 марта 2012

Во-первых, я считаю, что Тигр, Кошка, Леопард должны наследоваться от Животных.Теперь вы можете использовать общий базовый класс с ограничениями типов, чтобы сделать то же самое.Например,

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 голосов
/ 09 марта 2012

Первое, что вам нужно сделать, это создать наследование:

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 нарушает принцип единой ответственности, поэтому я бы разбил его на отдельный класс.

0 голосов
/ 09 марта 2012

Ваш основной класс должен иметь List<Animal> _animals вместо Animal _animals.Классы Tiger, Cat и Leopard должны наследоваться от класса Animal.Затем вы можете поместить свойство type в базовый класс Animal.Во время выполнения вы можете добавить столько Animals в список _animals, сколько захотите, и поскольку свойство type находится в базовом классе Animal, вы получите доступ к нему во всех производных классах.

0 голосов
/ 09 марта 2012

Да, использование Abstract Factory Pattern может решить вашу проблему. Проверьте это на:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...