#590 Add explanation for Prototype
This commit is contained in:
		
							
								
								
									
										1
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -464,6 +464,7 @@ | ||||
|                         <param>factory-method</param> | ||||
|                         <param>abstract-factory</param> | ||||
|                         <param>builder</param> | ||||
|                         <param>prototype</param> | ||||
|                     </skipForProjects> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|   | ||||
| @@ -15,14 +15,57 @@ tags: | ||||
| Specify the kinds of objects to create using a prototypical | ||||
| instance, and create new objects by copying this prototype. | ||||
|  | ||||
|  | ||||
| ## Explanation | ||||
| Real world example | ||||
|  | ||||
| > Remember Dolly? The sheep that was cloned! Lets not get into the details but the key point here is that it is all about cloning. | ||||
|  | ||||
| In plain words | ||||
|  | ||||
| > Create object based on an existing object through cloning. | ||||
|  | ||||
| Wikipedia says | ||||
|  | ||||
| > The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. | ||||
|  | ||||
| In short, it allows you to create a copy of an existing object and modify it to your needs, instead of going through the trouble of creating an object from scratch and setting it up. | ||||
|  | ||||
| **Programmatic Example** | ||||
|  | ||||
| In Java, it can be easily done by implementing `Cloneable` and overriding `clone` from `Object` | ||||
|  | ||||
| ``` | ||||
| class Sheep implements Cloneable { | ||||
|   privage String name; | ||||
|   public Sheep(String name) { this.name = name; } | ||||
|   public void setName(String name) { this.name = name; } | ||||
|   public String getName() { return name; } | ||||
|   @Override | ||||
|   public Sheep clone() throws CloneNotSupportedException { | ||||
|     return new Sheep(name); | ||||
|   } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| Then it can be cloned like below | ||||
|  | ||||
| ``` | ||||
| Sheep original = new Sheep("Jolly"); | ||||
| System.out.println(original.getName()); // Jolly | ||||
|  | ||||
| // Clone and modify what is required | ||||
| Sheep cloned = original.clone(); | ||||
| cloned.setName("Dolly"); | ||||
| System.out.println(cloned.getName()); // Dolly | ||||
| ``` | ||||
|  | ||||
| ## Applicability | ||||
| Use the Prototype pattern when a system should be independent of how its products are created, composed and represented; and | ||||
|  | ||||
| * when the classes to instantiate are specified at run-time, for example, by dynamic loading; or | ||||
| * to avoid building a class hierarchy of factories that parallels the class hierarchy of products; or | ||||
| * when the classes to instantiate are specified at run-time, for example, by dynamic loading | ||||
| * to avoid building a class hierarchy of factories that parallels the class hierarchy of products | ||||
| * when instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state | ||||
| * when object creation is expensive compared to cloning | ||||
|  | ||||
| ## Real world examples | ||||
|  | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 37 KiB | 
| @@ -1,182 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"  | ||||
|   realizations="true" associations="true" dependencies="false" nesting-relationships="true">   | ||||
|   <class id="1" language="java" name="com.iluwatar.prototype.ElfMage" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/ElfMage.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="142" width="132" x="788" y="192"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="2" language="java" name="com.iluwatar.prototype.OrcMage" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/OrcMage.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="142" width="140" x="960" y="192"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="3" language="java" name="com.iluwatar.prototype.Mage" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/Mage.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="105" width="132" x="665" y="28"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="4" language="java" name="com.iluwatar.prototype.Prototype" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/Prototype.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="105" width="132" x="493" y="-154"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="5" language="java" name="com.iluwatar.prototype.Beast" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/Beast.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="105" width="132" x="321" y="28"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="6" language="java" name="com.iluwatar.prototype.ElfWarlord" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/ElfWarlord.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="142" width="154" x="388" y="192"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="7" language="java" name="com.iluwatar.prototype.Warlord" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/Warlord.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="105" width="132" x="493" y="28"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="8" language="java" name="com.iluwatar.prototype.ElfBeast" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/ElfBeast.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="142" width="132" x="32" y="192"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="9" language="java" name="com.iluwatar.prototype.OrcWarlord" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/OrcWarlord.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="142" width="166" x="582" y="192"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="10" language="java" name="com.iluwatar.prototype.HeroFactoryImpl" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/HeroFactoryImpl.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="142" width="248" x="665" y="-154"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <class id="11" language="java" name="com.iluwatar.prototype.OrcBeast" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/OrcBeast.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="142" width="144" x="204" y="192"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </class>   | ||||
|   <interface id="12" language="java" name="com.iluwatar.prototype.HeroFactory" project="prototype"  | ||||
|     file="/prototype/src/main/java/com/iluwatar/prototype/HeroFactory.java" binary="false" corner="BOTTOM_RIGHT">     | ||||
|     <position height="124" width="164" x="837" y="28"/>     | ||||
|     <display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|       sort-features="false" accessors="true" visibility="true">       | ||||
|       <attributes public="true" package="true" protected="true" private="true" static="true"/>       | ||||
|       <operations public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     </display>   | ||||
|   </interface>   | ||||
|   <generalization id="13">     | ||||
|     <end type="SOURCE" refId="8"/>     | ||||
|     <end type="TARGET" refId="5"/>   | ||||
|   </generalization>   | ||||
|   <generalization id="14">     | ||||
|     <end type="SOURCE" refId="6"/>     | ||||
|     <end type="TARGET" refId="7"/>   | ||||
|   </generalization>   | ||||
|   <generalization id="15">     | ||||
|     <end type="SOURCE" refId="7"/>     | ||||
|     <end type="TARGET" refId="4"/>   | ||||
|   </generalization>   | ||||
|   <association id="16">     | ||||
|     <end type="SOURCE" refId="10" navigable="false">       | ||||
|       <attribute id="17" name="beast"/>       | ||||
|       <multiplicity id="18" minimum="0" maximum="1"/>     | ||||
|     </end>     | ||||
|     <end type="TARGET" refId="5" navigable="true"/>     | ||||
|     <display labels="true" multiplicity="true"/>   | ||||
|   </association>   | ||||
|   <realization id="19">     | ||||
|     <end type="SOURCE" refId="10"/>     | ||||
|     <end type="TARGET" refId="12"/>   | ||||
|   </realization>   | ||||
|   <generalization id="20">     | ||||
|     <end type="SOURCE" refId="9"/>     | ||||
|     <end type="TARGET" refId="7"/>   | ||||
|   </generalization>   | ||||
|   <generalization id="21">     | ||||
|     <end type="SOURCE" refId="1"/>     | ||||
|     <end type="TARGET" refId="3"/>   | ||||
|   </generalization>   | ||||
|   <generalization id="22">     | ||||
|     <end type="SOURCE" refId="5"/>     | ||||
|     <end type="TARGET" refId="4"/>   | ||||
|   </generalization>   | ||||
|   <association id="23">     | ||||
|     <end type="SOURCE" refId="10" navigable="false">       | ||||
|       <attribute id="24" name="mage"/>       | ||||
|       <multiplicity id="25" minimum="0" maximum="1"/>     | ||||
|     </end>     | ||||
|     <end type="TARGET" refId="3" navigable="true"/>     | ||||
|     <display labels="true" multiplicity="true"/>   | ||||
|   </association>   | ||||
|   <association id="26">     | ||||
|     <end type="SOURCE" refId="10" navigable="false">       | ||||
|       <attribute id="27" name="warlord"/>       | ||||
|       <multiplicity id="28" minimum="0" maximum="1"/>     | ||||
|     </end>     | ||||
|     <end type="TARGET" refId="7" navigable="true"/>     | ||||
|     <display labels="true" multiplicity="true"/>   | ||||
|   </association>   | ||||
|   <generalization id="29">     | ||||
|     <end type="SOURCE" refId="2"/>     | ||||
|     <end type="TARGET" refId="3"/>   | ||||
|   </generalization>   | ||||
|   <generalization id="30">     | ||||
|     <end type="SOURCE" refId="3"/>     | ||||
|     <end type="TARGET" refId="4"/>   | ||||
|   </generalization>   | ||||
|   <generalization id="31">     | ||||
|     <end type="SOURCE" refId="11"/>     | ||||
|     <end type="TARGET" refId="5"/>   | ||||
|   </generalization>   | ||||
|   <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"  | ||||
|     sort-features="false" accessors="true" visibility="true">     | ||||
|     <attributes public="true" package="true" protected="true" private="true" static="true"/>     | ||||
|     <operations public="true" package="true" protected="true" private="true" static="true"/>   | ||||
|   </classifier-display>   | ||||
|   <association-display labels="true" multiplicity="true"/> | ||||
| </class-diagram> | ||||
| @@ -1,82 +0,0 @@ | ||||
| @startuml | ||||
| package com.iluwatar.prototype { | ||||
|   class App { | ||||
|     - LOGGER : Logger {static} | ||||
|     + App() | ||||
|     + main(args : String[]) {static} | ||||
|   } | ||||
|   abstract class Beast { | ||||
|     + Beast() | ||||
|     + clone() : Beast {abstract} | ||||
|   } | ||||
|   class ElfBeast { | ||||
|     + ElfBeast() | ||||
|     + clone() : Beast | ||||
|     + toString() : String | ||||
|   } | ||||
|   class ElfMage { | ||||
|     + ElfMage() | ||||
|     + clone() : Mage | ||||
|     + toString() : String | ||||
|   } | ||||
|   class ElfWarlord { | ||||
|     + ElfWarlord() | ||||
|     + clone() : Warlord | ||||
|     + toString() : String | ||||
|   } | ||||
|   interface HeroFactory { | ||||
|     + createBeast() : Beast {abstract} | ||||
|     + createMage() : Mage {abstract} | ||||
|     + createWarlord() : Warlord {abstract} | ||||
|   } | ||||
|   class HeroFactoryImpl { | ||||
|     - beast : Beast | ||||
|     - mage : Mage | ||||
|     - warlord : Warlord | ||||
|     + HeroFactoryImpl(mage : Mage, warlord : Warlord, beast : Beast) | ||||
|     + createBeast() : Beast | ||||
|     + createMage() : Mage | ||||
|     + createWarlord() : Warlord | ||||
|   } | ||||
|   abstract class Mage { | ||||
|     + Mage() | ||||
|     + clone() : Mage {abstract} | ||||
|   } | ||||
|   class OrcBeast { | ||||
|     + OrcBeast() | ||||
|     + clone() : Beast | ||||
|     + toString() : String | ||||
|   } | ||||
|   class OrcMage { | ||||
|     + OrcMage() | ||||
|     + clone() : Mage | ||||
|     + toString() : String | ||||
|   } | ||||
|   class OrcWarlord { | ||||
|     + OrcWarlord() | ||||
|     + clone() : Warlord | ||||
|     + toString() : String | ||||
|   } | ||||
|   abstract class Prototype { | ||||
|     + Prototype() | ||||
|     + clone() : Object {abstract} | ||||
|   } | ||||
|   abstract class Warlord { | ||||
|     + Warlord() | ||||
|     + clone() : Warlord {abstract} | ||||
|   } | ||||
| } | ||||
| HeroFactoryImpl -->  "-beast" Beast | ||||
| HeroFactoryImpl -->  "-warlord" Warlord | ||||
| HeroFactoryImpl -->  "-mage" Mage | ||||
| Beast --|> Prototype  | ||||
| ElfBeast --|> Beast  | ||||
| ElfMage --|> Mage  | ||||
| ElfWarlord --|> Warlord  | ||||
| HeroFactoryImpl ..|> HeroFactory  | ||||
| Mage --|> Prototype  | ||||
| OrcBeast --|> Beast  | ||||
| OrcMage --|> Mage  | ||||
| OrcWarlord --|> Warlord  | ||||
| Warlord --|> Prototype  | ||||
| @enduml | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 95 KiB | 
		Reference in New Issue
	
	Block a user