Skip to content

Commit

Permalink
docs: update prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
iluwatar committed May 18, 2024
1 parent a0abbf0 commit 57f7c39
Showing 1 changed file with 43 additions and 39 deletions.
82 changes: 43 additions & 39 deletions prototype/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,37 @@ title: Prototype
category: Creational
language: en
tag:
- Gang Of Four
- Instantiation
- Gang Of Four
- Instantiation
- Object composition
- Polymorphism
---

## Also known as

* Clone

## Intent

Specify the kinds of objects to create using a prototypical instance, and create new objects by
copying this prototype.
The Prototype pattern is used to specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.

## Explanation

First, it should be noted that the Prototype pattern is not used to gain performance benefits. It's only
used for creating new objects from prototype instances.

Real-world example

> Remember Dolly? The sheep that was cloned! Let's not get into the details but the key point here is
> that it is all about cloning.
> Remember Dolly? The sheep that was cloned! Let's not get into the details but the key point here is that it is all about cloning.
In plain words

> Create an 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.
> 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.
**Programmatic Example**

In Java, the prototype pattern is recommended to be implemented as follows. First, create an
interface with a method for cloning objects. In this example, `Prototype` interface accomplishes
this with its `copy` method.
In Java, the prototype pattern is recommended to be implemented as follows. First, create an interface with a method for cloning objects. In this example, `Prototype` interface accomplishes this with its `copy` method.

```java
public abstract class Prototype<T> implements Cloneable {
Expand All @@ -50,17 +44,13 @@ public abstract class Prototype<T> implements Cloneable {
}
```

Our example contains a hierarchy of different creatures. For example, let's look at `Beast` and
`OrcBeast` classes.
Our example contains a hierarchy of different creatures. For example, let's look at `Beast` and `OrcBeast` classes.

```java
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
public abstract class Beast extends Prototype<Beast> {

public Beast(Beast source) {
}

public Beast(Beast source) {}
}

@EqualsAndHashCode(callSuper = false)
Expand All @@ -78,19 +68,15 @@ public class OrcBeast extends Beast {
public String toString() {
return "Orcish wolf attacks with " + weapon;
}

}
```

We don't want to go into too many details, but the full example contains also base classes `Mage`
and `Warlord` and there are specialized implementations for those for elves in addition to orcs.
We don't want to go into too many details, but the full example contains also base classes `Mage` and `Warlord` and there are specialized implementations for those for elves in addition to orcs.

To take full advantage of the prototype pattern, we create `HeroFactory` and `HeroFactoryImpl`
classes to produce different kinds of creatures from prototypes.
To take full advantage of the prototype pattern, we create `HeroFactory` and `HeroFactoryImpl` classes to produce different kinds of creatures from prototypes.

```java
public interface HeroFactory {

Mage createMage();
Warlord createWarlord();
Beast createBeast();
Expand All @@ -117,8 +103,7 @@ public class HeroFactoryImpl implements HeroFactory {
}
```

Now, we are able to show the full prototype pattern in action producing new creatures by cloning
existing instances.
Now, we are able to show the full prototype pattern in action producing new creatures by cloning existing instances.

```java
var factory = new HeroFactoryImpl(
Expand Down Expand Up @@ -163,21 +148,40 @@ Orcish wolf attacks with laser

## Applicability

Use the Prototype pattern when a system should be independent of how its products are created,
composed, represented and

* 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 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.
* When the concrete classes to instantiate are unknown until runtime.

## Known uses

* [java.lang.Object#clone()](http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#clone%28%29)
* In Java, the `Object.clone()` method is a classic implementation of the Prototype pattern.
* GUI libraries often use prototypes for creating buttons, windows, and other widgets.
* In game development, creating multiple objects (like enemy characters) with similar attributes.

## Consequences

Benefits:

* Hides the complexities of instantiating new objects.
* Reduces the number of classes.
* Allows adding and removing objects at runtime.

Trade-offs:

* Requires implementing a cloning mechanism which might be complex.
* Deep cloning can be difficult to implement correctly, especially if the classes have complex object graphs with circular references.

## Related patterns

- [Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/): Both involve creating objects, but Prototype uses cloning of a prototype instance whereas Abstract Factory creates objects using factory methods.
- [Singleton](https://java-design-patterns.com/patterns/singleton/): Singleton can use a prototype for creating instances if it allows cloning of its single instance.
- [Composite](https://java-design-patterns.com/patterns/composite/): Prototypes are often used within composites to allow for dynamic creation of component trees.

## Credits

* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
* [Effective Java](https://amzn.to/4cGk2Jz)
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3yhh525)

0 comments on commit 57f7c39

Please sign in to comment.