Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Strategy pattern instead of several if statements

I have this method with lot of if statements, in which I'm filtering SharePoint list based on employee position.The result is query string which is passed as parameter to another method QuerySPList.

 public List<Phone> GetListOfPhones(Employee emp)
 {
    List<Phone> records = new List<Phone>();
    string query = string.Empty;

    if (emp.Positions.Count == 1 && emp.Positions[0] == "Regular")
    {
       query = "";// some querystring                              
    }


    if (emp.Positions.Count == 1 && emp.Positions[0] == "OfficeDirector")
    {   
       query = "";// some querystring    
    }

    if (emp.Positions.Count == 1 && emp.Positions[0] == "Admin")
    {
        query = "";// some querystring 
    }              

    if (emp.Positions.Count == 2 && emp.Positions.Contains("Regular") && emp.Positions.Contains("OfficeDirector"))
    {

      query = "";// some querystring 

     }

   var rawItems = QuerySPList(query);

   foreach (SPListItem item in rawItems)
   {
        //business logic 
   }
   return records;
}}

I've read that with implementing strategy pattern we can avoid messy code with lot of if's , however , I'm new to developing , and design patterns , so I need little help with this one,so if someone can guide me what should I do and give me advice , feel free to answer my question.I have idea , but I think that I'm going in the wrong direction. Idea is to create interface IRoleHandler and than implement it to 3 classes , for example RoleAdmin ,RoleRegular,RoleOfficeDirector.Something like this :

public interface IRoleHandler<T>
{
    string handleRole(T obj);
}
public class RoleAdmin:IRoleHandler<Employee>
{

    public string handleRole(Employee emp)
    {
        if (emp.Positions.Count == 1 && emp.Positions[0] == "Admin")
        {
            //return some string query
        }

    }
}

Then idea is to create dictionary,something like this :

Dictionary<string, IRoleHandler<Employee>> strategyHandlers = new Dictionary<string, IRoleHandler<Employee>>();
        strategyHandlers.Add("Admin", new RoleAdmin());
        strategyHandlers.Add("Regular", new RoleRegularUser());
like image 427
Hank Mooody Avatar asked Dec 28 '15 16:12

Hank Mooody


1 Answers

Firstly, I think you need to be less concerned with the 'internal structure' of the Strategy Pattern and more concerned with its design goal/use.

https://en.wikipedia.org/wiki/Strategy_pattern

the strategy pattern (also known as the policy pattern) is a software design pattern that enables an algorithm's behavior to be selected at runtime. The strategy pattern

  • defines a family of algorithms,
  • encapsulates each algorithm, and
  • makes the algorithms interchangeable within that family.

To me, it looks like you are actually intending to "create" a string, based on some input value.

Therefore you would likely want to use one of the Creational patterns

My suggestion would be likely be Factory Pattern, or possibly Builder pattern. (Both linked in the creational patterns link)

private string BuildQueryByEmployee(Employee emp) {
    // create your builder
    EmployeeQueryBuilder mBuilder = new EmployeeQueryBuilder ();
    // add # of positions
    mBuilder.addPositionCount(emp.Positions.Count);
    // add each position
    for (int i =0 ; i < emp.Positions.Count; i++ ){
        mBuilder.addPosition(emp.Positions[i]);
    }
    // 'build' your query. 
    // and return the query as a string.
    return mBuilder.buildQuery(); 
}

Then inside your EmployeeQueryBuilder class, you handle the complexity of how to build your query based on the # of positions, and what they are.


Secondly, Here are some links that might be of use to you.

  • https://en.wikipedia.org/wiki/Software_design_pattern (General disc. of Patterns)
  • https://en.wikipedia.org/wiki/Design_Patterns (The "Gang of Four" book, essentially the first book on design patterns, and worth reading a few times, and writing each pattern out by hand a few times until you are comfortable with them, this alone will boost your coding ability by 2~3x if you haven't used patterns before, The examples in this book are somewhat out of date, since its motivating factor is writing a Text Editor... but still a 'classic', well worth knowing)
  • http://www.cs.wustl.edu/~schmidt/POSA/POSA2/ (One of the first books on patterns that have to deal with Concurrency) (POSA = Pattern Oriented Software Architecture) (might be overkill for now, but 'good to know about' in general)
like image 107
mawalker Avatar answered Sep 24 '22 05:09

mawalker