0

What is the best approach to achieve this (probably using some design pattern )?

Let say we have 3 stages to process a user input, at each stage data is validated/transformed and if successful next step is executed. Proceeding to next step is not desired if previous step fails.

class PipeAndFilter
{
  protected $input;
  protected $proceedToNextStep;

  public function __construct(Array $input)
  {
     $this->input=$input;
     $this->proceedToNextStep=true;
  }

  public function process()
  {
    $this->filterOne();
    if(!$this->proceedToNextStep()) return false;
    $this->filterTwo();
    if(!$this->proceedToNextStep()) return false;
    $this>filterThree()
    return $this->proceedToNextStep();
  }

  protected function filterOne()
  {          
     //perform some action and set 
     //$this->proceedToNextStep
  }

  protected function filterTwo()
  {
    //perform some action and set 
     //$this->proceedToNextStep
  }

  protected function filterThree()
  {
     //do some filter and set 
     //$this->proceedToNextStep
  }

}

I think the above class is enough to describe the problem . Is there any better approach/design pattern to accomplish this task ,probably using single class ?

Edit Got another approach , your comments please! (not tested)

class PipeAndFilter
{
  protected $callStack
  protected $input;
  /** fail states -ve numbers , success stats +ve numbers */
  protected $proceedToNextStep;

  public function __construct(Array $input)
  {
     $this->input=$input;
     $this->callStack=array();
     $this->callStack[]=array($this,'filterOne'));
     $this->callStack[]=array($this,'filterTwo'));
     $this->callStack[]=array($this,'filterThree'));
  }

  public function process()
  {
   foreach($this->callStack as $filterStep){
       call_user_func($filterStep);
       if(!$this->isProceedNext()) break;
   }
  }

  protected function isProceedNext()
  {       
    return $this->proceedToNextStep > 0 
  }

  protected function filterOne()
  {          
     //perform some action and set $this->proceedToNextStep

  }

  protected function filterTwo()
  {
     //perform some action and set $this->proceedToNextStep
  }

  protected function filterThree()
  {
     //perform some action and set $this->proceedToNextStep
  }

} 
sakhunzai
  • 13,900
  • 23
  • 98
  • 159
  • I have an installation procedure to a project of mine and i just use simple sessions, since they're temporary and they're user specific. You of course can do the same with a class. –  May 26 '14 at 10:13
  • @vlzvl in my case there is not user interaction once the process is initiated.So successive method calls dependent on each other. – sakhunzai May 26 '14 at 10:33
  • For simple functions I'd use array_reduce, but if you have classes and everything you might want to look at the 'chain of responsiblity' pattern. – rethab May 26 '14 at 12:46
  • @rethab , array_reduce is good for map-reduce functionality in my case I am not reducing the origional input data, instead I apply filter e.g some sort of validations such that if first validation fails we dont need to look up to next validation in stack – sakhunzai May 26 '14 at 12:55
  • 1
    also have a look at [Finite-state_machine](http://en.wikipedia.org/wiki/Finite-state_machine) – bitWorking May 26 '14 at 13:00
  • MapReduce was inspired by these functions, but they work in other scenarios as well. array_reduce(array('validator1', ...), function ($acc, $fun) { return $acc == false ? false : $fun(); }, false) – rethab May 26 '14 at 16:17
  • @rethab, I think I found the answer http://stackoverflow.com/questions/4274031/php-state-machine-framework and the pattern I was search for it was http://sourcemaking.com/design_patterns/state – sakhunzai May 27 '14 at 04:52

1 Answers1

1

I'd take a look at chain of responsibility pattern.

each handler in the chain does it's thing on the input (validate/transform) and either calls the next handler, or stops execution if fails.

Ami
  • 1,110
  • 1
  • 13
  • 26
  • #Ami thanks it seem state pattern :http://sourcemaking.com/design_patterns/state, is more reasonable choice here.How Chain of responsibility pattern seem more flexible in design such that any states in any order can be chained to-gather. – sakhunzai May 30 '14 at 09:58