Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype design pattern #27

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,28 @@
# DesignPatternsJava9
This repo consists Gang of Four Design patterns code on Java 9. Each branch in the repository has code of 1 design pattern. Switch repository to try out different design patterns.
# What is Prototype Design Pattern
The prototype pattern is a creational design pattern. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.

## Diagram
![Diagram](https://github.com/premaseem/DesignPatternsJava9/blob/prototype/diagrams/sequence%20diagram.png "Diagram")

### When to use Prototype Design Pattern
Prototype design pattern is used in scenarios where application needs to create a number of instances of a class, which has almost same state and when there is need to avoid creating objects using new keyword.

### Learn Design Patterns with Java by Aseem Jain
This repository contains working project code used in video Course by Packt Publication with title "Learn Design Patterns with Java " authored by "Aseem Jain".

### Course link:
https://www.packtpub.com/application-development/learn-design-patterns-java-9-video

### ![ http://in.linkedin.com/in/premaseem](https://github.com/premaseem/DesignPatternsJava9/blob/master/linkedin.png "http://in.linkedin.com/in/premaseem") Profile: http://in.linkedin.com/in/premaseem

### Authors blog on design patterns:
https://premaseem.wordpress.com/category/computers/design-patterns/

### Software Design pattern community face book page:
https://www.facebook.com/DesignPatternGuru/

### Note:
* This code base will work on Java 9 and above versions.
* `diagrams` folders carry UML diagrams.
* `pattern` folder has code of primary example.
* `patternBonus` folder has code of secondary or bonus example.
Binary file added diagrams/sequence diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions pattern/src/com/premaseem/Client.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
package com.premaseem;

import java.util.Scanner;

/*
@author: Aseem Jain
@title: Design Patterns with Java 9
@link: https://premaseem.wordpress.com/category/computers/design-patterns/
@copyright: 2018 Packt Publication
*/
public class Client {
public static void main (String[] args) {
System.out.println("Singleton cook example ");
public static void main (String[] args) throws CloneNotSupportedException {
System.out.println("### Statue creation by Prototype design pattern ");
System.out.println("How many Statue you want to create based on Mold / prototype ?");
Scanner scan = new Scanner(System.in);
int quantity = scan.nextInt();

StatueMold statueMold = new GaneshStatue();

for(int i=0;i<quantity;i++){
statueMold.createStatue();
}

}
}
20 changes: 20 additions & 0 deletions pattern/src/com/premaseem/GaneshStatue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.premaseem;

/*
@author: Aseem Jain
@title: Design Patterns with Java 9
@link: https://premaseem.wordpress.com/category/computers/design-patterns/
*/
public class GaneshStatue implements StatueMold, Cloneable{

@Override
public void createStatue () {
try {
Object obj = this.clone();
System.out.println("created statue object with id"+ obj.hashCode());

} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
10 changes: 10 additions & 0 deletions pattern/src/com/premaseem/StatueMold.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.premaseem;

/*
@author: Aseem Jain
@title: Design Patterns with Java 9
@link: https://premaseem.wordpress.com/category/computers/design-patterns/
*/
interface StatueMold {
void createStatue() throws CloneNotSupportedException;
}
13 changes: 0 additions & 13 deletions patternBonus/src/com/premaseem/Client.java

This file was deleted.

57 changes: 57 additions & 0 deletions patternBonus/src/com/premaseem/prototypePattern/Cell.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.premaseem.prototypePattern;

public abstract class Cell implements Cloneable {

public Cell(){
System.out.println("Constructor of Cell is called ... ");
}

String cellType;
public enum CellProtoTypes{
AMOEBA,BACTERIA,SINGLE_CELL_ORG
}

@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}

@Override
public String toString() {
// TODO Auto-generated method stub
return cellType + "with id " + hashCode();
}

public Object split() {
Object cloneCell = null;
try {
cloneCell = this.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return cloneCell;

}
}

class Amoeba extends Cell{
public Amoeba(){
cellType=" Amoeba ";
System.out.println("Constructor of Amoeba is called ... ");
}
}

class Bacteria extends Cell{
public Bacteria(){
cellType=" Bacteria ";
System.out.println("Constructor of Bacteria is called ... ");
}
}

class SingleCell extends Cell{
public SingleCell(){
cellType=" SingleCell ";
System.out.println("Constructor of SingleCell is called ... ");
}
}
50 changes: 50 additions & 0 deletions patternBonus/src/com/premaseem/prototypePattern/ClientFile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.premaseem.prototypePattern;

import java.util.Scanner;

import com.premaseem.prototypePattern.Cell.CellProtoTypes;

public class ClientFile {

public static void main(String[] args) {

System.out.println("Welcome to Prototype design patters Lab ");
Scanner scan = new Scanner(System.in);
SpecimenCache specimenLab = SpecimenCache.getInstance();
Cell subjectCell = null;

int repeatRunFlag = 1;
while (repeatRunFlag == 1) {
// TVInterface tv;
System.out.println("Which organizm you would like to culture / grow / multiply ? ");
System.out.println("press 1 for Single Cell Org");
System.out.println("press 2 for Amoeba ");
System.out.println("press 3 for Bacteria ");
int type = scan.nextInt();
if (type == 1) {
subjectCell = specimenLab.getCellProtoType(CellProtoTypes.SINGLE_CELL_ORG);
} else if (type == 2) {
subjectCell = specimenLab.getCellProtoType(CellProtoTypes.AMOEBA);
} else {
subjectCell = specimenLab.getCellProtoType(CellProtoTypes.BACTERIA);
}

System.out.println("Culture process has started ");
System.out.println(" Cells are spliting/cloning and growing ");

for (int i = 0; i < 10; i++) {
System.out.println(subjectCell.split());
System.out.println(" ........... ........ >>>> .... ");
}
System.out.println("=============================");

System.out.println("Press 1 to Repeat .... ");
repeatRunFlag = scan.nextInt();

}

System.out.println("\n $$$$$$$$$$$$$$$$$$$$ Thanks by Prem Aseem $$$$$$$$$$$$$$$$$$$$$$ \n ");
System.out.println("\n $$$$$$$$$$$$$$$$$$$$$ www.premaseem.com $$$$$$$$$$$$$$$$$$$$$$ \n ");

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Download the working example demo code in java from my GIT repository -https://github.com/premaseem/designPatterns/tree/4bb9beca7bab5b5e71d02b76e4f1ad48fce4aca6/ZipDownloadableProjects

Code Example
The Prototype pattern specifies the kind of objects to create using a prototypical instance. Cell is the abstract class with different subclasses like singleCell Organism, amoeba, bacteria etc. For each sub class a breeder object is created before hand and registered in SpecimenCache.java class. Now whenever client program wants to breed or culture a particular organism say amobea they will fetch it from cache and invoke split/clone method which will provide replicated organism with same state property. Download the example code and have fun.
Example of Prototype
When creating an object is time consuming and a costly affair and you already have a most similar object instance in hand, then you go for prototype pattern. Instead of going through a time consuming process to create a complex object, just copy the existing similar object and modify it according to your needs. Clone the existing instance in hand and then make the required update to the cloned instance so that you will get the object you need. Other way is, tweak the cloning method itself to suit your new object creation need.

Intent
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
Co-opt one instance of a class for use as a breeder of all future instances.
The new operator considered harmful.
Problem
Application "hard wires" the class of object to create in each "new" expression.
Discussion
Declare an abstract base class that specifies a pure virtual "clone" method, and, maintains a dictionary of all "cloneable" concrete derived classes. Any class that needs a "polymorphic constructor" capability: derives itself from the abstract base class, registers its prototypical instance, and implements the clone() operation.
The client then, instead of writing code that invokes the "new" operator on a hard-wired class name, calls a "clone" operation on the abstract base class, supplying a string or enumerated data type that designates the particular concrete derived class desired.

Check list
Add a clone() method to the existing "product" hierarchy.
Design a "registry" that maintains a cache of prototypical objects. The registry could be encapsulated in a new Factory class, or in the base class of the "product" hierarchy.
Design a factory method that: may (or may not) accept arguments, finds the correct prototype object, calls clone() on that object, and returns the result.
The client replaces all references to the new operator with calls to the factory method.
Rules of thumb
Prototype co-opts one instance of a class for use as a breeder of all future instances.
Prototypes are useful when object initialization is expensive, and you anticipate few variations on the initialization parameters. In this context, Prototype can avoid expensive "creation from scratch", and support cheap cloning of a pre-initialized prototype.
Factory Method: creation through inheritance. Protoype: creation through delegation.
Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Protoype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
Prototype doesn't require subclassing, but it does require an "initialize" operation. Factory Method requires subclassing, but doesn't require Initialize.
Designs that make heavy use of the Composite and Decorator patterns often can benefit from Prototype as well.


34 changes: 34 additions & 0 deletions patternBonus/src/com/premaseem/prototypePattern/SpecimenCache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.premaseem.prototypePattern;

import java.util.EnumMap;
import java.util.Map;

import com.premaseem.prototypePattern.Cell.CellProtoTypes;

public class SpecimenCache {

static SpecimenCache specimenCache=null;
private Map<CellProtoTypes,Cell> prototypeSamples = new EnumMap<CellProtoTypes,Cell>(CellProtoTypes.class);

static public SpecimenCache getInstance(){
if(specimenCache==null){
specimenCache = new SpecimenCache();
}
return specimenCache;
}

public SpecimenCache(){
loadSpecimenCache();
}

void loadSpecimenCache(){
prototypeSamples.put(CellProtoTypes.SINGLE_CELL_ORG, new SingleCell());
prototypeSamples.put(CellProtoTypes.BACTERIA, new Bacteria());
prototypeSamples.put(CellProtoTypes.AMOEBA, new Amoeba());
}

public Cell getCellProtoType(CellProtoTypes cell){
return prototypeSamples.get(cell);
}

}