Napisany gru-02-2008

strategy

Strategy jest wzorcem projektowym. Na początek jednak parę słów wyjaśnienia, dla osób które z wzorcami nie miały jeszcze do czynienia.

definicja

Wzorzec projektowy to pewnego rodzaju sprawdzony i uniwersalny sposób na rozwiązanie konkretnego problemu programisty z wykorzystaniem możliwości, jakie daje nam OOP. Stosowanie design patterns sprawia, że tworzony przez nas kod jest zdecydowanie bardziej czytelny i niezawodny. W razie rozbudowy funkcjonalności naszej aplikacji, proces ten przebiega znacznie szybciej. Wzorce projektowe pozwalają na lepszą komunikację programistów, w przypadku pracy grupowej. Spytacie dlaczego? Podam prosty przykład. Wyobraźcie sobie taką sytuację. Jesteście w pizzerii. Co jest szybsze podczas składania zamówienia: podawanie wszystkich składników danej pizzy czy wyłącznie jej nazwy? Wybierając drugie rozwiązanie zaoszczędzamy sporo czasu! Po co więc opisywać kolegom jak zaimplementujemy jakąś klasę (co i jak będzie działać), jak wystarczy podać im nazwę konkretnego wzorca! Również analiza kodu pisanego przez innego programistę z wykorzystaniem design patterns trwa znacznie krócej!
Wzorce dzielimy na:

  • konstrukcyjne (tworzenie obiektów klas)
  • strukturalne (łączenie obiektów klas)
  • behawioralne (zwiększanie elastyczności i przepływu danych w naszych aplikacji)

Strategy należy do ostatniej grupy.

poznajemy strategię

Wzorzec ten znajduje zastosowanie tam, gdzie daną czynność możemy wykonać na wiele sposobów. Zapis obrazka w rozmaitych formatach (GIF, PNG,itp.) czy też wyświetlania danych na wyjściu jako RSS,XML (i podobne) stanowią doskonałe przykłady.

Aby lepiej zrozumieć to co właśnie napisałem użyjemy strategy w praktyce. Załóżmy, że jesteśmy właścicielami sklepu internetowego. Korzystają z niego ludzie z całej Unii Europejskiej. Chcielibyśmy wprowadzić rabaty dla każdego zamówienia, w zależności od kraju z którego pochodzić będzie osoba zamawiająca. Na początku definiujemy sobie interfejs z prototypem funkcji, która będzie zwracać wysokość rabatu.

interface discountInterface {

	public function Discount ();

}

Kolejną rzeczą jest stworzenie klas implementujących powyższy interfejs. Każda klasa reprezentuje zniżkę w konkretnym kraju Unii.

class DiscountPL implements discountInterface {

	public function Discount () {

		return 10;

	}

}

class DiscountEN implements discountInterface {

	public function Discount () {

		return 20;

	}

}

class DiscountDE implements discountInterface {

	public function Discount () {

		return 15;

	}
}

class NoDiscount implements discountInterface {

	public function Discount () {

		return 0;

	}

}

Na koniec do klasy zamówienia dodaje możliwość nakładania upustów.

//mocno uproszczono aby dobrze zrozumiec wzorzec!
class Order {
		private $strategy;

		public function __construct () {

			$this->strategy = new NoDiscount ();

		}

		public function GetDiscount () {

			return $this->strategy->Discount();

		}

		public function SetDiscount (discountInterface $obj) {

			$this->strategy = $obj;

		}

}

Jak wygodne jest to rozwiązanie? Bardzo! Od teraz dodanie nowego kraju (z innym rabatem) nie wymaga od nas ingerencji w kod klasy Order! Wystarczy skorzystać z metody SetDiscount, zwanej fachowo setterem behawioralnym.

$new_order = new Order ();
echo $new_order->GetDiscount();

//ustawiamy znizke!
//behavior setter method
$new_order->SetDiscount(new DiscountEN());

echo $new_order->GetDiscount();

Czy to aby na pewno wzorzec strategy? Tak! Konkretna czynność “nakładanie rabatu” wykonywana jest na wiele różnych sposobów (w zależności od państwa Unii).

Mam nadzieję, że choć w małym stopniu zachęciłem Was do poznawania wzorców projektowych.

Tagi : , ,

Komentarze:

Napisz komentarz