Skip to content

Commit f803c35

Browse files
author
chenhao
committed
2 parents 01ef18a + 19378f3 commit f803c35

File tree

59 files changed

+1687
-1003
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1687
-1003
lines changed

.all-contributorsrc

+9
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,15 @@
11761176
"contributions": [
11771177
"code"
11781178
]
1179+
},
1180+
{
1181+
"login": "fedorskvorcov",
1182+
"name": "Fedor Skvorcov",
1183+
"avatar_url": "https://avatars3.githubusercontent.com/u/43882212?v=4",
1184+
"profile": "https://github.com/fedorskvorcov",
1185+
"contributions": [
1186+
"code"
1187+
]
11791188
}
11801189
],
11811190
"contributorsPerLine": 4,

.github/workflows/maven-ci.yml

+7-7
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@ on:
3333
jobs:
3434
build:
3535

36-
runs-on: ubuntu-18.04
36+
runs-on: ubuntu-20.04
3737

3838
steps:
3939
- uses: actions/checkout@v2
40+
with:
41+
# Disabling shallow clone for improving relevancy of SonarQube reporting
42+
fetch-depth: 0
4043
- name: Set up JDK 11
4144
uses: actions/setup-java@v1
4245
with:
@@ -49,14 +52,11 @@ jobs:
4952
${{ runner.os }}-maven-
5053
# Some tests need screen access
5154
- name: Install xvfb
52-
run: sudo apt-get install xvfb
53-
# SonarQube scan does not work for forked repositories
55+
run: sudo apt-get install -y xvfb
56+
# The SonarQube analysis is only for the master branch of the main repository.
57+
# SonarQube scan does not work for forked repositories try changing it to xvfb-run mvn clean verify
5458
# See https://jira.sonarsource.com/browse/MMF-1371
55-
- name: Build with Maven
56-
if: github.ref != 'refs/heads/master'
57-
run: xvfb-run mvn clean verify
5859
- name: Build with Maven and run SonarQube analysis
59-
if: github.ref == 'refs/heads/master'
6060
run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
6161
env:
6262
# These two env variables are needed for sonar analysis

.github/workflows/maven-pr-builder.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ on:
3333
jobs:
3434
build:
3535

36-
runs-on: ubuntu-18.04
36+
runs-on: ubuntu-20.04
3737

