Search code examples
oopdesign-patternsstrategy-pattern

Strategy Pattern the right thing?


i hope you can help me with my problem:

I have a Class doing soap calls. But if the soap definition changes i'll have to write a new class or inherit from it etc. So I came to the solution to write something like that:

switch(version)
{
  case "1.0":
     saopV1.getData()
  case "2.0":
     soapV2.getData()
}

Well pretty bad code, i know. Then I read about the Strategy pattern and i thought, wow that's what i need to get rid of this bad switch-case thing:

abstract SoapVersion
{
    public SoapVersion GetSoapVersion(string version)
    {
         //Damn switch-case thing
         //with return new SoapV1() and return new SoapV2()
    }
    public string[] virtual getData()
    {
          //Basic Implementation
    }
}

class SoapV1:SoapVersion
{
       public override string[] getData()
       {
           //Detail Implementation
       }
}

class SoapV2:SoapVersion
{//the same like soapv1}

But i can't avoid using "ifs" or switch cases in my code. Is this possible using OO-techniques??

Edit: The GetSoapVersion-Function should be static


Solution

  • That's more or less the right way to do this in a beautiful fashion. At some point in your code, you'll have to make a decision whether v1 or v2 has to be used, so you'll have to have a conditional statement (if or switch) anyway. However, when using a strategy and a factory (factory method or factory class), you've centralized that decision.

    I would make my factory method on the abstract class static though. Also, I would make use of the template-method pattern: that is, a public, non overridable GetData method which calls a protected virtual (abstract) method that should be overriden in a concrete implementation.

    public abstract class SoapProcessor
    {
    
        protected SoapProcessor() { /* protected constructor since public is of no use */  }
    
        public static SoapProcessor Create( SoapVersion version )
        {
              switch( version )
              {
                   case SoapVersion.Version1 : return new SoapV1Processor();
                   case SoapVersion.Version2 : return new SoapV2Processor();
                   default: throw new NOtSupportedException();
              }
        }
    
    
        public string[] GetData()
        {
             return GetDataCore();
        }
    
        protected abstract GetDataCore();
     }
    

    }