Нужен рисунок дизайна для удаления enums и оператор коммутатора в создании объекта

StackOverflow https://stackoverflow.com/questions/3897221

Вопрос

Допустим, я создаю спортивную игру, а в этой игре существуют различные позиции, которые игрок может играть, атаковать, защиту и т. Д. Так я начну с создания базового класса:

public abstract class Position
{
 public abstract string Name
 {
  get;
 }
}

и подклассы ...

public class Defender : Position
{
 public override string Name
 {
  get { return "Defender"; }
 }
}

и так далее. Это все в порядке.

Но теперь мне нужна функция для создания этих объектов. Мне нужна создание функции позиции. Таким образом, одно возможное решение состоит в том, чтобы создать enum всех позиций и передавать это значение функции, которая включает в себя enum и возвращает соответствующий объект. Но это вызывает мой код запаха тревоги. Эта вуза связывает классы, enum и выключатель внутри функции:

public static Position GetByType(Types position)
{
 switch(position)
 {
  case Types.Defender:
   return new Defender();
... and further terrible code

На какое решение я должен смотреть? Какой шаблон дизайна это?

Это было полезно?

Решение

Если вам нужно сделать это в небольших масштабах, переключатель не очень плохой, особенно если он живет в одном месте.

Если вам нужно сделать это в среднем масштабе, вы можете немного подумать о улучшении внутренних участников - предложение Стива Эллингера является разумным. Лично я предпочитаю использовать IDictionary<MyEnum, Action<T>> Где действие возвращает новый экземпляр рассматриваемого класса.

Если вам нужно сделать это в грандиозном или настраиваемом масштабе, вам, вероятно, следует проверить контроллер IOC, такой как structureMap или Ninject, или в чем -то, с чем классные дети играют в эти дни.

Другие советы

Звучит как Заводская модель.

Однако не может быть плохой вещью, чтобы иметь право коммутатора, который включает в себя enum / String, чтобы вернуть правильный тип объекта .... если это так изолирован в одном месте.

Действительно, что вы хотите, это абстрактная фабрика. Легкость реализации завода зависит от языка, который вы используете. PHP позволяет использовать имена переменного класса, поэтому вы можете просто отправить в название класса и получить новый $ Classname. Однако другие языки не позволяют этому. На самом деле, если ваш язык не делает этого, вы уже создали заводский класс!

На самом деле нет ничего более элегантного, которое вы можете сделать, если вы не хотите использовать отражение, чтобы имитировать, что делает PHP.

Один из способов справиться с переключением - это сделать заводской объявление типов, а затем использовать перечисление в качестве индекса в массиве, как так:

public abstract class Position {
    public abstract string Name {
        get;
    }
}
public class Defender : Position {
    public override string Name {
        get { return "Defender"; }
    }
}
public class Attacker : Position {
    public override string Name {
        get { return "Attacker"; }
    }
}
public static class PositionFactory {
    public enum Types {
        Defender, Attacker
    }
    private static Type[] sTypes = new Type[] { typeof(Defender), typeof(Attacker)};
    public static Position GetByType(Types positionType) {
        return Activator.CreateInstance(sTypes[(Int32)positionType]) as Position;
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top