tenac
tenac

Reputation: 97

Design patterns regarding if...else statements

I'm quite new to the field of design patterns and I'm having trouble handling a traditional scenario comprising multiple conditions.

Let's say I have a service (e.g. Printer) which has multiple attributes and depends on different parameters (e.g Department, Documenttype). When I want to verify for a specific parameter combination if an attribute is set correctly, I end up with a lot of if...else conditions.

In pseudo code it would look like this:

class Printer 
{
  AttributeA a;
  AttributeB b;
  AttributeC c;
  ...
  checkAttributeA(Department departement, Documenttype doctype);
  checkAttributeB(Department departement, Documenttype doctype);
  checkAttributeC(Department departement, Documenttype doctype);
  ...
 };

Printer::checkAttributeA(Department departement, Documenttype doctype)
{
  if (department == DepartmentA) 
  {
     if (doctype == DocumenttypeA) 
     {
        // do somthing
     } 
     else if (doctype == DocumenttypeB) {
        // do somthing else
     } 
     ...
  }
 else if (department == DepartmentB) 
  {
     if (doctype == DocumenttypeA) 
     {
        // do somthing
     } 
     else if (doctype == DocumenttypeB) {
        // do somthing else
     } 
     ...
  }
...
}

In case of the strategie pattern, I need to create a class for every condition if I got this correctly. But it not sure if this would be the right way as the number of conditions/classes would grow exponentially with every parameter. Is there a proper way to handle such scenarios?

Upvotes: 0

Views: 249

Answers (1)

Aman Agnihotri
Aman Agnihotri

Reputation: 3023

Suppose there are M departments and N document types and for each possible combination of these two values there is a distinct action that must be taken.

There is an inherent complexity in such a problem statement where you cannot do away with defining what all those actions (M x N) would be and if each attribute of your printer leads to a different action for each possible combination of department and document type then you have to define them separately as well.

Consider a four dimensional matrix. The first dimension is an attribute, the second dimension is the department, the third dimension is the document type, and the fourth dimension is the respective action to be taken for the combination of those three values.

You will at least have to define those actions:

var matrix = {
  AttributeA: {
    DepartmentX: {
      DocumentP: SomeActionA,
      DocumentQ: AnotherActionA
    },
    DepartmentY: {
      DocumentP: SomeActionB,
      DocumentQ: AnotherActionB
    }
  },
  AttributeB: {
    // similar structure
  },
  // and so on...
};

Now you can have a single function which takes in your attribute, department, and document type and does the action:

function takeAction(attribute, department, documentType) {
  // maybe do a sanity check of your inputs
  matrix[attribute][department][documentType](); // calling the action!
}

This way, you are separating your configurable data from your generic logic as well.

Upvotes: 1

Related Questions