#590 Add explanation for Prototype
This commit is contained in:
parent
f6c8bfbc39
commit
b639f3630e
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 |
Loading…
x
Reference in New Issue
Block a user