3838
steps:
3939
- uses: actions/checkout@v2
@@ -49,9 +49,9 @@ jobs:
4949
${{ runner.os }}-maven-
5050
# Some tests need screen access
5151
- name: Install xvfb
52-
run: sudo apt-get install xvfb
53-
# SonarQube scan does not work for forked repositories
52+
run: sudo apt-get install -y xvfb
53+
# This worflow is only for building Pull Requests, the master branch runs Sonar analysis on the main repository.
54+
# SonarQube scan does not work for forked repositories.
5455
# See https://jira.sonarsource.com/browse/MMF-1371
5556
- name: Build with Maven
56-
if: github.ref != 'refs/heads/master'
5757
run: xvfb-run mvn clean verify

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
1111
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
1212
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
13-
[![All Contributors](https://img.shields.io/badge/all_contributors-129-orange.svg?style=flat-square)](#contributors-)
13+
[![All Contributors](https://img.shields.io/badge/all_contributors-130-orange.svg?style=flat-square)](#contributors-)
1414
<!-- ALL-CONTRIBUTORS-BADGE:END -->
1515

1616
# Introduction
@@ -263,6 +263,7 @@ This project is licensed under the terms of the MIT license.
263263
</tr>
264264
<tr>
265265
<td align="center"><a href="https://www.stefan-birkner.de"><img src="https://avatars1.githubusercontent.com/u/711349?v=4" width="100px;" alt=""/><br /><sub><b>Stefan Birkner</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=stefanbirkner" title="Code">💻</a></td>
266+
<td align="center"><a href="https://github.com/fedorskvorcov"><img src="https://avatars3.githubusercontent.com/u/43882212?v=4" width="100px;" alt=""/><br /><sub><b>Fedor Skvorcov</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=fedorskvorcov" title="Code">💻</a></td>
266267
</tr>
267268
</table>
268269

callback/README.md

+12-6
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,26 @@ tags:
99
---
1010

1111
## Intent
12-
Callback is a piece of executable code that is passed as an argument to other code, which is expected to call back
13-
(execute) the argument at some convenient time.
12+
13+
Callback is a piece of executable code that is passed as an argument to other code, which is
14+
expected to call back (execute) the argument at some convenient time.
1415

1516
## Explanation
1617

1718
Real world example
1819

19-
> We need to be notified after executing task has finished. We pass a callback method for the executor and wait for it to call back on us.
20+
> We need to be notified after executing task has finished. We pass a callback method for
21+
> the executor and wait for it to call back on us.
2022
2123
In plain words
2224

2325
> Callback is a method passed to the executor which will be called at defined moment.
2426
2527
Wikipedia says
2628

27-
> In computer programming, a callback, also known as a "call-after" function, is any executable code that is passed as an argument to other code; that other code is expected to call back (execute) the argument at a given time.
29+
> In computer programming, a callback, also known as a "call-after" function, is any executable
30+
> code that is passed as an argument to other code; that other code is expected to call
31+
> back (execute) the argument at a given time.
2832
2933
**Programmatic Example**
3034

@@ -61,21 +65,23 @@ public final class SimpleTask extends Task {
6165
}
6266
```
6367

64-
Finally here's how we execute a task and receive a callback when it's finished.
68+
Finally, here's how we execute a task and receive a callback when it's finished.
6569

6670
```java
6771
var task = new SimpleTask();
6872
task.executeWith(() -> LOGGER.info("I'm done now."));
6973
```
7074

7175
## Class diagram
76+
7277
![alt text](./etc/callback.png "Callback")
7378

7479
## Applicability
80+
7581
Use the Callback pattern when
7682

7783
* when some arbitrary synchronous or asynchronous action must be performed after execution of some defined activity.
7884

7985
## Real world examples
8086

81-
* [CyclicBarrier](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped.
87+
* [CyclicBarrier](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept a callback that will be triggered every time a barrier is tripped.

callback/etc/callback.png

9.45 KB
Loading

callback/etc/callback.urm.puml

-5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ package com.iluwatar.callback {
88
interface Callback {
99
+ call() {abstract}
1010
}
11-
class LambdasApp {
12-
- LOGGER : Logger {static}
13-
- LambdasApp()
14-
+ main(args : String[]) {static}
15-
}
1611
class SimpleTask {
1712
- LOGGER : Logger {static}
1813
+ SimpleTask()

chain/README.md

+17-10
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,32 @@ tags:
99
---
1010

1111
## Intent
12-
Avoid coupling the sender of a request to its receiver by giving
13-
more than one object a chance to handle the request. Chain the receiving
14-
objects and pass the request along the chain until an object handles it.
12+
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to
13+
handle the request. Chain the receiving objects and pass the request along the chain until an object
14+
handles it.
1515

1616
## Explanation
1717

1818
Real world example
1919

20-
> 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.
20+
> The Orc King gives loud orders to his army. The closest one to react is the commander, then
21+
> officer and then soldier. The commander, officer and soldier here form a chain of responsibility.
2122
2223
In plain words
2324

24-
> It helps building a chain of objects. Request enters from one end and keeps going from object to object till it finds the suitable handler.
25+
> It helps to build a chain of objects. A request enters from one end and keeps going from an object
26+
> to another until it finds a suitable handler.
2527
2628
Wikipedia says
2729

28-
> In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain.
30+
> In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of
31+
> a source of command objects and a series of processing objects. Each processing object contains
32+
> logic that defines the types of command objects that it can handle; the rest are passed to the
33+
> next processing object in the chain.
2934
3035
**Programmatic Example**
3136

32-
Translating our example with orcs from above. First we have the request class
37+
Translating our example with the orcs from above. First we have the `Request` class:
3338

3439
```java
3540
public class Request {
@@ -140,14 +145,16 @@ king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); // Orc so
140145
```
141146

142147
## Class diagram
148+
143149
![alt text](./etc/chain.urm.png "Chain of Responsibility class diagram")
144150

145151
## Applicability
152+
146153
Use Chain of Responsibility when
147154

148-
* more than one object may handle a request, and the handler isn't known a priori. The handler should be ascertained automatically
149-
* you want to issue a request to one of several objects without specifying the receiver explicitly
150-
* the set of objects that can handle a request should be specified dynamically
155+
* More than one object may handle a request, and the handler isn't known a priori. The handler should be ascertained automatically.
156+
* You want to issue a request to one of several objects without specifying the receiver explicitly.
157+
* The set of objects that can handle a request should be specified dynamically.
151158

152159
## Real world examples
153160

circuit-breaker/README.md

+31-16
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,43 @@ tags:
1212

1313
## Intent
1414

15-
Handle costly remote *procedure/service* calls in such a way that the failure of a **single** service/component cannot bring the whole application down, and we can reconnect to the service as soon as possible.
15+
Handle costly remote service calls in such a way that the failure of a single service/component
16+
cannot bring the whole application down, and we can reconnect to the service as soon as possible.
1617

1718
## Explanation
1819

1920
Real world example
2021

21-
> Imagine a Web App that has both local (example: files and images) and remote (example: database entries) to serve. The database might not be responding due to a variety of reasons, so if the application keeps trying to read from the database using multiple threads/processes, soon all of them will hang and our entire web application will crash. We should be able to detect this situation and show the user an appropriate message so that he/she can explore other parts of the app unaffected by the database failure without any problem.
22+
> Imagine a web application that has both local files/images and remote database entries to serve.
23+
> The database might not be responding due to a variety of reasons, so if the application keeps
24+
> trying to read from the database using multiple threads/processes, soon all of them will hang
25+
> causing our entire web application will crash. We should be able to detect this situation and show
26+
> the user an appropriate message so that he/she can explore other parts of the app unaffected by
27+
> the database failure.
2228
2329
In plain words
2430

25-
> Allows us to save resources when we know a remote service failed. Useful when all parts of our application are highly decoupled from each other, and failure of one component doesn't mean the other parts will stop working.
31+
> Circuit Breaker allows graceful handling of failed remote services. It's especially useful when
32+
> all parts of our application are highly decoupled from each other, and failure of one component
33+
> doesn't mean the other parts will stop working.
2634
2735
Wikipedia says
2836

29-
> **Circuit breaker** is a design pattern used in modern software development. It is used to detect failures and encapsulates the logic of preventing a failure from constantly recurring, during maintenance, temporary external system failure or unexpected system difficulties.
30-
31-
So, how does this all come together?
37+
> Circuit breaker is a design pattern used in modern software development. It is used to detect
38+
> failures and encapsulates the logic of preventing a failure from constantly recurring, during
39+
> maintenance, temporary external system failure or unexpected system difficulties.
3240
3341
## Programmatic Example
34-
With the above example in mind we will imitate the functionality in a simple manner. We have two services: A *monitoring service* which will mimic the web app and will make both **local** and **remote** calls.
42+
43+
So, how does this all come together? With the above example in mind we will imitate the
44+
functionality in a simple example. A monitoring service mimics the web app and makes both local and
45+
remote calls.
3546

3647
The service architecture is as follows:
3748

3849
![alt text](./etc/ServiceDiagram.PNG "Service Diagram")
3950

40-
In terms of code, the End user application is:
51+
In terms of code, the end user application is:
4152

4253
```java
4354
public class App {
@@ -62,7 +73,7 @@ public class App {
6273
}
6374
```
6475

65-
The monitoring service is:
76+
The monitoring service:
6677

6778
``` java
6879
public class MonitoringService {
@@ -80,7 +91,8 @@ public class MonitoringService {
8091
}
8192
}
8293
```
83-
As it can be seen, it does the call to get local resources directly, but it wraps the call to remote (costly) service in a circuit breaker object, which prevents faults as follows:
94+
As it can be seen, it does the call to get local resources directly, but it wraps the call to
95+
remote (costly) service in a circuit breaker object, which prevents faults as follows:
8496

8597
```java
8698
public class CircuitBreaker {
@@ -155,24 +167,27 @@ public class CircuitBreaker {
155167
}
156168
```
157169

158-
How does the above pattern prevent failures? Let's understand via this finite state machine implemented by it.
170+
How does the above pattern prevent failures? Let's understand via this finite state machine
171+
implemented by it.
159172

160173
![alt text](./etc/StateDiagram.PNG "State Diagram")
161174

162-
- We initialize the Circuit Breaker object with certain parameters: **timeout**, **failureThreshold** and **retryTimePeriod** which help determine how resilient the API is.
163-
- Initially, we are in the **closed** state and the remote call to API happens.
175+
- We initialize the Circuit Breaker object with certain parameters: `timeout`, `failureThreshold` and `retryTimePeriod` which help determine how resilient the API is.
176+
- Initially, we are in the `closed` state and nos remote calls to the API have occurred.
164177
- Every time the call succeeds, we reset the state to as it was in the beginning.
165-
- If the number of failures cross a certain threshold, we move to the **open** state, which acts just like an open circuit and prevents remote service calls from being made, thus saving resources. (Here, we return the response called ```stale response from API```)
166-
- Once we exceed the retry timeout period, we move to the **half-open** state and make another call to the remote service again to check if the service is working so that we can serve fresh content. A *failure* sets it back to **open** state and another attempt is made after retry timeout period, while a *success* sets it to **closed** state so that everything starts working normally again.
178+
- If the number of failures cross a certain threshold, we move to the `open` state, which acts just like an open circuit and prevents remote service calls from being made, thus saving resources. (Here, we return the response called ```stale response from API```)
179+
- Once we exceed the retry timeout period, we move to the `half-open` state and make another call to the remote service again to check if the service is working so that we can serve fresh content. A failure sets it back to `open` state and another attempt is made after retry timeout period, while a success sets it to `closed` state so that everything starts working normally again.
167180

168181
## Class diagram
182+
169183
![alt text](./etc/circuit-breaker.urm.png "Circuit Breaker class diagram")
170184

171185
## Applicability
186+
172187
Use the Circuit Breaker pattern when
173188

174189
- Building a fault-tolerant application where failure of some services shouldn't bring the entire application down.
175-
- Building an continuously incremental/continuous delivery application, as some of it's components can be upgraded without shutting it down entirely.
190+
- Building a continuously running (always-on) application, so that its components can be upgraded without shutting it down entirely.
176191

177192
## Related Patterns
178193

0 commit comments

Comments
 (0)