HTML

Friss topikok

Linkblog

Design patterns 3. Chain of Responsibility

2012.05.08. 22:57 6aIL6ec

A Chain of Responsibility egy Behavioral pattern, az objektumok viselkedési módját határozza meg.

Mikor alkalmazzuk: konkrét példával élve - egy adott inputot több szűrőn is végig kell vinni úgy, hogy a szűrőket könnyen ki és be lehessen építeni a szűrőrendszerbe.
 

Legyen az inputunk egy

class InputObject{ ... }osztály egy példánya, amin többszintű szűrést szeretnénk végezni. Ekkor szükség van egy

/**
* @author  6aIL6ec     
*     
* A Filterek alaposztálya
*     
*/
abstract class BaseFilter{   
    public abstract function handleInput($inputObject);
}
alaposztályra, amely nem tartalmaz logikát, csak definiálja a metódust, amelyet a konkrét implementációkban megvalósíthatjuk:

/**
* @author  6aIL6ec     
*     
* A BaseFilter egyik implementációja
*     
*/
class Filter1 extends BaseFilter{   
    public function handleInput($inputObject){
       [...]
    }
}

/**
* @author  6aIL6ec     
*     
* A BaseFilter másik implementációja
*     
*/
class Filter2 extends BaseFilter{   
    public function handleInput($inputObject){
       [...]
    }
             [...]

/**
* @author  6aIL6ec     
*     
* A BaseFilter N.k implementációja
*     
*/
class FilterN extends BaseFilter{   
    public function handleInput($inputObject){
       [...]
    }
}
A célunk az, hogy ezeket egyenként "úszitsuk" rá az inputunkra, akár tetszőleges, akár előre meghatározott sorrendben.
Több olyan ChOR implementációval is találkoztam, ahol a konkrét implementációk nem voltak kiemelve, hanem egymásba voltak ágyazva, így valóban láncot képeztek - ebben az esetben a Filter1 tartalmazná a Filter2-t, Filter2 a Filter3-t és így tovább.
Nem sok értelmét látom ennek a megoldásnak, mivel külön eljárás szükséges ahhoz, hogy a beágyazásokat kezeljen a rendszer - mi van akkor, ha az egyik szűrőt ki kell venni vagy más sorrendben kell elvégezni a szűrést?
Véleményem szerint egy külső, könnyen kezelhető hivatkozáslista merőben megkönnyíti a ChOR használatát.


Szükség van egy listára, amely tartalmazza a felhasználni kívánt Filter implementációkat, ebben az esetben a listát egy újabb osztály fogja tartalmazni:

/**
* @author  6aIL6ec     
*     
* A Filterek listáját tartalmazó osztály
*     
*/
class FilterRegistry{
   
    private static $filterArray = array(
            "Filter1",
            "Filter2",
            "FilterN"

        );
   
    public function getFilterList(){
         return self::$filterArray;
    }
}

Végül kell egy olyan osztály is, amely elvégzi a példányosítást és a metódushívást:
 
/**
* @author  6aIL6ec     
*     
* A Filterek hívását végző osztály
*     
*/
class FilterCaller{
    
     public static function filterInputObject($inputObject){
          $filterList = FilterRegistry::getFilterList();
          foreach($filterList as $filter){
               /*
               * Factory Method design pattern-ről
               * bővebben
itt
               */

               $concreteFilter = new $filter();
               $concreteFilter->handleInput($inputObject);
          }
     }
}

Ennélfogva a
FilterCaller::filterInputObject($inputObject);
meghívása minden BaseFilter implementáción végigrángatja az inputunkat, méghozzá abban a sorrendben, amelyben a FilterRegistry-ben a Filtereket definiáltuk.

 

 



Szólj hozzá!

Címkék: design php factory method chain pattern chain of responsibility

A bejegyzés trackback címe:

https://elephpantfan.blog.hu/api/trackback/id/tr604497265

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása