diff --git a/pom.xml b/pom.xml index df01809f4..4976c14d5 100644 --- a/pom.xml +++ b/pom.xml @@ -464,6 +464,7 @@ factory-method abstract-factory builder + prototype diff --git a/prototype/README.md b/prototype/README.md index fe9e17917..e6d5d8b8b 100644 --- a/prototype/README.md +++ b/prototype/README.md @@ -15,14 +15,57 @@ tags: Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. -![alt text](./etc/prototype_1.png "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 diff --git a/prototype/etc/prototype.png b/prototype/etc/prototype.png deleted file mode 100644 index 073b472e5..000000000 Binary files a/prototype/etc/prototype.png and /dev/null differ diff --git a/prototype/etc/prototype.ucls b/prototype/etc/prototype.ucls deleted file mode 100644 index 6d19fdc23..000000000 --- a/prototype/etc/prototype.ucls +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/prototype/etc/prototype.urm.puml b/prototype/etc/prototype.urm.puml deleted file mode 100644 index 801679fb7..000000000 --- a/prototype/etc/prototype.urm.puml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/prototype/etc/prototype_1.png b/prototype/etc/prototype_1.png deleted file mode 100644 index 8b513c8d2..000000000 Binary files a/prototype/etc/prototype_1.png and /dev/null differ