Intercepting filter to wzorzec projektowy, który znajduje zastosowanie w aplikacjach wymagających wielokrotnego wykonywania tych samych czynności. Za przykład może posłużyć sytuacja, w której skrypt na samym początku musi uzyskać połączenie z bazą danych, a na końcu je zamknąć. Innymi często powtarzającymi się działaniami są operacje związane z autoryzacją, transakcjami, logowaniem zdarzeń, itd. Sposób implementacji intercepting filter zależy w dużej mierze od naszych indywidualnych wymagań. Nie pozostaje nam więc nic innego, jak przejść do praktyki.

przykład pierwszy

Poniżej prezentuję prostą klasę ImplementAction, która korzysta z omawianego przeze mnie wzorca (klasa abstrakcyjna Action). Popatrzmy na jej kod:

abstract class Action {

	abstract public function BeforeAction();

	abstract public function AfterAction();

	public function __construct () {
		$this->BeforeAction ();
	}

	public function __destruct() {
		$this->AfterAction ();
	}

}

class ImplementAction extends Action {

	public function BeforeAction() {
		echo __METHOD__;
	}

	public function AfterAction() {
		echo __METHOD__;
	}

	public function A () {
		echo __METHOD__;
	}

	public function B () {
		echo __METHOD__;
	}

}

$obj = new ImplementAction();
$obj->A();
$obj->b();

Na wyjściu otrzymamy:

ImplementAction::BeforeAction
ImplementAction::A
ImplementAction::B
ImplementAction::AfterAction

Jak widać przy tworzeniu obiektu wywoływana jest metoda BeforeAction(), a w destruktorze AfterAction(). Oczywiście powyższy kod ma swoje wady i zalety. Zależą one jednak od wymogów tworzonego oprogramowania, zatem coś co dla jednych może być dużym plusem, dla innych staje się rozwiązaniem nie do przyjęcia. Najwyższy czas na przyjrzenie się bardziej zaawansowanemu modelowi użycia Intercepting Filter, dzięki któremu zwiększymy jego elastyczność i możliwości.

przykład drugi

// iterfejs dla filtrow
interface InterceptingFilter {

	public function doBefore();
	public function doAfter();

}

// klasa filtra
class FirstFilter implements InterceptingFilter {

	public function doBefore() {

		echo __METHOD__;

	}

	public function doAfter() {

		echo __METHOD__;

	}

}
// klasa filtra
class SecondFilter implements InterceptingFilter {

	public function doBefore() {

		echo __METHOD__;

	}

	public function doAfter() {

		echo __METHOD__;

	}

}
// klasa filtra
class AnotherFilter implements InterceptingFilter {

	public function doBefore() {

		echo __METHOD__;

	}

	public function doAfter() {

		echo __METHOD__;

	}

}
// abstrakcyjna klasa zajmujaca sie odpowiednim wywolywaniem
// filtrow
abstract class UseInterceptingFilter {

	private $filters = array();

	private function doBeforeActions() {

		foreach ($this->filters as $do)
			$do->doBefore();

	}

	private function doAfterActions() {

		foreach ($this->filters as $do)
			$do->doAfter();

	}

	public function __construct (array $filters = array()) {

		$this->filters = $filters;

		$this->doBeforeActions();

	}

	public function __destruct () {
		$this->doAfterActions();
	}

}

// klasa korzystajaca z filtrow
class Example extends UseInterceptingFilter {

	public function A() {

		echo __METHOD__;

	}

	public function B() {

		echo __METHOD__;

	}

}

// tworzymy przykladowe filtry
$filter1 = new FirstFilter();
$filter2 = new SecondFilter();
$filter3 = new AnotherFilter();

// filtry przekazywane w konstruktorze
$obj = new Example(array($filter1,$filter2,$filter3));
$obj->A();
$obj->B();

Na wyjściu dostajemy:

FirstFilter::doBefore
SecondFilter::doBefore
AnotherFilter::doBefore
Example::A
Example::B
FirstFilter::doAfter
SecondFilter::doAfter
AnotherFilter::doAfter

Aby dodać nowy filtr wystarczy napisać klasę implementującą interfejs InterceptingFilter. Natomiast klasy z nich korzystające dziedziczą po UseInterceptingFilter , a ów filtry są przekazywane jako tablica w konstruktorze.

Zachęcam więc do własnych eksperymentów, które doprowadzą do rozwiązań w pełni dostosowanych do stawianych przez Was wymagań.

Pozostaw Odpowiedź