Is it a good idea to use the Factory design pattern for versioning classes in C #?

The code below provides a small starting point for a new way (for me) to write and manage code. Before I lose a few weeks and maybe finally declare that yes, it was a stupid idea, I thought it would be better to "stress test" here first.

So here's the idea. Every time there are type dependencies, when the Client (Envoker) classes are using the server (a class that provides some services, called a controller in the following example), the Client will use a static method to "stub" with a name that is generic enough, this name is not should change - for example, CreateDynamicTextBox () or RunProcedureGetDataSet () and pass a config object according to which the factory will provide the requested version of the Server class, so every time there is a fairly stable version of the server when new functions (or logic it must be changed) and a new version of the server class will be written. The suggested advantage would be to keep the stream through the generic method and pass the "customization" object.

It is a bad idea?! If so, why? Anything positive about this approach ?!

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  

      

0


a source to share


2 answers


It's good to use a factory pattern for something like this. However, there FactoryMethod()

has to be where the logic is to choose which class should be created. Also, if it FactoryMethod()

returns a type Controller

, then there is no reason to wrap the returned object.

Yours RunMethod()

would change to something like this ...

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

      



And yours FactoryMethod()

will look like this ...

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;

      

+1


a source


Thanks, John. I think you meant the implementation I'm posting below (of course I'm not going to accept it as an answer!). Yes, it seems to be simpler than my code above with a strange static method. However, is this the same "functionality"? If this type of hot-swap works that often, or what type of situations it might be used for (I'm thinking about creating dynamic controls and dynamically selecting database vendors).



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  

      

0


a source







All Articles