Uzorak prototipa na Javi

1. Uvod

U ovom uputstvu naučit ćemo o jednom od obrazaca kreativnog dizajna - uzorku prototipa. U početku ćemo objasniti ovaj obrazac, a zatim ćemo ga nastaviti implementirati u Javi.

Također ćemo razgovarati o nekim njegovim prednostima i nedostacima.

2. Uzorak prototipa

Uzorak prototipa je općenito koristi se kada imamo instancu klase (prototipa) i željeli bismo stvoriti nove objekte samo kopiranjem prototipa.

Upotrijebimo analogiju da bismo bolje razumjeli ovaj obrazac.

U nekim igrama želimo drveće ili zgrade u pozadini. Možda shvatimo da ne moramo stvarati nova stabla ili zgrade i prikazivati ​​ih na ekranu svaki put kad se lik pomakne.

Dakle, prvo stvorimo primjerak stabla. Tada možemo stvoriti onoliko stabala koliko želimo od ove instance (prototipa) i ažurirati njihove položaje. Također možemo odlučiti promijeniti boju drveća za novu razinu u igri.

Uzorak prototipa prilično je sličan. Umjesto stvaranja novih predmeta, samo moramo klonirati prototipnu instancu.

3. UML dijagram

Na dijagramu vidimo da klijent govori prototipu da se klonira i stvori objekt. Prototip je sučelje i deklarira metodu za samo kloniranje. ConcretePrototype1 i ConcretePrototype2 provesti operaciju kloniranja.

4. Provedba

Jedan od načina na koji možemo implementirati ovaj obrazac u Javi je upotreba klon() metoda. Da bismo to učinili, primijenili bismo Klonirajući sučelje.

Kada pokušavamo klonirati, trebali bismo se odlučiti između izrade plitke ili duboke kopije. Na kraju se sve svodi na zahtjeve.

Na primjer, ako klasa sadrži samo primitivna i nepromjenjiva polja, možemo koristiti plitku kopiju.

Ako sadrži reference na promjenjiva polja, trebali bismo napraviti dubinsku kopiju. Mogli bismo to učiniti s konstruktori kopija ili serializacija i deserializacija.

Uzmimo primjer koji smo ranije spomenuli i nastavimo vidjeti kako primijeniti uzorak prototipa bez upotrebe Klonirajući sučelje. Da bismo to učinili, kreirajmo sažetak razred nazvan Drvo s an sažetak metoda 'kopirati'.

javni sažetak klase Tree {// ... public abstract Tree copy (); }

Sad recimo da imamo dvije različite implementacije Drvo pozvao PlasticTree i Bor:

javna klasa PlasticTree proširuje Tree {// ... @Override public Tree copy () {PlasticTree plasticTreeClone = new PlasticTree (this.getMass (), this.getHeight ()); plasticTreeClone.setPosition (this.getPosition ()); vratiti plasticTreeClone; }}
javna klasa PineTree proširuje Tree {// ... @Override public Tree copy () {PineTree pineTreeClone = new PineTree (this.getMass (), this.getHeight ()); pineTreeClone.setPosition (this.getPosition ()); povratak pineTreeClone; }}

Dakle, ovdje vidimo da se razredi koji se protežu Drvo i provesti kopirati metoda može djelovati kao prototipi za stvaranje njihove kopije.

Uzorak prototipa također nam omogućuje stvaranje kopija objekata bez ovisno o konkretnim klasama. Recimo da imamo popis stabala i željeli bismo ih stvoriti. Zbog polimorfizma možemo lako stvoriti više kopija bez poznavanja vrsta drveća.

5. Ispitivanje

Ajmo sada testirati:

javna klasa TreePrototypesUnitTest {@Test javna praznina givenAPlasticTreePrototypeWhenClonedThenCreateA_Clone () {// ... PlasticTree plasticTree = novo PlasticTree (masa, visina); plasticTree.setPosition (položaj); PlasticTree anotherPlasticTree = (PlasticTree) plasticTree.copy (); anotherPlasticTree.setPosition (otherPosition); assertEquals (position, plasticTree.getPosition ()); assertEquals (otherPosition, anotherPlasticTree.getPosition ()); }}

Vidimo da je stablo klonirano iz prototipa i imamo dvije različite instance PlasticTree. Upravo smo ažurirali položaj u klonu i zadržali ostale vrijednosti.

Sada klonirajmo popis stabala:

@Test javna praznina givenA_ListOfTreesWhenClonedThenCreateListOfClones () {// kreirajte instance stabala Popisa PlasticTree i PineTree = Arrays.asList (plasticTree, pineTree); Popis treeClones = trees.stream (). Map (Tree :: copy) .collect (toList ()); // ... assertEquals (visina, plasticTreeClone.getHeight ()); assertEquals (position, plasticTreeClone.getPosition ()); }

Primijetite da ovdje možemo napraviti duboku kopiju popisa, a da ne ovisimo o konkretnim implementacijama Drvo.

6. Prednosti i nedostaci

Ovaj obrazac je zgodan kada se naš novi objekt samo malo razlikuje od našeg postojećeg. U nekim slučajevima instance mogu imati samo nekoliko kombinacija stanja u klasi. Dakle, umjesto stvaranja novih instanci, možemo prethodno stvoriti instance s odgovarajućim stanjem, a zatim ih klonirati kad god želimo.

Ponekad bismo mogli susresti podrazrede koji se razlikuju samo po svom stanju. Te potklase možemo eliminirati stvaranjem prototipova s ​​početnim stanjem, a zatim ih kloniranjem.

Uzorak prototipa, baš kao i svaki drugi obrazac dizajna, treba koristiti samo kada je to prikladno. Budući da kloniramo objekte, proces bi mogao postati složen kad postoji mnogo klasa, što bi rezultiralo neredom. Uz to, teško je klonirati klase koje imaju kružne reference.

7. Zaključak

U ovom uputstvu naučili smo ključne koncepte uzorka Prototype i vidjeli kako ga implementirati u Javi. Također smo razgovarali o nekim prednostima i nedostacima.

Kao i obično, izvorni kod za ovaj članak dostupan je na Githubu.