Home  /  Questions  /  Question



58   94.9
Sep 28, 2011


What pattern to use?

Hi,

I'm totally new in patterns. I've read a lot about creational patterns and I think I've understud them theoretically. But I have problems, to choose the right pattern in real live.
My actual problem: I have a simple telephony application. In this application I have to deal with several phone interfaces. What I want to have is an object that tells me what interfaces are available to let the user choose one of them in a combobox. Then I only want to change the object to work with. E.g. depending on the selected interface the MakeCall method calls a method in an external dll, creates a textfile or writes the number to the registry or sometihing else.
But what is the best pattern to do this? Factory, abstract factory or builder pattern? Or something total different?
I hope you can help me to learn how to choose the right pattern.

Thanks a lot

Markus



90   96.5
Oct 06, 2011
Hi,

You have Family of products here, so factory pattern would be helpful.

Please refer to the code sample have put in here, you could think of having list of hard-coded strings but enums provide better control over the code, especially when you distribute it across developers and avoid case-sensitivity issues.

Please walk through the code, try and let me know your thoughts.

- Tarriq Ferrose Khan
//ENUMERATOR FOR EACH CUSTOM TELEPHONY TYPE

public enum TelephonyInterfaceType {TelephonyInterface1,TelephonyInterface2,TelephonyInterface3 }

// COMMON METHODS TO GET LIST OF ENUMS AND RETURN ENUM BASED ON STRING RETURNED FROM 
//DROPDOWN LIST
public Array GetListOfTelephonyInterfaceTypes()
        {
            
            Array lstProvider = System.Enum.GetValues(typeof(TelephonyInterfaceType));
                        return lstProvider ;
           //Use this Array to populate your dropdown list.
        }


private TelephonyInterfaceType GetTelephonyInterfaceType(string strFilterType)
        {
//send in the selected text from the dropdown to this method which will return the correct enum
// of the selected telephony interface
            TelephonyInterfaceType filterType = new TelephonyInterfaceType();
            Array lstProvider = System.Enum.GetValues(typeof(TelephonyInterfaceType));
            foreach (TelephonyInterfaceType enumFilterType in lstProvider)
            {
                if (enumFilterType.ToString().ToUpper() == strFilterType.ToUpper())
                {
                    filterType = enumFilterType;break;
                }
            }
            return filterType;
        }


//COMMON INTERFACE ACROSS CUSTOM TELEPHONY CLIENTS.

public Interface ICustomTelephony
{
  void MakeCall();
}

//EACH CLIENT CLASS 
public class TelephonyClient1:ICustomTelephony
{
   public void MakeCall()
   {
    // Provide your custom implementation here...
   }
}

public class TelephonyClient2:ICustomTelephony
{
   public void MakeCall()
   {
    // Provide your custom implementation here...
   }
}


public class TelephonyClient3:ICustomTelephony
{
   public void MakeCall()
   {
    // Provide your custom implementation here...
   }
}


//FACTORY

public class TelephoneFactory()
{
  public TelephoneFactory()
  {
  }

  public void MakeCall(string interfaceType )
  {
    //interfaceType should be the selected text from your Dropdown list box
    TelephonyInterfaceType interfaceType = GetTelephonyInterfaceType(interfaceType)
    ICustomTelephony iTelephony;
    switch(interfaceType)
    {
      case TelephonyInterfaceType.TelephonyInterface1:
       iTelephony= new TelephonyClient1();
      break;
      case TelephonyInterfaceType.TelephonyInterface2:
      iTelephony= new TelephonyClient2();
      break;
      case TelephonyInterfaceType.TelephonyInterface3: 
      iTelephony= new TelephonyClient3();
      break;
     }
     iTelephony.MakeCall();
  }

}

// MAKE CALL 

public class ClientTelehphony()
{

  private void BindDropdown()
  {
   //call GetListOfTelephonyInterfaceTypes method and populate the dropdown
  }

  //on selected index changed or event of your choice call below method

  public void MakeCall()
  {
    TelephoneFactory factory = new TelephoneFactory();
    factory.MakeCall(DropdownList1.SelectedText);
   //MakeCall() method of your relevant Client Telephony Class will be called, based on your dropdown selection.
   
  }

}

 

58   94.9
Oct 10, 2011
Hi,

thank you very much for your answer and your very good example code.
Because the telephone interface would not change very often (in best case it is set only once at the first call of the telephony application) I'm thinking about the following two things:
- Wouldn't it be good to set the used telephone interface in the factory class by a property in which the specific telephone object (iTelephony) of type ICustomTelephony is set? So I don't have to create a specific object in every method by select-case.
- Would it be a good way to get the specific telephone object (iTelephony) of type ICustomTelephony by a Methode of the factory class with a parameter whick specifies the used telephone interface? So I could directly call methods on this object (e.g. MakeCall) and don't have to implement this method again in the factory class? Would this way of implementation still be the factory pattern?
Lots of thoughts ;-) This is what i meant with heaving difficulties in applying theory to my actual problem.

90   96.5
Oct 10, 2011

1)- Wouldn't it be good to set the used telephone interface in the factory class by a property in which the specific telephone object (iTelephony) of type ICustomTelephony is set? So I don't have to create a specific object in every method by select-case.

2- Would it be a good way to get the specific telephone object (iTelephony) of type ICustomTelephony by a Methode of the factory class with a parameter whick specifies the used telephone interface? So I could directly call methods on this object (e.g. MakeCall) and don't have to implement this method again in the factory class? Would this way of implementation still be the factory pattern?

Ans for 2: ---- in my code sample just to make it simple for understanding have enclosed returning the class and making call in same method. Ideally you need to have a method like GetTelephoneProduct(<requiredParameter), which will return instance of the correct Telehpony class.

Then in the client class you can just do returnedobject.MakeCall()... which will be still Factory Pattern..

Ans for 1: If you have done per ans for 2, then you do not need the select case for every method..

Please find the modified code sample, for your reference,

In case if you want to have some other method, expose the same in the Interface and provide implementation in each individual classes

Hope this helps.

--Tarriq Ferrose Khan


//ENUMERATOR FOR EACH CUSTOM TELEPHONY TYPE

public enum TelephonyInterfaceType {TelephonyInterface1,TelephonyInterface2,TelephonyInterface3 }

// COMMON METHODS TO GET LIST OF ENUMS AND RETURN ENUM BASED ON STRING RETURNED FROM 
//DROPDOWN LIST
public Array GetListOfTelephonyInterfaceTypes()
        {
            
            Array lstProvider = System.Enum.GetValues(typeof(TelephonyInterfaceType));
                        return lstProvider ;
           //Use this Array to populate your dropdown list.
        }


private TelephonyInterfaceType GetTelephonyInterfaceType(string strFilterType)
        {
//send in the selected text from the dropdown to this method which will return the correct enum
// of the selected telephony interface
            TelephonyInterfaceType filterType = new TelephonyInterfaceType();
            Array lstProvider = System.Enum.GetValues(typeof(TelephonyInterfaceType));
            foreach (TelephonyInterfaceType enumFilterType in lstProvider)
            {
                if (enumFilterType.ToString().ToUpper() == strFilterType.ToUpper())
                {
                    filterType = enumFilterType;break;
                }
            }
            return filterType;
        }


//COMMON INTERFACE ACROSS CUSTOM TELEPHONY CLIENTS.

public interface ICustomTelephony
{
  void MakeCall();
}

//EACH CLIENT CLASS 
public class TelephonyClient1:ICustomTelephony
{
   public void MakeCall()
   {
    // Provide your custom implementation here...
   }
}

public class TelephonyClient2:ICustomTelephony
{
   public void MakeCall()
   {
    // Provide your custom implementation here...
   }
}


public class TelephonyClient3:ICustomTelephony
{
   public void MakeCall()
   {
    // Provide your custom implementation here...
   }
}



//FACTORY

public class TelephoneFactory
{
  public TelephoneFactory()
  {
  }

  public ICustomTelephony GetTelephonyProduct(string strInterfaceType )
  {
    //interfaceType should be the selected text from your Dropdown list box
    TelephonyInterfaceType interfaceType = GetTelephonyInterfaceType(strInterfaceType)
    ICustomTelephony iTelephony;
    switch(interfaceType)
    {
      case TelephonyInterfaceType.TelephonyInterface1:
       iTelephony= new TelephonyClient1();
      break;
      case TelephonyInterfaceType.TelephonyInterface2:
      iTelephony= new TelephonyClient2();
      break;
      case TelephonyInterfaceType.TelephonyInterface3: 
      iTelephony= new TelephonyClient3();
      break;
     }
     return iTelephony;
  }

}

// MAKE CALL 

public class ClientTelehphony
{
  ICustomTelephony iCustomTelephony;
  public ClientTelehphony()
  {
  }

  
  private void BindDropdown()
  {
   //call GetListOfTelephonyInterfaceTypes method and populate the dropdown
  }

  //on selected index changed of the DropdownList1 call below method

  public void SetTelephonyInterface()
  {  
   //call this method in Page_load or any initialization routine as well
  //, in case if you don ot   //have a default option
  //like --select-- in the dropdownlist, the Telephony product will be returned for the 1st 
  //item in the Dropdown list, that way iCustomTelephony will never be null.
  //The reason we have this in a method is to re-use the Initialization part when the 
  // user changes the Dropdown.
   if(DropdownList1.SelectedText==null) return;
   TelephoneFactory factory = new TelephoneFactory(); 
   iCustomTelephony= factory.GetTelephonyProduct(DropdownList1.SelectedText); 
  } 


  public void MakeCall()
  {
   if(iCustomTelephony!=null)
      iCustomTelephony.MakeCall();   
  }

}