Skip to content

Commit

Permalink
task: Explanations and grammar fixes for all the GoF patterns (#1791)
Browse files Browse the repository at this point in the history
* Grammatical fixes to command pattern

* Update bridge pattern readme

* Fixes to builder pattern grammar

* Update chain of responsibility

* Improvements to the composite example

* Fixes to headings

* Minor updates to decorator pattern

* Update facade

* Update factory example

* Update factory method

* Update flyweight

* Interpreter explanation

* Update iterator readme

* Add explanation for mediator pattern

* Grammatical fixes to memento

* Grammar fixes for observer

* Update explanation for the prototype pattern

* Proxy pattern grammar fixes

* Update singleton

* Grammar fixes to state pattern

* Grammar fixes for strategy

* Grammar fixes, template method

* Grammar fixes for visitor

* Fix typo
  • Loading branch information
iluwatar committed Jun 24, 2021
1 parent bbdff14 commit 04bf566
Show file tree
Hide file tree
Showing 66 changed files with 870 additions and 355 deletions.
4 changes: 2 additions & 2 deletions abstract-factory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,13 @@ Example use cases
* Unit test case writing becomes much easier
* UI tools for different OS

## Consequences:
## Consequences

* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time.
* While the pattern is great when creating predefined objects, adding the new ones might be challenging.
* The code becomes more complicated than it should be since a lot of new interfaces and classes are introduced along with the pattern.

## Tutorial
## Tutorials

* [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java)

Expand Down
4 changes: 2 additions & 2 deletions adapter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Use the Adapter pattern when
* you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class.
* most of the applications using third party libraries use adapters as a middle layer between the application and the 3rd party library to decouple the application from the library. If another library has to be used only an adapter for the new library is required without having to change the application code.

## Consequences:
## Consequences
Class and object adapters have different trade-offs. A class adapter

* adapts Adaptee to Target by committing to a concrete Adaptee class. As a consequence, a class adapter won’t work when we want to adapt a class and all its subclasses.
Expand All @@ -118,7 +118,7 @@ An object adapter
* makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making Adapter refer to the subclass rather than the Adaptee itself.


## Real world examples
## Known uses

* [java.util.Arrays#asList()](http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29)
* [java.util.Collections#list()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#list-java.util.Enumeration-)
Expand Down
35 changes: 22 additions & 13 deletions bridge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Decouple an abstraction from its implementation so that the two can vary indepen

## Explanation

Real world example
Real-world example

> Consider you have a weapon with different enchantments, and you are supposed to allow mixing
> different weapons with different enchantments. What would you do? Create multiple copies of each
Expand Down Expand Up @@ -161,27 +161,36 @@ public class SoulEatingEnchantment implements Enchantment {
Here are both hierarchies in action:

```java
LOGGER.info("The knight receives an enchanted sword.");
var enchantedSword = new Sword(new SoulEatingEnchantment());
enchantedSword.wield();
enchantedSword.swing();
enchantedSword.unwield();
// The sword is wielded.
// The item spreads bloodlust.
// The sword is swinged.
// The item eats the soul of enemies.
// The sword is unwielded.
// Bloodlust slowly disappears.

LOGGER.info("The valkyrie receives an enchanted hammer.");
var hammer = new Hammer(new FlyingEnchantment());
hammer.wield();
hammer.swing();
hammer.unwield();
// The hammer is wielded.
// The item begins to glow faintly.
// The hammer is swinged.
// The item flies and strikes the enemies finally returning to owner's hand.
// The hammer is unwielded.
// The item's glow fades.
```

Here's the console output.

```
The knight receives an enchanted sword.
The sword is wielded.
The item spreads bloodlust.
The sword is swung.
The item eats the soul of enemies.
The sword is unwielded.
Bloodlust slowly disappears.
The valkyrie receives an enchanted hammer.
The hammer is wielded.
The item begins to glow faintly.
The hammer is swung.
The item flies and strikes the enemies finally returning to owner's hand.
The hammer is unwielded.
The item's glow fades.
```

## Class diagram
Expand Down
8 changes: 4 additions & 4 deletions builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ process can create different representations.

## Explanation

Real world example
Real-world example

> Imagine a character generator for a role-playing game. The easiest option is to let the computer
> create the character for you. If you want to manually select the character details like
> profession, gender, hair color etc. the character generation becomes a step-by-step process that
> profession, gender, hair color, etc. the character generation becomes a step-by-step process that
> completes when all the selections are ready.
In plain words
Expand Down Expand Up @@ -49,7 +49,7 @@ anti-pattern.

**Programmatic Example**

The sane alternative is to use the Builder pattern. First of all we have our hero that we want to
The sane alternative is to use the Builder pattern. First of all, we have our hero that we want to
create:

```java
Expand Down Expand Up @@ -134,7 +134,7 @@ Use the Builder pattern when
* The algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled
* The construction process must allow different representations for the object that's constructed

## Real world examples
## Known uses

* [java.lang.StringBuilder](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)
* [java.nio.ByteBuffer](http://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#put-byte-) as well as similar buffers such as FloatBuffer, IntBuffer and so on.
Expand Down
35 changes: 22 additions & 13 deletions chain/README.md → chain-of-responsibility/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
---
layout: pattern
title: Chain of responsibility
folder: chain
permalink: /patterns/chain/
folder: chain-of-responsibility
permalink: /patterns/chain-of-responsibility/
categories: Behavioral
language: en
tags:
- Gang of Four
---

## Intent

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to
handle the request. Chain the receiving objects and pass the request along the chain until an object
handles it.

## Explanation

Real world example
Real-world example

> The Orc King gives loud orders to his army. The closest one to react is the commander, then
> officer and then soldier. The commander, officer and soldier here form a chain of responsibility.
> an officer, and then a soldier. The commander, officer, and soldier form a chain of responsibility.
In plain words

Expand All @@ -35,7 +36,7 @@ Wikipedia says
**Programmatic Example**

Translating our example with the orcs from above. First we have the `Request` class:
Translating our example with the orcs from above. First, we have the `Request` class:

```java
public class Request {
Expand Down Expand Up @@ -66,7 +67,7 @@ public enum RequestType {
}
```

Then the request handler hierarchy
Next, we show the request handler hierarchy.

```java
@Slf4j
Expand Down Expand Up @@ -116,7 +117,7 @@ public class OrcCommander extends RequestHandler {

```

Then we have the Orc King who gives the orders and forms the chain
The Orc King gives the orders and forms the chain.

```java
public class OrcKing {
Expand All @@ -136,18 +137,26 @@ public class OrcKing {
}
```

Then it is used as follows
The chain of responsibility in action.

```java
var king = new OrcKing();
king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle")); // Orc commander handling request "defend castle"
king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner")); // Orc officer handling request "torture prisoner"
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); // Orc soldier handling request "collect tax"
king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle"));
king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner"));
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax"));
```

The console output.

```
Orc commander handling request "defend castle"
Orc officer handling request "torture prisoner"
Orc soldier handling request "collect tax"
```

## Class diagram

![alt text](./etc/chain.urm.png "Chain of Responsibility class diagram")
![alt text](./etc/chain-of-responsibility.urm.png "Chain of Responsibility class diagram")

## Applicability

Expand All @@ -157,7 +166,7 @@ Use Chain of Responsibility when
* You want to issue a request to one of several objects without specifying the receiver explicitly.
* The set of objects that can handle a request should be specified dynamically.

## Real world examples
## Known uses

* [java.util.logging.Logger#log()](http://docs.oracle.com/javase/8/docs/api/java/util/logging/Logger.html#log%28java.util.logging.Level,%20java.lang.String%29)
* [Apache Commons Chain](https://commons.apache.org/proper/commons-chain/index.html)
Expand Down
File renamed without changes
File renamed without changes.
2 changes: 1 addition & 1 deletion chain/pom.xml → chain-of-responsibility/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<artifactId>java-design-patterns</artifactId>
<version>1.25.0-SNAPSHOT</version>
</parent>
<artifactId>chain</artifactId>
<artifactId>chain-of-responsibility</artifactId>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
29 changes: 13 additions & 16 deletions command/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
---
---
layout: pattern
title: Command
folder: command
Expand All @@ -19,7 +19,7 @@ Encapsulate a request as an object, thereby letting you parameterize clients wit
requests, queue or log requests, and support undoable operations.

## Explanation
Real world example
Real-world example

> There is a wizard casting spells on a goblin. The spells are executed on the goblin one by one.
> The first spell shrinks the goblin and the second makes him invisible. Then the wizard reverses
Expand Down Expand Up @@ -135,7 +135,7 @@ public class Goblin extends Target {
}
```

Finally we have the wizard in main function who casts spell
Finally, we have the wizard in the main function casting spells.

```java
public static void main(String[] args) {
Expand Down Expand Up @@ -202,32 +202,29 @@ Use the Command pattern when you want to:
* Parameterize objects by an action to perform. You can express such parameterization in a
procedural language with a callback function, that is, a function that's registered somewhere to be
called at a later point. Commands are an object-oriented replacement for callbacks.
* Specify, queue, and execute requests at different times. A Command object can have a lifetime
* Specify, queue, and execute requests at different times. A Command object can have a life
independent of the original request. If the receiver of a request can be represented in an address
space-independent way, then you can transfer a command object for the request to a different process
and fulfill the request there.
* Support undo. The Command's execute operation can store state for reversing its effects in the
command itself. The Command interface must have an added un-execute operation that reverses the
effects of a previous call to execute. The executed commands are stored in a history list.
Unlimited-level undo and redo is achieved by traversing this list backwards and forwards calling
un-execute and execute, respectively.
Unlimited-level undo and redo functionality is achieved by traversing this list backward and forward
calling un-execute and execute, respectively.
* Support logging changes so that they can be reapplied in case of a system crash. By augmenting the
Command interface with load and store operations, you can keep a persistent log of changes.
Recovering from a crash involves reloading logged commands from disk and re-executing them with
Recovering from a crash involves reloading logged commands from the disk and re-executing them with
the execute operation.
* Structure a system around high-level operations build on primitive operations. Such a structure is
common in information systems that support transactions. A transaction encapsulates a set of changes
to data. The Command pattern offers a way to model transactions. Commands have a common interface,
common in information systems that support transactions. A transaction encapsulates a set of data
changes. The Command pattern offers a way to model transactions. Commands have a common interface,
letting you invoke all transactions the same way. The pattern also makes it easy to extend the
system with new transactions.
* Keep a history of requests.
* Implement callback functionality.
* Implement the undo functionality.

## Typical Use Case

* To keep a history of requests
* Implement callback functionality
* Implement the undo functionality

## Real world examples
## Known uses

* [java.lang.Runnable](http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html)
* [org.junit.runners.model.Statement](https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/runners/model/Statement.java)
Expand Down
2 changes: 1 addition & 1 deletion command/src/main/java/com/iluwatar/command/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/**
* The Command pattern is a behavioral design pattern in which an object is used to encapsulate all
* information needed to perform an action or trigger an event at a later time. This information
* includes the method name, the object that owns the method and values for the method parameters.
* includes the method name, the object that owns the method, and values for the method parameters.
*
* <p>Four terms always associated with the command pattern are command, receiver, invoker and
* client. A command object (spell) knows about the receiver (target) and invokes a method of the
Expand Down
30 changes: 21 additions & 9 deletions composite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ treat individual objects and compositions of objects uniformly.

## Explanation

Real world example
Real-world example

> Every sentence is composed of words which are in turn composed of characters. Each of these
> objects is printable and they can have something printed before or after them like sentence always
> ends with full stop and word always has space before it.
> objects are printable and they can have something printed before or after them like sentence
> always ends with full stop and word always has space before it.
In plain words

> Composite pattern lets clients treat the individual objects in a uniform manner.
> Composite pattern lets clients uniformly treat the individual objects.
Wikipedia says

Expand Down Expand Up @@ -154,10 +154,22 @@ public class Messenger {
And then it can be used as:

```java
var orcMessage = new Messenger().messageFromOrcs();
orcMessage.print(); // Where there is a whip there is a way.
var elfMessage = new Messenger().messageFromElves();
elfMessage.print(); // Much wind pours from your mouth.
var messenger = new Messenger();

LOGGER.info("Message from the orcs: ");
messenger.messageFromOrcs().print();

LOGGER.info("Message from the elves: ");
messenger.messageFromElves().print();
```

The console output:

```
Message from the orcs:
Where there is a whip there is a way.
Message from the elves:
Much wind pours from your mouth.
```

## Class diagram
Expand All @@ -172,7 +184,7 @@ Use the Composite pattern when
* You want clients to be able to ignore the difference between compositions of objects and
individual objects. Clients will treat all objects in the composite structure uniformly.

## Real world examples
## Known uses

* [java.awt.Container](http://docs.oracle.com/javase/8/docs/api/java/awt/Container.html) and [java.awt.Component](http://docs.oracle.com/javase/8/docs/api/java/awt/Component.html)
* [Apache Wicket](https://github.com/apache/wicket) component tree, see [Component](https://github.com/apache/wicket/blob/91e154702ab1ff3481ef6cbb04c6044814b7e130/wicket-core/src/main/java/org/apache/wicket/Component.java) and [MarkupContainer](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java)
Expand Down
11 changes: 5 additions & 6 deletions composite/src/main/java/com/iluwatar/composite/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ public class App {
* @param args command line args
*/
public static void main(String[] args) {
LOGGER.info("Message from the orcs: ");

var orcMessage = new Messenger().messageFromOrcs();
orcMessage.print();
var messenger = new Messenger();

LOGGER.info("\nMessage from the elves: ");
LOGGER.info("Message from the orcs: ");
messenger.messageFromOrcs().print();

var elfMessage = new Messenger().messageFromElves();
elfMessage.print();
LOGGER.info("Message from the elves: ");
messenger.messageFromElves().print();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ public Sentence(List<Word> words) {

@Override
protected void printThisAfter() {
System.out.print(".");
System.out.print(".\n");
}
}

0 comments on commit 04bf566

Please sign in to comment.