Wzorzec projektowy Proxy (pośrednik)

Dzisiejszy post jest o jednym z moich ulubionych wzorców projektowych – Proxy.

Proxy jest przydatnym wzorcem projektowym, który umożliwia dodanie pewnych dodatkowych zachowań do jakiegoś obiektu w sposób transparentny.

Jakie ma zastosowania ?

  • Logowanie użycia metod obiektu
  • Sprawdzanie uprawnień do użycia metod obiektu
  • Lazy loading

Oczywiście powyższe zastosowania są tylko przykładami. Można wymyślić wiele innych fajnych rzeczy przy użyciu Proxy.

Przykład:

Naszym przykładem użycia będzie sprawdzenie uprawnień do użycia metod jakiegoś obiektu.

Składniki:

Jedna fabryka obiektów (nie jest koniecznie potrzebna):

class CFactory {
    protected $_acl = null;
    public function __construct(IAcl $acl){
        $this->_acl = $acl;
    }    

    public function factory($className){
        $oObject = new $className;
        $oProxy = new CProxy($oObject, $this->_acl);
        return $oProxy;
    }
}

Jedna klasa obiektów która robi coś ciekawego:

class CCiekawyObiekt {
    public function robCosCiekawego(){
        echo 'robie cos ciekawego, serio ;P';
    }
}

Jedna klasa Access Control List

interface IAcl {
    public function isAllowed($className, $methodName);
}

Jedna klasa proxy:

class CProxy {
    protected $_object = null;
    protected $_acl = null;
    protected $_class = null;

    public function __construct($object,IAcl $acl){
        $this->_object = $object;
        $this->_acl = $acl;
        $this->_class = get_class($object);
    }
    public function __call($name,$arguments){
        if($this->_acl->isAllowed($this->_class,$name)){
            return call_user_func_array(array($this->_object,$name),$arguments)
        }
        throw new InsufficentPrivilegesException();
    }
}

Użycie:

//Fabryka implementująca interfejs IFactory
$oFactory = new CFactory;
//zwraca nam proxy ktory wszystkie wywolania przekazuje do docelowego obiektu
$oCiekawy = $oFactory->factory('CCiekawyObiekt');

// wywali InsufficentPrivilegesException jeżeli nie mamy uprawnień do danej metody
$oCiekawy->robCosCiekawego();
  1. […] Btw. podobny przykład, jednak bez użycia kontenera IoC zaprezentowałem we wpisie poświęconemu wzorcowi Proxy. Pełny kod przykładu można ściągnąć […]

Leave a Reply

Informuj mnie o odpowiedziach poprzez e-mail. Możesz również subskrybować wpis bez zostawiania komentarza.