Prototyp (ang. Prototype) (wzorzec kreacyjny) ma za zadanie utworzyć kopię macierzystego obiektu zwanego prototypem. Zamiast tworzyć obiekt od nowa używa on istniejącą instancje do wygenerowania jej kopii, która jest zupełnie nowym obiektem, ale o tych samych właściwościach co prototyp. Modyfikacja kopii nie wpływa zatem w żaden sposób na obiekt macierzysty. Użycie wzorca Prototyp uniezależnia system od znajomości sposobu tworzenia obiektów, a także może pozytywnie wpływać na jego wydajność. Wzorzec ten jest standardowym elementem w wielu językach programowania.
Ograniczenia
Kopiowanie skomplikowanych obiektów z wieloma referencjami do innych obiektów może być utrudnione. W takiej sytuacji wiele klas, których instancje zawierają się w klasie obiektu macierzystego muszą implementować metodę klonowania copy.
Użycie
Prototyp stosowany jest tam, gdzie zachodzi potrzeba tworzenia dużej ilości podobnych lub tych samych obiektów, a ich kopiowanie jest wydajniejsze niż tworzenie. Może zostać także wykorzystany wraz z innymi wzorcami kreacyjnymi jak np.: Fabryka abstrakcyjna czy też w procesach przywracania/przechowywania stanu systemu.
Implementacja
Klasy dla których instancje mogą być klonowane implementują metodę copy w której tworzona i zwracana jest kopia bieżącego obiektu na podstawie kopi wszystkich pól obiektu. Zadanie to może zostać oddelegowane także do konstruktora kopiującego. Należy mieć na uwadzę, aby wszystkie klasy (których instancje zawierają się w klasie klonowanej) także implementowały metodę copy lub posiadały konstruktor kopiujący. W przeciwnym wypadku w klasie macierzystej należy rekurencyjnie pobrać wszystkie wartości prymitywne.
Poniższy listing przedstawia implementacja wzorca Prototyp dla klasy Prototype1 składającej się z prymitów - płytka kopia (shallow copy) oraz dla klasy Prototype2 składającej się z obiektów złożonych - głęboka kopia (deep copy).
Na podstawie istniejących obiektów (prototypów) klient generuje ich kopie. Następnie na całej kolekcji klonów wykonuje operacje.
Przykład
Aplikacja MathFigures pomaga w nauce geometrii i figur geometrycznych. Pozwala m.in. na rysowanie figur na tablicy, a następnie na wyliczenie dla nich pola powierzchni oraz obwodu. Rezultaty te mogą być porównane z wyliczeniami użytkownika dzięki czemu sprawdza on swoją wiedzę. Użytkownik tworząc nowe figury geometryczne często kopiuje już istniejące figury, a następnie modyfikuje je wg swojego uznania. Ze względu na wymóg klonowanie istniejących figur w projekcie został zaimplementowany wzorzec Prototyp.
Użytkownik tworzy w całości kilka figur i na podstawie ich kopii generuje kolejne oraz sprawdza swoje obliczenia z faktycznymi wynikami.
Biblioteki
Każda klasa implementująca interfejs Cloneable oraz rozszerzająca metodę copy klasy Object (ze standardowego pakietu Java) jest przykładem implementacji wzorca Prototyp jednakże ze względu na narzucane ograniczenia takie rozwiązanie jest odradzane. Jako alternatywe podaje się BeanUtils.cloneBean oraz SerializationUtils.clone.