Какой шаблон дизайна это будет, и это хорошая идея? (С #) - PullRequest
4 голосов
/ 11 марта 2012

У меня есть класс, который я хочу расширить функциональностью в виде декоратора / адаптера, только я не хочу, чтобы мой расширяющий класс знал что-либо о видах классов, которые он расширяет, и Я не хочу писать новый класс для каждого типа объекта, который я хочу расширить. Все объекты, которые я хотел бы расширить, имеют общий базовый класс Team. Это звучит созрели для использования дженериков, поэтому вот моя первоначальная идея:

public class TournamentTeam<T> : T
   where T : Team
{
   private int mSeed;

   public TournamentTeam(T team, int seed)
      : base(team)
   {
      /*
       * error checking stuff here
       */

      // set class variables
      this.mSeed = seed;
   }

   public int Seed
   {
      get { return this.mSeed; }
   }
}

Это сделало бы то, что я хотел, так как теперь, если я хочу получить доступ к членам T, у нового класса есть все из них. Базовый конструктор позаботится о настройке состояния таким образом, чтобы расширенному классу не нужно было об этом беспокоиться. Я также не должен был бы знать, какие методы переопределить, чтобы указывать на внутренний объект типом декоратор / фасад. Излишне говорить, что это не скомпилировано. Итак, я попробовал что-то немного другое.

    public class TournamentTeam<T> : Team
        where T : Team
    {
        #region class variables
        private int mSeed;
        private T mTeam;
        #endregion

        public TournamentTeam(int seed, T team)
            : base(team)
        {
            /*
             * error checking stuff here
             */

            // set class variables
            this.mSeed = seed;
            this.mTeam = team;
        }

        public int Seed
        {
            get { return this.mSeed; }
        }

        public T Team
        {
            get { return this.mTeam; }
        }
    }

Хорошо, теперь, если я хочу получить функциональность «базового класса», я просто вызываю свойство Team, и я готов идти дальше. И, поскольку это универсально, мне не нужно заниматься боксом, чтобы добраться до функциональности. это работает, это не красиво, но это работает.

Что это за образец, если он существует, и какие подводные камни вы все-таки увидите в этой идее? Есть ли лучший способ сделать это?

Ответы [ 2 ]

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

К сожалению, C # не допускает наследования от параметров типа, потому что я думаю, что первый дизайн идеален, учитывая то, чего вы хотите достичь.

Второй дизайн выглядит как разумное применение шаблона адаптера, при условии, что вы гарантируете, что все открытые члены TournamentTeam, унаследованные от Team, будут перенаправлены в инкапсулированную Team.

Лично, если бы я разработал это в C #, я бы отказался от шаблона адаптера в пользу простой композиции и сделал бы что-то вроде следующего:

  • Переименуйте TournamentTeam во что-то другое ... может быть, TournamentTeamAllocation или TournamentTeamInfo или что-то в этом роде (имена сложно!). По сути, он будет отвечать за обработку данных, относящихся как к турниру, так и к команде (например, к семенам)
  • Измените его так, чтобы оно ничего не делило на подклассы
  • Сохраните инкапсуляцию, чтобы она все еще содержала T : Team.
1 голос
/ 11 марта 2012

это то, что должно быть сделано, как я это вижу принцип "композиция в пользу наследования" и шаблон "стратегия" (если я не ошибаюсь)

Мне также нравится имплиментация.

...