mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 10:58:42 +00:00
docs: update prototype
This commit is contained in:
+43
-39
@@ -3,24 +3,25 @@ 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
|
||||
|
||||
@@ -28,18 +29,11 @@ In plain words
|
||||
|
||||
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 {
|
||||
@@ -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)
|
||||
@@ -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();
|
||||
@@ -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(
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user