Wzorzec projektowy Prototype jest konstrukcyjnym wzorcem projektowym, którego zadaniem jest unikanie powstawania nowych instancji danego obiektu. Prototype tworzy klony podanego obiektu zamiast tworzenia nowych. Jest to potrzebne gdy musimy uniknąć tworzenia w aplikacji klienckiej podklas obiektu budującego (tak jak to jest w przypadku Abstract Factory). Drugim przypadkiem kiedy Prototype jest wykorzystywany jest sytuacja, gdy potrzebujemy obiektu, którego utworzenie nowej instancji jest zbyt kosztowne.
Aby zaimplementować ten wzorzec deklaruje się klasę bazową abstrakcyjną która implementuje interfejs Cloneable. Klient który chce powołać nowy obiekt wywołuje metode clone() na prototypie, albo metodę fabrykującą z parametrem określającym pożądaną docelową klasę pochodną.
Implementacja wzorca może wyglądać następująco:
Tworzymy produkt abstrakcyjny i jego implementację:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public abstract class Product implements Cloneable { private String name; @Override protected Object clone() { try { Product copy = (Product) super.clone(); return copy; } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class ConcreteProduct extends Product { } |
i budujemy klienta, który korzysta z wzorca Prototype:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class Klient { private Product product; public Klient(Product product) { this.product = product; } public Product makeProduct() { return (Product)product.clone(); } public static void main(String[] args) { Product temp = null; Product p = new ConcreteProduct(); p.setName("Przykładowy Produkt"); //inne działania definiujące prototyp Klient klient = new Klient(p); System.out.print(p.hashCode()); System.out.print(" "); System.out.println(p.getName()); for (int i = 0; i < 10; i++) { temp = klient.makeProduct(); System.out.print(i + ": "+temp.hashCode()); System.out.print(" "); System.out.println(temp.getName()); } } } |
Diagram wzorca: