Является ли хорошей идеей использовать шаблон проектирования метода Factory для управления различными версиями классов в C #? - PullRequest
0 голосов
/ 15 мая 2009

Код ниже - небольшая отправная точка для нового (для меня) способа написания и управления кодом. Прежде чем я потерял несколько недель и, возможно, в конце скажу, что да, это была глупая идея, я подумал, что лучше сначала провести «стресс-тестирование» здесь.

Так вот в чем идея. Каждый раз, когда существуют зависимости типа, когда клиент (Envoker) classs использует Server (класс, предоставляющий некоторые службы - в следующем примере - Controller), клиент будет использовать статический метод для «заглушки» с именем, которое будет достаточно универсальным, чтобы это имя не нужно будет менять - например, CreateDynamicTextBox () или RunProcedureGetDataSet () и будет передавать объект конфигурации, в соответствии с которым фабрика будет предоставлять запрошенную версию класса Server, поэтому каждый раз, когда существует достаточно стабильная версия Server когда к нему должны быть добавлены новые функции (или должна быть изменена логика), и будет написана новая версия класса сервера. Предлагаемое преимущество - сохранение потока с помощью универсального метода и передача объекта «установка».

Это плохая идея ?! Если да, то почему? Что-нибудь положительное в этом подходе?!

using System;


namespace ControllerFactory
{
  class ClientEnvoker
  {
    static void Main ( string[] args )
    {

      Console.WriteLine ( " START " );
      ClientEnvoker objClientEnvoker = new ClientEnvoker ();

      ControllerFactory objControllerFactory = new ControllerFactory ();

      Console.WriteLine ( " RUN METHOD 1 WITH CONTROLLER 1 WITH CONFIG 1 " );
      objControllerFactory.GenericMethodName ( ControllerFactory.CFSetter.First );

      Console.WriteLine ( " RUN METHOD 2 WITH CONTROLLER 2 WITH CONFIG 2 " );
      objControllerFactory.GenericMethodName ( ControllerFactory.CFSetter.Second );

      Console.WriteLine ( " RUN METHOD 3 WITH CONTROLLER 3 WITH CONFIG 3 " );
      objControllerFactory.GenericMethodName ( ControllerFactory.CFSetter.Second );

      Console.WriteLine ( " END HIT A KEY TO EXIT " );
      Console.ReadLine ();

    } //eof method 

  } //eof class 


  class ControllerFactory
  {
    public enum CFSetter : int
    {
      First = 1,
      Second = 2 , 
      Third = 3
    }

    public void GenericMethodName ( CFSetter objCFSetter )
    {
      Controller c = this.FactoryMethod ( objCFSetter );
      c.ConcreteMethod ();
    } //eof method 

    public Controller FactoryMethod ( CFSetter objCFSetter )
    {
      Controller controllerReturn = null;
      switch (objCFSetter)
      {
        case CFSetter.First:
          controllerReturn = new Controller1 ();
          break;
        case CFSetter.Second:
          controllerReturn = new Controller2 ();
          break;
        case CFSetter.Third:
          controllerReturn = new Controller3 ();
          break;
        default:
          controllerReturn = new Controller1 ();
          break;
      }
      return controllerReturn;
    }

  } //eof class

  #region Controllers
  public abstract class Controller
  {
    public abstract void ConcreteMethod ();
  }


  public class Controller1 : Controller
  {

    public override void ConcreteMethod ()
    {
      Console.WriteLine ( "Controller1 screams according to version 1 logic" );
    }
  } //eof class 

  public class Controller2 : Controller
  {

    public override void ConcreteMethod ()
    {
      Console.WriteLine ( "Controller2 screams according to version 2 logic" );
    }
  } //eof class 


  public class Controller3 : Controller
  {

    public override void ConcreteMethod ()
    {
      Console.WriteLine ( "Controller3 screams according to version 3 logic" );
    }
  } //eof class 

  #endregion Controllers



} //eof namespace  

Ответы [ 2 ]

1 голос
/ 15 мая 2009

Можно использовать фабричный шаблон для чего-то подобного. Однако FactoryMethod() должно быть там, где находится логика, чтобы выбрать, какой класс создать. Кроме того, если FactoryMethod() возвращает тип Controller, то нет смысла приводить возвращаемый объект.

Ваш RunMethod() изменится на что-то вроде этого ...

ControllerFactory cf = new ControllerFactory();
Controller c = cf.FactoryMethod(objCFSetter);
c.Scream();

И ваш FactoryMethod() будет выглядеть так ...

Controller controllerReturn = null;
switch (objCFSetter) {
    case CFSetter.First:
      controllerReturn = new Controller1();
      break;
    case CFSetter.Second:  
      controllerReturn = new Controller2();
      break;
    default:
      controllerReturn = new Controller1();
      break;
}
return controllerReturn;
0 голосов
/ 15 мая 2009

Спасибо, Джон. Я думаю, что вы имели в виду реализацию, которую я публикую ниже (конечно, не собираюсь принимать это как ответ!). Да, это кажется более простым, чем мой код выше со странным статическим методом. Тем не менее, это та же самая «функциональность»? Если этот тип «горячей замены» работает, как часто или в каких ситуациях он может быть использован (я думаю о динамическом создании элементов управления и динамическом выборе поставщиков баз данных).

using System;


namespace ControllerFactory
{
  class ClientEnvoker
  {
    static void Main ( string[] args )
    {

      Console.WriteLine ( " START " );
      ClientEnvoker objClientEnvoker = new ClientEnvoker ();

      ControllerFactory cf = new ControllerFactory ();

      Console.WriteLine ( " RUN METHOD 1 WITH CONTROLLER 1 WITH CONFIG 1 " );
      cf.RunMethod ( ControllerFactory.CFSetter.First );

      Console.WriteLine ( " RUN METHOD 2 WITH CONTROLLER 1 WITH CONFIG 2 " );
      cf.RunMethod ( ControllerFactory.CFSetter.Second );


      Console.WriteLine ( " END HIT A KEY TO EXIT " );
      Console.ReadLine ();

    } //eof method 

  } //eof class 


  class ControllerFactory
  {
    public enum CFSetter : int
    {
      First = 1,
      Second = 2
    }

    public void RunMethod ( CFSetter objCFSetter )
    {
      Controller c = this.FactoryMethod ( objCFSetter );
      c.Scream ();
    } //eof method 

    public Controller FactoryMethod ( CFSetter objCFSetter )
    {
      Controller controllerReturn = null;
      switch (objCFSetter)
      {
        case CFSetter.First:
          controllerReturn = new Controller1 ();
          break;
        case CFSetter.Second:
          controllerReturn = new Controller2 ();
          break;
        default:
          controllerReturn = new Controller1 ();
          break;
      }
      return controllerReturn;
    }

  } //eof class

  #region Controllers
  public abstract class Controller
  {
    public abstract void Scream ();
  }


  public class Controller1 : Controller
  {

    public override void Scream ()
    {
      Console.WriteLine ( "Controller1 screams according to version 1 logic" );
    }
  } //eof class 

  public class Controller2 : Controller
  {

    public override void Scream ()
    {
      Console.WriteLine ( "Controller2 screams according to version 2 logic" );
    }
  } //eof class 

  #endregion Controllers



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