Wzorzec Prototyp polega na klonowaniu instancji obiektów przy użyciu wbudowanej funkcji PHP – clone. Z tego wzorca korzystamy wtedy, kiedy potrzebujemy wielu identycznych obiektów o zbieżnych cechach i/lub właściwościach.

Schemat klonowania instancji obiektu:

Prosty przykład, to gra Pac-Man, którą każdy zna od zygoty. W grze występują złe „duszki”, które mają za zadanie dorwać Pac-Mana zanim ten wszama wszystkie „kropki” na planszy. Każdy z duszków ma identyczny kształt, funkcjonalności; „duszki” różnią się jedynie kolorem. Możemy więc zastosować wzorzec Prototyp do powielania postaci w grze.

pacman

PRZYKŁAD

W poniższym przykładzie zastosujemy wzorzec Prototyp do kopiowania różnych kształtów grafiki wektorowej SVG, np: koło (<circle></circle>) i prostokąt (<rect></rect>).

W tym celu tworzymy klasę abstrakcyjną Shape (Kształt), w której zapiszemy wspólne cechy dla wszystkich obrazów SVG, tj.: $svg_width, $svg_height – szerokość i wysokość płótna grafiki, $color – kolor figury oraz dwie metody abstrakcyjne: getShape() – zwracająca kształt i __clone() – metoda klonująca obiekt.

Poniższa klasa Circle rozszerza (extends) abstrakcyjną klasę Shape. Konstruktor __construct() przyjmuje i ustawia zmienne z klasy bazowej. Dodatkowo deklarujemy kolejne zmienne charakterystyczne dla obiektu Circle: $cx, $cy – współrzędne położenia figury na płótnie oraz $r – promień koła. Funkcja getShape() – wyświetla grafikę wektorową z zadanymi parametrami w znacznikach <svg … ><circle … /></svg>.

Analogicznie postępujemy z klasą Rectangle. Konstruktor przyjmuje oprócz domyślnych wartości, dodatkowe parametry: $width, $height – szerokość i wysokość prostokąta. Funkcja getShape() wyświetla prostokąt z podstawionymi wartościami w znacznikach <svg … ><rect … /></svg>:

Funkcja __clone() w obu przypadkach pozwoli na użycie klonowania instancji obiektu w taki oto sposób:

Ważne: podczas klonowania instancji obiektu konstruktor nie jest wywoływany / uruchamiany, a więc można jedynie korzystać z jego domyślnych wartości, ale nie można wprowadzać żadnych akcji, zdarzeń, np: echo.

Na koniec tworzymy klasę Client, w której użyjemy klas potomnych do prezentacji figur:

Jak widać poszczególne prototypy możemy modyfikować, albo tworzyć klony z innych klonów 🙂