Compare commits
151 Commits
1.22.0
...
all-contri
Author | SHA1 | Date | |
---|---|---|---|
942f0665cb | |||
38cb7d1554 | |||
a77e9620b5 | |||
cf8e366e25 | |||
80605283f5 | |||
8ba111fe60 | |||
1cb9c2bcde | |||
d6edeee326 | |||
781a7c8b52 | |||
960adfc37a | |||
b3eb6ccea4 | |||
d609f3eec6 | |||
09dd0bee30 | |||
64eff5eb93 | |||
05dfd31fb7 | |||
2c8535e839 | |||
aea90ab115 | |||
211d7903ae | |||
02b6aba6ae | |||
76f634ff7a | |||
ae7a0b8a4a | |||
b7d122f614 | |||
93c11fdf23 | |||
ef4de30310 | |||
b62bed7e43 | |||
54c0b1725c | |||
4b88214bae | |||
eee409f284 | |||
2fdd7a11e9 | |||
f37d697a60 | |||
3e1a83e29d | |||
0a35cdfbe4 | |||
1eafb46b61 | |||
2ee5789c77 | |||
d9ed8a52b5 | |||
205b87cd93 | |||
689486267d | |||
9deb587c52 | |||
645fb20730 | |||
1886a6f969 | |||
9db997d0ae | |||
8982392fea | |||
082d63a1b3 | |||
6c21143303 | |||
172964e75c | |||
ab4e53a468 | |||
b907a2a9bc | |||
467f647ca2 | |||
a18c0f76ea | |||
e34de39ae7 | |||
4d95d38b8d | |||
d2724e8091 | |||
9a81ddb7d8 | |||
61dfa50822 | |||
09cee8ffa7 | |||
5aacdecc6c | |||
eeea3c7b1f | |||
76fb9aff8b | |||
68fa6f451b | |||
e98ad671e9 | |||
4264f52d49 | |||
ee654cf7b2 | |||
51f6282e9b | |||
2212690468 | |||
4beb53b8b8 | |||
0b1a98137a | |||
bd1dbec19f | |||
a3564a8847 | |||
9e30383eb6 | |||
6fe219d644 | |||
5192beb5dd | |||
f4f9c1a441 | |||
a396d972f6 | |||
30678792fd | |||
cfa2b35bff | |||
5db8037b8b | |||
71affacee2 | |||
371263d1b3 | |||
0b41aaaa76 | |||
f28a63a46c | |||
3ea65e06bc | |||
1aea35f8e5 | |||
0f751d40cb | |||
92ecd63ccf | |||
3033e4c9fc | |||
e68beb40ec | |||
a3c4d36c3d | |||
1c26bd7416 | |||
845da1fa16 | |||
751b3b9452 | |||
be1c0b8143 | |||
6ce33ed6df | |||
a4be693de6 | |||
80519379f1 | |||
95bef5f0e8 | |||
d429865c54 | |||
37a34ae174 | |||
67edeb806d | |||
0ad67c8726 | |||
a410004a8f | |||
16ef70bfdc | |||
6bf3a13064 | |||
54db4497a3 | |||
eaf3598807 | |||
4e01ca39fd | |||
1c558ff4c5 | |||
33e4a870ca | |||
33682ad3e8 | |||
2d6c372f21 | |||
f2bb46f9b4 | |||
81cc85a9cd | |||
f942bfa51c | |||
d2fdd7d82b | |||
365c74ddde | |||
728de1bb34 | |||
428efc7d53 | |||
1401accb4f | |||
6dba5b9b58 | |||
1ffb28ba4f | |||
c7c8940c5a | |||
e88ea8a870 | |||
8618ab64f6 | |||
f1471641b0 | |||
b99d37506f | |||
6c545c93e5 | |||
f00523f7c0 | |||
346cf0f793 | |||
20ea465b7f | |||
cd2a2e7711 | |||
310ae50248 | |||
670c4e43f3 | |||
f835d3d516 | |||
7d0a5c0edb | |||
ea57934db6 | |||
5681684157 | |||
b2b1ba95eb | |||
0335c61512 | |||
fb2c026822 | |||
b09b100614 | |||
0685a505d3 | |||
55769e9841 | |||
05e582ca3e | |||
a9c3df78ee | |||
1fbe9bbac5 | |||
e0b728c5e2 | |||
515b7e7134 | |||
d4b2496e60 | |||
7e4d0b4cdc | |||
8037495e04 | |||
6941e65cb4 | |||
7d845505b5 |
184
.all-contributorsrc
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"imageSize": 100,
|
||||||
|
"commit": false,
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"login": "iluwatar",
|
||||||
|
"name": "Ilkka Seppälä",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/582346?v=4",
|
||||||
|
"profile": "https://github.com/iluwatar",
|
||||||
|
"contributions": [
|
||||||
|
"projectManagement",
|
||||||
|
"maintenance",
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "amit1307",
|
||||||
|
"name": "amit1307",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/23420222?v=4",
|
||||||
|
"profile": "https://github.com/amit1307",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "npathai",
|
||||||
|
"name": "Narendra Pathai",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/1792515?v=4",
|
||||||
|
"profile": "https://github.com/npathai",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"ideas",
|
||||||
|
"review"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "fluxw42",
|
||||||
|
"name": "Jeroen Meulemeester",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/1545460?v=4",
|
||||||
|
"profile": "https://github.com/fluxw42",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mikulucky",
|
||||||
|
"name": "Joseph McCarthy",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/4526195?v=4",
|
||||||
|
"profile": "http://www.joemccarthy.co.uk",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "thomasoss",
|
||||||
|
"name": "Thomas",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/22516154?v=4",
|
||||||
|
"profile": "https://github.com/thomasoss",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "anuragagarwal561994",
|
||||||
|
"name": "Anurag Agarwal",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/6075379?v=4",
|
||||||
|
"profile": "https://github.com/anuragagarwal561994",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "markusmo3",
|
||||||
|
"name": "Markus Moser",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/3317416?v=4",
|
||||||
|
"profile": "https://markusmo3.github.io",
|
||||||
|
"contributions": [
|
||||||
|
"design",
|
||||||
|
"code",
|
||||||
|
"ideas"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "isabiq",
|
||||||
|
"name": "Sabiq Ihab",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/19510920?v=4",
|
||||||
|
"profile": "https://twitter.com/i_sabiq",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "inbravo",
|
||||||
|
"name": "Amit Dixit",
|
||||||
|
"avatar_url": "https://avatars3.githubusercontent.com/u/5253764?v=4",
|
||||||
|
"profile": "http://inbravo.github.io",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "piyushchaudhari04",
|
||||||
|
"name": "Piyush Kailash Chaudhari",
|
||||||
|
"avatar_url": "https://avatars3.githubusercontent.com/u/10268029?v=4",
|
||||||
|
"profile": "https://github.com/piyushchaudhari04",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "joshzambales",
|
||||||
|
"name": "joshzambales",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/8704552?v=4",
|
||||||
|
"profile": "https://github.com/joshzambales",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Crossy147",
|
||||||
|
"name": "Kamil Pietruszka",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/7272996?v=4",
|
||||||
|
"profile": "https://github.com/Crossy147",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "zafarella",
|
||||||
|
"name": "Zafar Khaydarov",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/660742?v=4",
|
||||||
|
"profile": "http://cs.joensuu.fi/~zkhayda",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"doc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "kemitix",
|
||||||
|
"name": "Paul Campbell",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/1147749?v=4",
|
||||||
|
"profile": "https://kemitix.github.io/",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Argyro-Sioziou",
|
||||||
|
"name": "Argyro Sioziou",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/22822639?v=4",
|
||||||
|
"profile": "https://github.com/Argyro-Sioziou",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "TylerMcConville",
|
||||||
|
"name": "TylerMcConville",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/4946449?v=4",
|
||||||
|
"profile": "https://github.com/TylerMcConville",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "saksham93",
|
||||||
|
"name": "saksham93",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/37399540?v=4",
|
||||||
|
"profile": "https://github.com/saksham93",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"contributorsPerLine": 7,
|
||||||
|
"projectName": "java-design-patterns",
|
||||||
|
"projectOwner": "iluwatar",
|
||||||
|
"repoType": "github",
|
||||||
|
"repoHost": "https://github.com",
|
||||||
|
"skipCi": true
|
||||||
|
}
|
60
.github/workflows/maven.yml
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#
|
||||||
|
# The MIT License
|
||||||
|
# Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
#
|
||||||
|
|
||||||
|
# This workflow will build a Java project with Maven
|
||||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||||
|
|
||||||
|
name: Java CI with Maven
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up JDK 11
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: 11
|
||||||
|
# Some tests need screen access
|
||||||
|
- name: Install xvfb
|
||||||
|
run: sudo apt-get install xvfb
|
||||||
|
# SonarQube scan does not work for forked repositories
|
||||||
|
# See https://jira.sonarsource.com/browse/MMF-1371
|
||||||
|
- name: Build with Maven
|
||||||
|
if: github.ref != 'refs/heads/master'
|
||||||
|
run: xvfb-run mvn clean verify
|
||||||
|
- name: Build with Maven and run SonarQube analysis
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
run: xvfb-run mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
|
||||||
|
env:
|
||||||
|
# These two env variables are needed for sonar analysis
|
||||||
|
GITHUB_TOKEN: ${{ secrets.REPOSITORY_ACCESS_TOKEN }}
|
||||||
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
36
.travis.yml
@ -1,36 +0,0 @@
|
|||||||
language: java
|
|
||||||
dist: bionic
|
|
||||||
jdk:
|
|
||||||
- openjdk11
|
|
||||||
sudo: required
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- secure: "DCpazS3nkLnter3sguXEAS2fC/1ZWNfM+XLyif9MfNFxlZdpni2vCD/jA0Rdpga8puQWHNVLyAec+RPFH/2qSmJ1c1UTV5MaLv8tPqwUX0VFA+1I6XoSv6oX4ldHTBWHEWqQHkRFOLoil0h0edc0tTOWQwXF8U+DLAB+HkRb4gw="
|
|
||||||
|
|
||||||
services:
|
|
||||||
- xvfb
|
|
||||||
|
|
||||||
addons:
|
|
||||||
sonarcloud:
|
|
||||||
organization: "iluwatar"
|
|
||||||
token:
|
|
||||||
secure: "FpHwMYPMkdWU6CeIB7+O3qIeIM4vJMp47UjkKK53f0w0s6tPZofZZkab+gcL2TqKSil7sFVB/AQXU1cUubflRszwcLbNsc8H2yFehD79o0o0Mqd1Dd5ip/q0KQbHkkln+InFlVLfvrLB4Xd4mlQVxbGhqpULBhXjKzFzQlRFcuU="
|
|
||||||
script:
|
|
||||||
# Because of Travis security restrictions, SonarCloud analysis cannot be run on pull requests originated from forks
|
|
||||||
# See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
|
|
||||||
- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then mvn clean verify; fi'
|
|
||||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then mvn clean verify sonar:sonar -Dsonar.projectKey=iluwatar_java-design-patterns -Dsonar.host.url=https://sonarcloud.io; fi'
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- bash update-website.sh
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
- iluwatar@gmail.com
|
|
||||||
webhooks:
|
|
||||||
urls:
|
|
||||||
- https://webhooks.gitter.im/e/3319623945358a093a6f
|
|
||||||
on_success: change # options: [always|never|change] default: always
|
|
||||||
on_failure: always # options: [always|never|change] default: always
|
|
||||||
on_start: never # options: [always|never|change] default: always
|
|
@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014-2016 Ilkka Seppälä
|
Copyright (c) 2014-2020 Ilkka Seppälä
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
54
README.md
@ -4,10 +4,13 @@
|
|||||||
|
|
||||||
# Design patterns implemented in Java
|
# Design patterns implemented in Java
|
||||||
|
|
||||||
[](https://travis-ci.org/iluwatar/java-design-patterns)
|

|
||||||
[](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md)
|
[](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md)
|
||||||
[](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
|
[](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
|
||||||
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||||
|
[](#contributors-)
|
||||||
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||||
|
|
||||||
# Introduction
|
# Introduction
|
||||||
|
|
||||||
@ -31,19 +34,20 @@ programming tutorials how to implement a specific pattern. We use the most
|
|||||||
popular battle-proven open source Java technologies.
|
popular battle-proven open source Java technologies.
|
||||||
|
|
||||||
Before you dive into the material, you should be familiar with various
|
Before you dive into the material, you should be familiar with various
|
||||||
software design principles.
|
[Software Design Principles](https://java-design-patterns.com/principles/).
|
||||||
|
|
||||||
All designs should be as simple as possible. You should start with KISS, YAGNI,
|
All designs should be as simple as possible. You should start with KISS, YAGNI,
|
||||||
and Do The Simplest Thing That Could Possibly Work principles. Complexity and
|
and Do The Simplest Thing That Could Possibly Work principles. Complexity and
|
||||||
patterns should only be introduced when they are needed for practical
|
patterns should only be introduced when they are needed for practical
|
||||||
extensibility.
|
extensibility.
|
||||||
|
|
||||||
Once you are familiar with these concepts you can start drilling down into
|
Once you are familiar with these concepts you can start drilling down into the
|
||||||
patterns by any of the following approaches
|
[available design patterns](https://java-design-patterns.com/patterns/) by any
|
||||||
|
of the following approaches
|
||||||
|
|
||||||
- Using difficulty tags, `Difficulty-Beginner`, `Difficulty-Intermediate` & `Difficulty-Expert`.
|
- Search for a specific pattern by name. Can't find one? Please report a new pattern [here](https://github.com/iluwatar/java-design-patterns/issues).
|
||||||
|
- Using tags such as `Performance`, `Gang of Four` or `Data access`.
|
||||||
- Using pattern categories, `Creational`, `Behavioral`, and others.
|
- Using pattern categories, `Creational`, `Behavioral`, and others.
|
||||||
- Search for a specific pattern. Can't find one? Please report a new pattern [here](https://github.com/iluwatar/java-design-patterns/issues).
|
|
||||||
|
|
||||||
Hopefully you find the object oriented solutions presented on this site useful
|
Hopefully you find the object oriented solutions presented on this site useful
|
||||||
in your architectures and have as much fun learning them as we had developing them.
|
in your architectures and have as much fun learning them as we had developing them.
|
||||||
@ -57,3 +61,41 @@ you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwata
|
|||||||
# License
|
# License
|
||||||
|
|
||||||
This project is licensed under the terms of the MIT license.
|
This project is licensed under the terms of the MIT license.
|
||||||
|
|
||||||
|
# Contributors
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/iluwatar"><img src="https://avatars1.githubusercontent.com/u/582346?v=4" width="100px;" alt=""/><br /><sub><b>Ilkka Seppälä</b></sub></a><br /><a href="#projectManagement-iluwatar" title="Project Management">📆</a> <a href="#maintenance-iluwatar" title="Maintenance">🚧</a> <a href="#content-iluwatar" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/amit1307"><img src="https://avatars0.githubusercontent.com/u/23420222?v=4" width="100px;" alt=""/><br /><sub><b>amit1307</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=amit1307" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/npathai"><img src="https://avatars2.githubusercontent.com/u/1792515?v=4" width="100px;" alt=""/><br /><sub><b>Narendra Pathai</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=npathai" title="Code">💻</a> <a href="#ideas-npathai" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3Anpathai" title="Reviewed Pull Requests">👀</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/fluxw42"><img src="https://avatars1.githubusercontent.com/u/1545460?v=4" width="100px;" alt=""/><br /><sub><b>Jeroen Meulemeester</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=fluxw42" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="http://www.joemccarthy.co.uk"><img src="https://avatars0.githubusercontent.com/u/4526195?v=4" width="100px;" alt=""/><br /><sub><b>Joseph McCarthy</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=mikulucky" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/thomasoss"><img src="https://avatars1.githubusercontent.com/u/22516154?v=4" width="100px;" alt=""/><br /><sub><b>Thomas</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=thomasoss" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/anuragagarwal561994"><img src="https://avatars1.githubusercontent.com/u/6075379?v=4" width="100px;" alt=""/><br /><sub><b>Anurag Agarwal</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=anuragagarwal561994" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://markusmo3.github.io"><img src="https://avatars1.githubusercontent.com/u/3317416?v=4" width="100px;" alt=""/><br /><sub><b>Markus Moser</b></sub></a><br /><a href="#design-markusmo3" title="Design">🎨</a> <a href="https://github.com/iluwatar/java-design-patterns/commits?author=markusmo3" title="Code">💻</a> <a href="#ideas-markusmo3" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||||
|
<td align="center"><a href="https://twitter.com/i_sabiq"><img src="https://avatars1.githubusercontent.com/u/19510920?v=4" width="100px;" alt=""/><br /><sub><b>Sabiq Ihab</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=isabiq" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="http://inbravo.github.io"><img src="https://avatars3.githubusercontent.com/u/5253764?v=4" width="100px;" alt=""/><br /><sub><b>Amit Dixit</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=inbravo" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/piyushchaudhari04"><img src="https://avatars3.githubusercontent.com/u/10268029?v=4" width="100px;" alt=""/><br /><sub><b>Piyush Kailash Chaudhari</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=piyushchaudhari04" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/joshzambales"><img src="https://avatars1.githubusercontent.com/u/8704552?v=4" width="100px;" alt=""/><br /><sub><b>joshzambales</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=joshzambales" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Crossy147"><img src="https://avatars2.githubusercontent.com/u/7272996?v=4" width="100px;" alt=""/><br /><sub><b>Kamil Pietruszka</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Crossy147" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="http://cs.joensuu.fi/~zkhayda"><img src="https://avatars2.githubusercontent.com/u/660742?v=4" width="100px;" alt=""/><br /><sub><b>Zafar Khaydarov</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=zafarella" title="Code">💻</a> <a href="https://github.com/iluwatar/java-design-patterns/commits?author=zafarella" title="Documentation">📖</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://kemitix.github.io/"><img src="https://avatars1.githubusercontent.com/u/1147749?v=4" width="100px;" alt=""/><br /><sub><b>Paul Campbell</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=kemitix" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Argyro-Sioziou"><img src="https://avatars0.githubusercontent.com/u/22822639?v=4" width="100px;" alt=""/><br /><sub><b>Argyro Sioziou</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Argyro-Sioziou" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/TylerMcConville"><img src="https://avatars0.githubusercontent.com/u/4946449?v=4" width="100px;" alt=""/><br /><sub><b>TylerMcConville</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=TylerMcConville" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/saksham93"><img src="https://avatars1.githubusercontent.com/u/37399540?v=4" width="100px;" alt=""/><br /><sub><b>saksham93</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=saksham93" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- markdownlint-enable -->
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
|
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||||
|
@ -5,13 +5,13 @@ folder: abstract-document
|
|||||||
permalink: /patterns/abstract-document/
|
permalink: /patterns/abstract-document/
|
||||||
categories: Structural
|
categories: Structural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Extensibility
|
||||||
- Difficulty-Intermediate
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
Achieve flexibility of untyped languages and keep the type-safety
|
Achieve flexibility of untyped languages and keep the type-safety
|
||||||
|
|
||||||
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
@ -26,4 +26,4 @@ Use the Abstract Document Pattern when
|
|||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Wikipedia: Abstract Document Pattern](https://en.wikipedia.org/wiki/Abstract_Document_Pattern)
|
* [Wikipedia: Abstract Document Pattern](https://en.wikipedia.org/wiki/Abstract_Document_Pattern)
|
||||||
* [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf)
|
* [Martin Fowler: Dealing with properties](http://martinfowler.com/apsupp/properties.pdf)
|
||||||
|
65
abstract-document/etc/abstract-document.urm.puml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.abstractdocument.domain.enums {
|
||||||
|
enum Property {
|
||||||
|
+ MODEL {static}
|
||||||
|
+ PARTS {static}
|
||||||
|
+ PRICE {static}
|
||||||
|
+ TYPE {static}
|
||||||
|
+ valueOf(name : String) : Property {static}
|
||||||
|
+ values() : Property[] {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
package com.iluwatar.abstractdocument.domain {
|
||||||
|
class Car {
|
||||||
|
+ Car(properties : Map<String, Object>)
|
||||||
|
}
|
||||||
|
interface HasModel {
|
||||||
|
+ getModel() : Optional<String>
|
||||||
|
}
|
||||||
|
interface HasParts {
|
||||||
|
+ getParts() : Stream<Part>
|
||||||
|
}
|
||||||
|
interface HasPrice {
|
||||||
|
+ getPrice() : Optional<Number>
|
||||||
|
}
|
||||||
|
interface HasType {
|
||||||
|
+ getType() : Optional<String>
|
||||||
|
}
|
||||||
|
class Part {
|
||||||
|
+ Part(properties : Map<String, Object>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
package com.iluwatar.abstractdocument {
|
||||||
|
abstract class AbstractDocument {
|
||||||
|
- properties : Map<String, Object>
|
||||||
|
# AbstractDocument(properties : Map<String, Object>)
|
||||||
|
+ children(key : String, constructor : Function<Map<String, Object>, T>) : Stream<T>
|
||||||
|
+ get(key : String) : Object
|
||||||
|
+ put(key : String, value : Object)
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
interface Document {
|
||||||
|
+ children(String, Function<Map<String, Object>, T>) : Stream<T> {abstract}
|
||||||
|
+ get(String) : Object {abstract}
|
||||||
|
+ put(String, Object) {abstract}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AbstractDocument ..|> Document
|
||||||
|
Car ..|> HasModel
|
||||||
|
Car ..|> HasPrice
|
||||||
|
Car ..|> HasParts
|
||||||
|
Car --|> AbstractDocument
|
||||||
|
HasModel --|> Document
|
||||||
|
HasParts --|> Document
|
||||||
|
HasPrice --|> Document
|
||||||
|
HasType --|> Document
|
||||||
|
Part ..|> HasType
|
||||||
|
Part ..|> HasModel
|
||||||
|
Part ..|> HasPrice
|
||||||
|
Part --|> AbstractDocument
|
||||||
|
@enduml
|
@ -1,42 +1,55 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
<modelVersion>4.0.0</modelVersion>
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
<parent>
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
<artifactId>java-design-patterns</artifactId>
|
||||||
THE SOFTWARE.
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
-->
|
</parent>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<artifactId>abstract-document</artifactId>
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<dependencies>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<dependency>
|
||||||
<parent>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<scope>test</scope>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
</dependency>
|
||||||
</parent>
|
</dependencies>
|
||||||
<artifactId>abstract-document</artifactId>
|
<build>
|
||||||
<dependencies>
|
<plugins>
|
||||||
<dependency>
|
<!-- Maven assembly plugin is invoked with default setting which we have
|
||||||
<groupId>org.junit.jupiter</groupId>
|
in parent pom and specifying the class having main method -->
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<plugin>
|
||||||
<scope>test</scope>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
</dependency>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
</dependencies>
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.abstractdocument.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.iluwatar.abstractdocument {
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
@ -5,9 +5,7 @@ folder: abstract-factory
|
|||||||
permalink: /patterns/abstract-factory/
|
permalink: /patterns/abstract-factory/
|
||||||
categories: Creational
|
categories: Creational
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Gang of Four
|
||||||
- Gang Of Four
|
|
||||||
- Difficulty-Intermediate
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Also known as
|
## Also known as
|
||||||
@ -157,6 +155,9 @@ public static void main(String[] args) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Use the Abstract Factory pattern when
|
Use the Abstract Factory pattern when
|
||||||
@ -197,4 +198,5 @@ Use the Abstract Factory pattern when
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
* [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)
|
||||||
|
* [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)
|
||||||
|
BIN
abstract-factory/etc/abstract-factory.urm.png
Normal file
After Width: | Height: | Size: 80 KiB |
101
abstract-factory/etc/abstract-factory.urm.puml
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.abstractfactory {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- army : Army
|
||||||
|
- castle : Castle
|
||||||
|
- king : King
|
||||||
|
+ App()
|
||||||
|
+ createKingdom(factory : KingdomFactory)
|
||||||
|
+ getArmy() : Army
|
||||||
|
~ getArmy(factory : KingdomFactory) : Army
|
||||||
|
+ getCastle() : Castle
|
||||||
|
~ getCastle(factory : KingdomFactory) : Castle
|
||||||
|
+ getKing() : King
|
||||||
|
~ getKing(factory : KingdomFactory) : King
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
- setArmy(army : Army)
|
||||||
|
- setCastle(castle : Castle)
|
||||||
|
- setKing(king : King)
|
||||||
|
}
|
||||||
|
class FactoryMaker {
|
||||||
|
+ FactoryMaker()
|
||||||
|
+ makeFactory(type : KingdomType) : KingdomFactory {static}
|
||||||
|
}
|
||||||
|
enum KingdomType {
|
||||||
|
+ ELF {static}
|
||||||
|
+ ORC {static}
|
||||||
|
+ valueOf(name : String) : KingdomType {static}
|
||||||
|
+ values() : KingdomType[] {static}
|
||||||
|
}
|
||||||
|
interface Army {
|
||||||
|
+ getDescription() : String {abstract}
|
||||||
|
}
|
||||||
|
interface Castle {
|
||||||
|
+ getDescription() : String {abstract}
|
||||||
|
}
|
||||||
|
class ElfArmy {
|
||||||
|
~ DESCRIPTION : String {static}
|
||||||
|
+ ElfArmy()
|
||||||
|
+ getDescription() : String
|
||||||
|
}
|
||||||
|
class ElfCastle {
|
||||||
|
~ DESCRIPTION : String {static}
|
||||||
|
+ ElfCastle()
|
||||||
|
+ getDescription() : String
|
||||||
|
}
|
||||||
|
class ElfKing {
|
||||||
|
~ DESCRIPTION : String {static}
|
||||||
|
+ ElfKing()
|
||||||
|
+ getDescription() : String
|
||||||
|
}
|
||||||
|
class ElfKingdomFactory {
|
||||||
|
+ ElfKingdomFactory()
|
||||||
|
+ createArmy() : Army
|
||||||
|
+ createCastle() : Castle
|
||||||
|
+ createKing() : King
|
||||||
|
}
|
||||||
|
interface King {
|
||||||
|
+ getDescription() : String {abstract}
|
||||||
|
}
|
||||||
|
interface KingdomFactory {
|
||||||
|
+ createArmy() : Army {abstract}
|
||||||
|
+ createCastle() : Castle {abstract}
|
||||||
|
+ createKing() : King {abstract}
|
||||||
|
}
|
||||||
|
class OrcArmy {
|
||||||
|
~ DESCRIPTION : String {static}
|
||||||
|
+ OrcArmy()
|
||||||
|
+ getDescription() : String
|
||||||
|
}
|
||||||
|
class OrcCastle {
|
||||||
|
~ DESCRIPTION : String {static}
|
||||||
|
+ OrcCastle()
|
||||||
|
+ getDescription() : String
|
||||||
|
}
|
||||||
|
class OrcKing {
|
||||||
|
~ DESCRIPTION : String {static}
|
||||||
|
+ OrcKing()
|
||||||
|
+ getDescription() : String
|
||||||
|
}
|
||||||
|
class OrcKingdomFactory {
|
||||||
|
+ OrcKingdomFactory()
|
||||||
|
+ createArmy() : Army
|
||||||
|
+ createCastle() : Castle
|
||||||
|
+ createKing() : King
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KingdomType ..+ FactoryMaker
|
||||||
|
App --> "-castle" Castle
|
||||||
|
FactoryMaker ..+ App
|
||||||
|
App --> "-king" King
|
||||||
|
App --> "-army" Army
|
||||||
|
ElfArmy ..|> Army
|
||||||
|
ElfCastle ..|> Castle
|
||||||
|
ElfKing ..|> King
|
||||||
|
ElfKingdomFactory ..|> KingdomFactory
|
||||||
|
OrcArmy ..|> Army
|
||||||
|
OrcCastle ..|> Castle
|
||||||
|
OrcKing ..|> King
|
||||||
|
OrcKingdomFactory ..|> KingdomFactory
|
||||||
|
@enduml
|
@ -1,42 +1,56 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
<project
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
<modelVersion>4.0.0</modelVersion>
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
<parent>
|
||||||
THE SOFTWARE.
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
-->
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
</parent>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<artifactId>abstract-factory</artifactId>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<dependencies>
|
||||||
<parent>
|
<dependency>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<scope>test</scope>
|
||||||
</parent>
|
</dependency>
|
||||||
<artifactId>abstract-factory</artifactId>
|
</dependencies>
|
||||||
<dependencies>
|
<build>
|
||||||
<dependency>
|
<plugins>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<!-- Maven assembly plugin is invoked with default setting which we have
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
in parent pom and specifying the class having main method -->
|
||||||
<scope>test</scope>
|
<plugin>
|
||||||
</dependency>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
</dependencies>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.abstractfactory.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.iluwatar.abstractfactory {
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
@ -5,17 +5,18 @@ folder: acyclic-visitor
|
|||||||
permalink: /patterns/acyclic-visitor/
|
permalink: /patterns/acyclic-visitor/
|
||||||
categories: Behavioral
|
categories: Behavioral
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Extensibility
|
||||||
- Difficulty-Intermediate
|
|
||||||
---
|
---
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
Allow new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating the troublesome dependency cycles that are inherent to the GOF VISITOR Pattern.
|
Allow new functions to be added to existing class hierarchies without affecting those hierarchies, and without creating the troublesome dependency cycles that are inherent to the GOF VISITOR Pattern.
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
This pattern can be used:
|
This pattern can be used:
|
||||||
|
|
||||||
* When you need to add a new function to an existing hierarchy without the need to alter or affect that hierarchy.
|
* When you need to add a new function to an existing hierarchy without the need to alter or affect that hierarchy.
|
||||||
* When there are functions that operate upon a hierarchy, but which do not belong in the hierarchy itself. e.g. the ConfigureForDOS / ConfigureForUnix / ConfigureForX issue.
|
* When there are functions that operate upon a hierarchy, but which do not belong in the hierarchy itself. e.g. the ConfigureForDOS / ConfigureForUnix / ConfigureForX issue.
|
||||||
* When you need to perform very different operations on an object depending upon its type.
|
* When you need to perform very different operations on an object depending upon its type.
|
||||||
@ -24,11 +25,13 @@ This pattern can be used:
|
|||||||
|
|
||||||
## Consequences
|
## Consequences
|
||||||
The good:
|
The good:
|
||||||
|
|
||||||
* No dependency cycles between class hierarchies.
|
* No dependency cycles between class hierarchies.
|
||||||
* No need to recompile all the visitors if a new one is added.
|
* No need to recompile all the visitors if a new one is added.
|
||||||
* Does not cause compilation failure in existing visitors if class hierarchy has a new member.
|
* Does not cause compilation failure in existing visitors if class hierarchy has a new member.
|
||||||
|
|
||||||
The bad:
|
The bad:
|
||||||
|
|
||||||
* Violates the principle of least surprise or Liskov's Substitution principle by showing that it can accept all visitors but actually only being interested in particular visitors.
|
* Violates the principle of least surprise or Liskov's Substitution principle by showing that it can accept all visitors but actually only being interested in particular visitors.
|
||||||
* Parallel hierarchy of visitors has to be created for all members in visitable class hierarchy.
|
* Parallel hierarchy of visitors has to be created for all members in visitable class hierarchy.
|
||||||
|
|
||||||
|
53
acyclic-visitor/etc/acyclic-visitor.urm.puml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.acyclicvisitor {
|
||||||
|
interface AllModemVisitor {
|
||||||
|
}
|
||||||
|
class App {
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class ConfigureForDosVisitor {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ ConfigureForDosVisitor()
|
||||||
|
+ visit(hayes : Hayes)
|
||||||
|
+ visit(zoom : Zoom)
|
||||||
|
}
|
||||||
|
class ConfigureForUnixVisitor {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ ConfigureForUnixVisitor()
|
||||||
|
+ visit(zoom : Zoom)
|
||||||
|
}
|
||||||
|
class Hayes {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ Hayes()
|
||||||
|
+ accept(modemVisitor : ModemVisitor)
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
interface HayesVisitor {
|
||||||
|
+ visit(Hayes) {abstract}
|
||||||
|
}
|
||||||
|
abstract class Modem {
|
||||||
|
+ Modem()
|
||||||
|
+ accept(ModemVisitor) {abstract}
|
||||||
|
}
|
||||||
|
interface ModemVisitor {
|
||||||
|
}
|
||||||
|
class Zoom {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ Zoom()
|
||||||
|
+ accept(modemVisitor : ModemVisitor)
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
interface ZoomVisitor {
|
||||||
|
+ visit(Zoom) {abstract}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AllModemVisitor --|> ZoomVisitor
|
||||||
|
AllModemVisitor --|> HayesVisitor
|
||||||
|
ConfigureForDosVisitor ..|> AllModemVisitor
|
||||||
|
ConfigureForUnixVisitor ..|> ZoomVisitor
|
||||||
|
Hayes --|> Modem
|
||||||
|
HayesVisitor --|> ModemVisitor
|
||||||
|
Zoom --|> Modem
|
||||||
|
ZoomVisitor --|> ModemVisitor
|
||||||
|
@enduml
|
@ -1,38 +1,29 @@
|
|||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>acyclic-visitor</artifactId>
|
<artifactId>acyclic-visitor</artifactId>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@ -53,19 +44,40 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>uk.org.lidalia</groupId>
|
<groupId>uk.org.lidalia</groupId>
|
||||||
<artifactId>slf4j-test</artifactId>
|
<artifactId>slf4j-test</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.2.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-all</artifactId>
|
<artifactId>mockito-all</artifactId>
|
||||||
<version>1.9.5</version>
|
<version>1.10.19</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- Maven assembly plugin is invoked with default setting which we have
|
||||||
|
in parent pom and specifying the class having main method -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.acyclicvisitor.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.iluwatar.acyclicvisitor {
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
@ -5,9 +5,7 @@ folder: adapter
|
|||||||
permalink: /patterns/adapter/
|
permalink: /patterns/adapter/
|
||||||
categories: Structural
|
categories: Structural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Gang of Four
|
||||||
- Gang Of Four
|
|
||||||
- Difficulty-Beginner
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Also known as
|
## Also known as
|
||||||
@ -97,6 +95,9 @@ var captain = new Captain(new FishingBoatAdapter());
|
|||||||
captain.row();
|
captain.row();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Use the Adapter pattern when
|
Use the Adapter pattern when
|
||||||
|
|
||||||
@ -128,5 +129,7 @@ An object adapter
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
* [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)
|
||||||
* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
|
* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31)
|
||||||
|
* [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)
|
||||||
|
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)
|
||||||
|
BIN
adapter/etc/adapter.urm.png
Normal file
After Width: | Height: | Size: 25 KiB |
31
adapter/etc/adapter.urm.puml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.adapter {
|
||||||
|
class App {
|
||||||
|
- App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class Captain {
|
||||||
|
- rowingBoat : RowingBoat
|
||||||
|
+ Captain()
|
||||||
|
+ Captain(boat : RowingBoat)
|
||||||
|
~ row()
|
||||||
|
~ setRowingBoat(boat : RowingBoat)
|
||||||
|
}
|
||||||
|
~class FishingBoat {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
~ FishingBoat()
|
||||||
|
~ sail()
|
||||||
|
}
|
||||||
|
class FishingBoatAdapter {
|
||||||
|
- boat : FishingBoat
|
||||||
|
+ FishingBoatAdapter()
|
||||||
|
+ row()
|
||||||
|
}
|
||||||
|
interface RowingBoat {
|
||||||
|
+ row() {abstract}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FishingBoatAdapter --> "-boat" FishingBoat
|
||||||
|
Captain --> "-rowingBoat" RowingBoat
|
||||||
|
FishingBoatAdapter ..|> RowingBoat
|
||||||
|
@enduml
|
104
adapter/pom.xml
@ -1,47 +1,61 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
<project
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
<modelVersion>4.0.0</modelVersion>
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
<parent>
|
||||||
THE SOFTWARE.
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
-->
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
</parent>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<artifactId>adapter</artifactId>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<dependencies>
|
||||||
<parent>
|
<dependency>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<scope>test</scope>
|
||||||
</parent>
|
</dependency>
|
||||||
<artifactId>adapter</artifactId>
|
<dependency>
|
||||||
<dependencies>
|
<groupId>org.mockito</groupId>
|
||||||
<dependency>
|
<artifactId>mockito-core</artifactId>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<scope>test</scope>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
</dependency>
|
||||||
<scope>test</scope>
|
</dependencies>
|
||||||
</dependency>
|
<build>
|
||||||
<dependency>
|
<plugins>
|
||||||
<groupId>org.mockito</groupId>
|
<!-- Maven assembly plugin is invoked with default setting which we have
|
||||||
<artifactId>mockito-core</artifactId>
|
in parent pom and specifying the class having main method -->
|
||||||
<scope>test</scope>
|
<plugin>
|
||||||
</dependency>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
</dependencies>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.adapter.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -5,8 +5,7 @@ folder: aggregator-microservices
|
|||||||
permalink: /patterns/aggregator-microservices/
|
permalink: /patterns/aggregator-microservices/
|
||||||
categories: Architectural
|
categories: Architectural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Cloud distributed
|
||||||
- Spring
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
@ -18,6 +17,8 @@ More variations of the aggregator are:
|
|||||||
- Chained Microservice Design Pattern: In this case each microservice is dependent/ chained to a series
|
- Chained Microservice Design Pattern: In this case each microservice is dependent/ chained to a series
|
||||||
of other microservices.
|
of other microservices.
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
@ -26,4 +27,4 @@ Use the Aggregator Microservices pattern when you need a unified API for various
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Microservice Design Patterns](http://blog.arungupta.me/microservice-design-patterns/)
|
* [Microservice Design Patterns](http://web.archive.org/web/20190705163602/http://blog.arungupta.me/microservice-design-patterns/)
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.aggregator.microservices {
|
||||||
|
class Aggregator {
|
||||||
|
- informationClient : ProductInformationClient
|
||||||
|
- inventoryClient : ProductInventoryClient
|
||||||
|
+ Aggregator()
|
||||||
|
+ getProduct() : Product
|
||||||
|
}
|
||||||
|
class App {
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class Product {
|
||||||
|
- productInventories : int
|
||||||
|
- title : String
|
||||||
|
+ Product()
|
||||||
|
+ getProductInventories() : int
|
||||||
|
+ getTitle() : String
|
||||||
|
+ setProductInventories(productInventories : int)
|
||||||
|
+ setTitle(title : String)
|
||||||
|
}
|
||||||
|
interface ProductInformationClient {
|
||||||
|
+ getProductTitle() : String {abstract}
|
||||||
|
}
|
||||||
|
class ProductInformationClientImpl {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ ProductInformationClientImpl()
|
||||||
|
+ getProductTitle() : String
|
||||||
|
}
|
||||||
|
interface ProductInventoryClient {
|
||||||
|
+ getProductInventories() : Integer {abstract}
|
||||||
|
}
|
||||||
|
class ProductInventoryClientImpl {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ ProductInventoryClientImpl()
|
||||||
|
+ getProductInventories() : Integer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Aggregator --> "-informationClient" ProductInformationClient
|
||||||
|
Aggregator --> "-inventoryClient" ProductInventoryClient
|
||||||
|
ProductInformationClientImpl ..|> ProductInformationClient
|
||||||
|
ProductInventoryClientImpl ..|> ProductInventoryClient
|
||||||
|
@enduml
|
@ -1,73 +1,81 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>aggregator-microservices</artifactId>
|
<artifactId>aggregator-microservices</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>aggregator-service</artifactId>
|
<artifactId>aggregator-service</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-webmvc</artifactId>
|
<artifactId>spring-webmvc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>repackage</goal>
|
<goal>repackage</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
<!-- Maven assembly plugin is invoked with default setting which we have
|
||||||
</build>
|
in parent pom and specifying the class having main method -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.aggregator.microservices.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
@startuml
|
||||||
|
@enduml
|
@ -0,0 +1,12 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.information.microservice {
|
||||||
|
class InformationApplication {
|
||||||
|
+ InformationApplication()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class InformationController {
|
||||||
|
+ InformationController()
|
||||||
|
+ getProductTitle() : String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@enduml
|
@ -1,70 +1,76 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>aggregator-microservices</artifactId>
|
<artifactId>aggregator-microservices</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>information-microservice</artifactId>
|
<artifactId>information-microservice</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-webmvc</artifactId>
|
<artifactId>spring-webmvc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>repackage</goal>
|
<goal>repackage</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
<plugin>
|
||||||
</build>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.information.microservices.InformationApplication</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.inventory.microservice {
|
||||||
|
class InventoryApplication {
|
||||||
|
+ InventoryApplication()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class InventoryController {
|
||||||
|
+ InventoryController()
|
||||||
|
+ getProductInventories() : int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@enduml
|
@ -1,69 +1,75 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>aggregator-microservices</artifactId>
|
<artifactId>aggregator-microservices</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>inventory-microservice</artifactId>
|
<artifactId>inventory-microservice</artifactId>
|
||||||
|
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-webmvc</artifactId>
|
<artifactId>spring-webmvc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>repackage</goal>
|
<goal>repackage</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
<plugin>
|
||||||
</build>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.inventory.microservices.InventoryApplication</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>aggregator-microservices</artifactId>
|
<artifactId>aggregator-microservices</artifactId>
|
||||||
|
@ -5,8 +5,8 @@ folder: ambassador
|
|||||||
permalink: /patterns/ambassador/
|
permalink: /patterns/ambassador/
|
||||||
categories: Structural
|
categories: Structural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Decoupling
|
||||||
- Difficulty-Intermediate
|
- Cloud distributed
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
@ -23,8 +23,7 @@ In plain words
|
|||||||
|
|
||||||
Microsoft documentation states
|
Microsoft documentation states
|
||||||
|
|
||||||
> An ambassador service can be thought of as an out-of-process proxy that is co-located with the client.
|
> An ambassador service can be thought of as an out-of-process proxy that is co-located with the client. This pattern can be useful for offloading common client connectivity tasks such as monitoring, logging, routing, security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications, or other applications that are difficult to modify, in order to extend their networking capabilities. It can also enable a specialized team to implement those features.
|
||||||
This pattern can be useful for offloading common client connectivity tasks such as monitoring, logging, routing, security (such as TLS), and resiliency patterns in a language agnostic way. It is often used with legacy applications, or other applications that are difficult to modify, in order to extend their networking capabilities. It can also enable a specialized team to implement those features.
|
|
||||||
|
|
||||||
**Programmatic Example**
|
**Programmatic Example**
|
||||||
|
|
||||||
@ -150,6 +149,9 @@ public class App {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Ambassador is applicable when working with a legacy remote service that cannot
|
Ambassador is applicable when working with a legacy remote service that cannot
|
||||||
be modified or would be extremely difficult to modify. Connectivity features can
|
be modified or would be extremely difficult to modify. Connectivity features can
|
||||||
|
BIN
ambassador/etc/ambassador.urm.png
Normal file
After Width: | Height: | Size: 48 KiB |
47
ambassador/etc/ambassador.urm.puml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.ambassador.util {
|
||||||
|
interface RandomProvider {
|
||||||
|
+ random() : double {abstract}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
package com.iluwatar.ambassador {
|
||||||
|
class App {
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class Client {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- serviceAmbassador : ServiceAmbassador
|
||||||
|
+ Client()
|
||||||
|
~ useService(value : int) : long
|
||||||
|
}
|
||||||
|
class RemoteService {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- THRESHOLD : int {static}
|
||||||
|
- randomProvider : RandomProvider
|
||||||
|
- service : RemoteService {static}
|
||||||
|
- RemoteService()
|
||||||
|
~ RemoteService(randomProvider : RandomProvider)
|
||||||
|
+ doRemoteFunction(value : int) : long
|
||||||
|
~ getRemoteService() : RemoteService {static}
|
||||||
|
}
|
||||||
|
~interface RemoteServiceInterface {
|
||||||
|
+ FAILURE : int {static}
|
||||||
|
+ doRemoteFunction(int) : long {abstract}
|
||||||
|
}
|
||||||
|
class ServiceAmbassador {
|
||||||
|
- DELAY_MS : int {static}
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- RETRIES : int {static}
|
||||||
|
~ ServiceAmbassador()
|
||||||
|
- checkLatency(value : int) : long
|
||||||
|
+ doRemoteFunction(value : int) : long
|
||||||
|
- safeCall(value : int) : long
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RemoteService --> "-service" RemoteService
|
||||||
|
Client --> "-serviceAmbassador" ServiceAmbassador
|
||||||
|
RemoteService --> "-randomProvider" RandomProvider
|
||||||
|
RemoteService ..|> RemoteServiceInterface
|
||||||
|
ServiceAmbassador ..|> RemoteServiceInterface
|
||||||
|
@enduml
|
@ -1,43 +1,53 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>ambassador</artifactId>
|
<artifactId>ambassador</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.ambassador.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -5,26 +5,155 @@ folder: api-gateway
|
|||||||
permalink: /patterns/api-gateway/
|
permalink: /patterns/api-gateway/
|
||||||
categories: Architectural
|
categories: Architectural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Cloud distributed
|
||||||
- Difficulty-Intermediate
|
- Decoupling
|
||||||
- Spring
|
- Microservices
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
|
|
||||||
Aggregate calls to microservices in a single location: the API Gateway. The user makes a single
|
Aggregate calls to microservices in a single location: the API Gateway. The user makes a single call to the API Gateway,
|
||||||
call to the API Gateway, and the API Gateway then calls each relevant microservice.
|
and the API Gateway then calls each relevant microservice.
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
With the Microservices pattern, a client may need data from multiple different microservices. If the client called each
|
||||||
|
microservice directly, that could contribute to longer load times, since the client would have to make a network request
|
||||||
|
for each microservice called. Moreover, having the client call each microservice directly ties the client to that
|
||||||
|
microservice - if the internal implementations of the microservices change (for example, if two microservices are
|
||||||
|
combined sometime in the future) or if the location (host and port) of a microservice changes, then every client that
|
||||||
|
makes use of those microservices must be updated.
|
||||||
|
|
||||||
|
The intent of the API Gateway pattern is to alleviate some of these issues. In the API Gateway pattern, an additional
|
||||||
|
entity (the API Gateway) is placed between the client and the microservices. The job of the API Gateway is to aggregate
|
||||||
|
the calls to the microservices. Rather than the client calling each microservice individually, the client calls the
|
||||||
|
API Gateway a single time. The API Gateway then calls each of the microservices that the client needs.
|
||||||
|
|
||||||
|
Real world example
|
||||||
|
|
||||||
|
> We are implementing microservices and API Gateway pattern for an e-commerce site. In this system the API Gateway makes
|
||||||
|
calls to the Image and Price microservices.
|
||||||
|
|
||||||
|
In plain words
|
||||||
|
|
||||||
|
> For a system implemented using microservices architecture, API Gateway is the single entry point that aggregates the
|
||||||
|
calls to the individual microservices.
|
||||||
|
|
||||||
|
Wikipedia says
|
||||||
|
|
||||||
|
> API Gateway is a server that acts as an API front-end, receives API requests, enforces throttling and security
|
||||||
|
policies, passes requests to the back-end service and then passes the response back to the requester. A gateway often
|
||||||
|
includes a transformation engine to orchestrate and modify the requests and responses on the fly. A gateway can also
|
||||||
|
provide functionality such as collecting analytics data and providing caching. The gateway can provide functionality to
|
||||||
|
support authentication, authorization, security, audit and regulatory compliance.
|
||||||
|
|
||||||
|
**Programmatic Example**
|
||||||
|
|
||||||
|
This implementation shows what the API Gateway pattern could look like for an e-commerce site. The `ApiGateway` makes
|
||||||
|
calls to the Image and Price microservices using the `ImageClientImpl` and `PriceClientImpl` respectively. Customers
|
||||||
|
viewing the site on a desktop device can see both price information and an image of a product, so the `ApiGateway` calls
|
||||||
|
both of the microservices and aggregates the data in the `DesktopProduct` model. However, mobile users only see price
|
||||||
|
information; they do not see a product image. For mobile users, the `ApiGateway` only retrieves price information, which
|
||||||
|
it uses to populate the `MobileProduct`.
|
||||||
|
|
||||||
|
Here's the Image microservice implementation.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface ImageClient {
|
||||||
|
String getImagePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ImageClientImpl implements ImageClient {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getImagePath() {
|
||||||
|
var httpClient = HttpClient.newHttpClient();
|
||||||
|
var httpGet = HttpRequest.newBuilder()
|
||||||
|
.GET()
|
||||||
|
.uri(URI.create("http://localhost:50005/image-path"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
|
||||||
|
return httpResponse.body();
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here's the Price microservice implementation.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface PriceClient {
|
||||||
|
String getPrice();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PriceClientImpl implements PriceClient {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPrice() {
|
||||||
|
var httpClient = HttpClient.newHttpClient();
|
||||||
|
var httpGet = HttpRequest.newBuilder()
|
||||||
|
.GET()
|
||||||
|
.uri(URI.create("http://localhost:50006/price"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try {
|
||||||
|
var httpResponse = httpClient.send(httpGet, BodyHandlers.ofString());
|
||||||
|
return httpResponse.body();
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And here we can see how API Gateway maps the requests to the microservices.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ApiGateway {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ImageClient imageClient;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PriceClient priceClient;
|
||||||
|
|
||||||
|
@RequestMapping(path = "/desktop", method = RequestMethod.GET)
|
||||||
|
public DesktopProduct getProductDesktop() {
|
||||||
|
var desktopProduct = new DesktopProduct();
|
||||||
|
desktopProduct.setImagePath(imageClient.getImagePath());
|
||||||
|
desktopProduct.setPrice(priceClient.getPrice());
|
||||||
|
return desktopProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(path = "/mobile", method = RequestMethod.GET)
|
||||||
|
public MobileProduct getProductMobile() {
|
||||||
|
var mobileProduct = new MobileProduct();
|
||||||
|
mobileProduct.setPrice(priceClient.getPrice());
|
||||||
|
return mobileProduct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
|
|
||||||
Use the API Gateway pattern when
|
Use the API Gateway pattern when
|
||||||
|
|
||||||
* you're also using the Microservices pattern and need a single point of aggregation for your
|
* You're using microservices architecture and need a single point of aggregation for your microservice calls.
|
||||||
microservice calls
|
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [microservices.io - API Gateway](http://microservices.io/patterns/apigateway.html)
|
* [microservices.io - API Gateway](http://microservices.io/patterns/apigateway.html)
|
||||||
* [NGINX - Building Microservices: Using an API Gateway](https://www.nginx.com/blog/building-microservices-using-an-api-gateway/)
|
* [NGINX - Building Microservices: Using an API Gateway](https://www.nginx.com/blog/building-microservices-using-an-api-gateway/)
|
||||||
|
* [Microservices Patterns: With examples in Java](https://www.amazon.com/gp/product/1617294543/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617294543&linkId=ac7b6a57f866ac006a309d9086e8cfbd)
|
||||||
|
* [Building Microservices: Designing Fine-Grained Systems](https://www.amazon.com/gp/product/1491950358/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1491950358&linkId=4c95ca9831e05e3f0dadb08841d77bf1)
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.api.gateway {
|
||||||
|
class ApiGateway {
|
||||||
|
- imageClient : ImageClient
|
||||||
|
- priceClient : PriceClient
|
||||||
|
+ ApiGateway()
|
||||||
|
+ getProductDesktop() : DesktopProduct
|
||||||
|
+ getProductMobile() : MobileProduct
|
||||||
|
}
|
||||||
|
class App {
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class DesktopProduct {
|
||||||
|
- imagePath : String
|
||||||
|
- price : String
|
||||||
|
+ DesktopProduct()
|
||||||
|
+ getImagePath() : String
|
||||||
|
+ getPrice() : String
|
||||||
|
+ setImagePath(imagePath : String)
|
||||||
|
+ setPrice(price : String)
|
||||||
|
}
|
||||||
|
interface ImageClient {
|
||||||
|
+ getImagePath() : String {abstract}
|
||||||
|
}
|
||||||
|
class ImageClientImpl {
|
||||||
|
+ ImageClientImpl()
|
||||||
|
+ getImagePath() : String
|
||||||
|
}
|
||||||
|
class MobileProduct {
|
||||||
|
- price : String
|
||||||
|
+ MobileProduct()
|
||||||
|
+ getPrice() : String
|
||||||
|
+ setPrice(price : String)
|
||||||
|
}
|
||||||
|
interface PriceClient {
|
||||||
|
+ getPrice() : String {abstract}
|
||||||
|
}
|
||||||
|
class PriceClientImpl {
|
||||||
|
+ PriceClientImpl()
|
||||||
|
+ getPrice() : String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ApiGateway --> "-imageClient" ImageClient
|
||||||
|
ApiGateway --> "-priceClient" PriceClient
|
||||||
|
ImageClientImpl ..|> ImageClient
|
||||||
|
PriceClientImpl ..|> PriceClient
|
||||||
|
@enduml
|
@ -29,7 +29,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>api-gateway</artifactId>
|
<artifactId>api-gateway</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>api-gateway-service</artifactId>
|
<artifactId>api-gateway-service</artifactId>
|
||||||
@ -68,6 +68,21 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.api.gateway.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
2
api-gateway/etc/api-gateway.urm.puml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@startuml
|
||||||
|
@enduml
|
@ -0,0 +1,12 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.image.microservice {
|
||||||
|
class ImageApplication {
|
||||||
|
+ ImageApplication()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class ImageController {
|
||||||
|
+ ImageController()
|
||||||
|
+ getImagePath() : String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@enduml
|
@ -29,7 +29,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>api-gateway</artifactId>
|
<artifactId>api-gateway</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>image-microservice</artifactId>
|
<artifactId>image-microservice</artifactId>
|
||||||
@ -63,6 +63,21 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.image.microservice.ImageApplication</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>api-gateway</artifactId>
|
<artifactId>api-gateway</artifactId>
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.price.microservice {
|
||||||
|
class PriceApplication {
|
||||||
|
+ PriceApplication()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class PriceController {
|
||||||
|
+ PriceController()
|
||||||
|
+ getPrice() : String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@enduml
|
@ -29,7 +29,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>api-gateway</artifactId>
|
<artifactId>api-gateway</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
@ -65,6 +65,21 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.price.microservices.PriceApplication</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
30
arrange-act-assert/README.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
layout: pattern
|
||||||
|
title: Arrange/Act/Assert
|
||||||
|
folder: arrange-act-assert
|
||||||
|
permalink: /patterns/arrange-act-assert/
|
||||||
|
categories: Idiom
|
||||||
|
tags:
|
||||||
|
- Testing
|
||||||
|
---
|
||||||
|
|
||||||
|
## Also known as
|
||||||
|
Given/When/Then
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
The Arrange/Act/Assert (AAA) is a pattern for organizing unit tests.
|
||||||
|
It breaks tests down into three clear and distinct steps:
|
||||||
|
1. Arrange: Perform the setup and initialization required for the test.
|
||||||
|
2. Act: Take action(s) required for the test.
|
||||||
|
3. Assert: Verify the outcome(s) of the test.
|
||||||
|
|
||||||
|
## Applicability
|
||||||
|
Use Arrange/Act/Assert pattern when
|
||||||
|
|
||||||
|
* you need to structure your unit tests so they're easier to read, maintain, and enhance.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* [Arrange, Act, Assert: What is AAA Testing?](https://blog.ncrunch.net/post/arrange-act-assert-aaa-testing.aspx)
|
||||||
|
* [Bill Wake: 3A – Arrange, Act, Assert](https://xp123.com/articles/3a-arrange-act-assert/)
|
||||||
|
* [Martin Fowler: GivenWhenThen](https://martinfowler.com/bliki/GivenWhenThen.html)
|
11
arrange-act-assert/etc/arrange-act-assert.urm.puml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.arrangeactassert {
|
||||||
|
class Cash {
|
||||||
|
- amount : int
|
||||||
|
~ Cash(amount : int)
|
||||||
|
~ count() : int
|
||||||
|
~ minus(subtrahend : int) : boolean
|
||||||
|
~ plus(addend : int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@enduml
|
44
arrange-act-assert/pom.xml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License
|
||||||
|
Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>arrange-act-assert</artifactId>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.iluwatar.arrangeactassert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arrange/Act/Assert (AAA) is a unit test pattern. In this simple example, we have a ({@link Cash})
|
||||||
|
* object for plus, minus and counting amount.
|
||||||
|
*/
|
||||||
|
public class Cash {
|
||||||
|
|
||||||
|
private int amount;
|
||||||
|
|
||||||
|
Cash(int amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
//plus
|
||||||
|
void plus(int addend) {
|
||||||
|
amount += addend;
|
||||||
|
}
|
||||||
|
|
||||||
|
//minus
|
||||||
|
boolean minus(int subtrahend) {
|
||||||
|
if (amount >= subtrahend) {
|
||||||
|
amount -= subtrahend;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//count
|
||||||
|
int count() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.iluwatar.arrangeactassert;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. It is a way to structure your
|
||||||
|
* tests so they're easier to read, maintain and enhance.
|
||||||
|
*
|
||||||
|
* <p>It breaks tests down into three clear and distinct steps:
|
||||||
|
* <p>1. Arrange: Perform the setup and initialization required for the test.
|
||||||
|
* <p>2. Act: Take action(s) required for the test.
|
||||||
|
* <p>3. Assert: Verify the outcome(s) of the test.
|
||||||
|
*
|
||||||
|
* <p>This pattern has several significant benefits. It creates a clear separation between a test's
|
||||||
|
* setup, operations, and results. This structure makes the code easier to read and understand. If
|
||||||
|
* you place the steps in order and format your code to separate them, you can scan a test and
|
||||||
|
* quickly comprehend what it does.
|
||||||
|
*
|
||||||
|
* <p>It also enforces a certain degree of discipline when you write your tests. You have to think
|
||||||
|
* clearly about the three steps your test will perform. But it makes tests more natural to write at
|
||||||
|
* the same time since you already have an outline.
|
||||||
|
*
|
||||||
|
* <p>In ({@link CashAAATest}) we have four test methods. Each of them has only one reason to
|
||||||
|
* change and one reason to fail. In a large and complicated code base, tests that honor the single
|
||||||
|
* responsibility principle are much easier to troubleshoot.
|
||||||
|
*/
|
||||||
|
public class CashAAATest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlus() {
|
||||||
|
//Arrange
|
||||||
|
var cash = new Cash(3);
|
||||||
|
//Act
|
||||||
|
cash.plus(4);
|
||||||
|
//Assert
|
||||||
|
assertEquals(cash.count(), 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMinus() {
|
||||||
|
//Arrange
|
||||||
|
var cash = new Cash(8);
|
||||||
|
//Act
|
||||||
|
var result = cash.minus(5);
|
||||||
|
//Assert
|
||||||
|
assertTrue(result);
|
||||||
|
assertEquals(cash.count(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsufficientMinus() {
|
||||||
|
//Arrange
|
||||||
|
var cash = new Cash(1);
|
||||||
|
//Act
|
||||||
|
var result = cash.minus(6);
|
||||||
|
//Assert
|
||||||
|
assertFalse(result);
|
||||||
|
assertEquals(cash.count(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() {
|
||||||
|
//Arrange
|
||||||
|
var cash = new Cash(5);
|
||||||
|
//Act
|
||||||
|
cash.plus(6);
|
||||||
|
var result = cash.minus(3);
|
||||||
|
//Assert
|
||||||
|
assertTrue(result);
|
||||||
|
assertEquals(cash.count(), 8);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.iluwatar.arrangeactassert;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ({@link CashAAATest}) is an anti-example of AAA pattern. This test is functionally correct, but
|
||||||
|
* with the addition of new feature, it needs refactoring. There are an awful lot of steps in that
|
||||||
|
* test method, but it verifies the class' important behavior in just eleven lines. It violates the
|
||||||
|
* single responsibility principle. If this test method failed after a small code change, it might
|
||||||
|
* take some digging to discover why.
|
||||||
|
*/
|
||||||
|
public class CashAntiAAATest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCash() {
|
||||||
|
//initialize
|
||||||
|
var cash = new Cash(3);
|
||||||
|
//test plus
|
||||||
|
cash.plus(4);
|
||||||
|
assertEquals(cash.count(), 7);
|
||||||
|
//test minus
|
||||||
|
cash = new Cash(8);
|
||||||
|
assertTrue(cash.minus(5));
|
||||||
|
assertEquals(cash.count(), 3);
|
||||||
|
assertFalse(cash.minus(6));
|
||||||
|
assertEquals(cash.count(), 3);
|
||||||
|
//test update
|
||||||
|
cash.plus(5);
|
||||||
|
assertTrue(cash.minus(5));
|
||||||
|
assertEquals(cash.count(), 3);
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,6 @@ folder: async-method-invocation
|
|||||||
permalink: /patterns/async-method-invocation/
|
permalink: /patterns/async-method-invocation/
|
||||||
categories: Concurrency
|
categories: Concurrency
|
||||||
tags:
|
tags:
|
||||||
- Java
|
|
||||||
- Difficulty-Intermediate
|
|
||||||
- Functional
|
|
||||||
- Reactive
|
- Reactive
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -17,6 +14,7 @@ is not blocked while waiting results of tasks. The pattern provides parallel
|
|||||||
processing of multiple independent tasks and retrieving the results via
|
processing of multiple independent tasks and retrieving the results via
|
||||||
callbacks or waiting until everything is done.
|
callbacks or waiting until everything is done.
|
||||||
|
|
||||||
|
# Class diagram
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
|
51
async-method-invocation/etc/async-method-invocation.urm.puml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.async.method.invocation {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
- callback(name : String) : AsyncCallback<T> {static}
|
||||||
|
- lazyval(value : T, delayMillis : long) : Callable<T> {static}
|
||||||
|
- log(msg : String) {static}
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
interface AsyncCallback<T> {
|
||||||
|
+ onComplete(T, Optional<Exception>) {abstract}
|
||||||
|
}
|
||||||
|
interface AsyncExecutor {
|
||||||
|
+ endProcess(AsyncResult<T>) : T {abstract}
|
||||||
|
+ startProcess(Callable<T>) : AsyncResult<T> {abstract}
|
||||||
|
+ startProcess(Callable<T>, AsyncCallback<T>) : AsyncResult<T> {abstract}
|
||||||
|
}
|
||||||
|
interface AsyncResult<T> {
|
||||||
|
+ await() {abstract}
|
||||||
|
+ getValue() : T {abstract}
|
||||||
|
+ isCompleted() : boolean {abstract}
|
||||||
|
}
|
||||||
|
class ThreadAsyncExecutor {
|
||||||
|
- idx : AtomicInteger
|
||||||
|
+ ThreadAsyncExecutor()
|
||||||
|
+ endProcess(asyncResult : AsyncResult<T>) : T
|
||||||
|
+ startProcess(task : Callable<T>) : AsyncResult<T>
|
||||||
|
+ startProcess(task : Callable<T>, callback : AsyncCallback<T>) : AsyncResult<T>
|
||||||
|
}
|
||||||
|
-class CompletableResult<T> {
|
||||||
|
~ COMPLETED : int {static}
|
||||||
|
~ FAILED : int {static}
|
||||||
|
~ RUNNING : int {static}
|
||||||
|
~ callback : Optional<AsyncCallback<T>>
|
||||||
|
~ exception : Exception
|
||||||
|
~ lock : Object
|
||||||
|
~ state : int
|
||||||
|
~ value : T
|
||||||
|
~ CompletableResult<T>(callback : AsyncCallback<T>)
|
||||||
|
+ await()
|
||||||
|
+ getValue() : T
|
||||||
|
+ isCompleted() : boolean
|
||||||
|
~ setException(exception : Exception)
|
||||||
|
~ setValue(value : T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CompletableResult ..+ ThreadAsyncExecutor
|
||||||
|
ThreadAsyncExecutor ..|> AsyncExecutor
|
||||||
|
CompletableResult ..|> AsyncResult
|
||||||
|
@enduml
|
@ -1,52 +1,64 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
<project
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
<modelVersion>4.0.0</modelVersion>
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
<parent>
|
||||||
THE SOFTWARE.
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
-->
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
</parent>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<artifactId>async-method-invocation</artifactId>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<dependencies>
|
||||||
<parent>
|
<dependency>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<scope>test</scope>
|
||||||
</parent>
|
</dependency>
|
||||||
<artifactId>async-method-invocation</artifactId>
|
<dependency>
|
||||||
<dependencies>
|
<groupId>org.mockito</groupId>
|
||||||
<dependency>
|
<artifactId>mockito-core</artifactId>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<scope>test</scope>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
</dependency>
|
||||||
<scope>test</scope>
|
<dependency>
|
||||||
</dependency>
|
<groupId>junit</groupId>
|
||||||
<dependency>
|
<artifactId>junit</artifactId>
|
||||||
<groupId>org.mockito</groupId>
|
<scope>test</scope>
|
||||||
<artifactId>mockito-core</artifactId>
|
</dependency>
|
||||||
<scope>test</scope>
|
</dependencies>
|
||||||
</dependency>
|
<build>
|
||||||
<dependency>
|
<plugins>
|
||||||
<groupId>junit</groupId>
|
<plugin>
|
||||||
<artifactId>junit</artifactId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<scope>test</scope>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
</dependency>
|
<executions>
|
||||||
</dependencies>
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.async.method.invocation.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -5,14 +5,14 @@ folder: balking
|
|||||||
permalink: /patterns/balking/
|
permalink: /patterns/balking/
|
||||||
categories: Concurrency
|
categories: Concurrency
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Decoupling
|
||||||
- Difficulty-Beginner
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
Balking Pattern is used to prevent an object from executing certain code if it is an
|
Balking Pattern is used to prevent an object from executing certain code if it is an
|
||||||
incomplete or inappropriate state
|
incomplete or inappropriate state
|
||||||
|
|
||||||
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
|
30
balking/etc/balking.urm.puml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.balking {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
interface DelayProvider {
|
||||||
|
+ executeAfterDelay(long, TimeUnit, Runnable) {abstract}
|
||||||
|
}
|
||||||
|
class WashingMachine {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- delayProvider : DelayProvider
|
||||||
|
- washingMachineState : WashingMachineState
|
||||||
|
+ WashingMachine()
|
||||||
|
+ WashingMachine(delayProvider : DelayProvider)
|
||||||
|
+ endOfWashing()
|
||||||
|
+ getWashingMachineState() : WashingMachineState
|
||||||
|
+ wash()
|
||||||
|
}
|
||||||
|
enum WashingMachineState {
|
||||||
|
+ ENABLED {static}
|
||||||
|
+ WASHING {static}
|
||||||
|
+ valueOf(name : String) : WashingMachineState {static}
|
||||||
|
+ values() : WashingMachineState[] {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WashingMachine --> "-washingMachineState" WashingMachineState
|
||||||
|
WashingMachine --> "-delayProvider" DelayProvider
|
||||||
|
@enduml
|
@ -1,46 +1,54 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>balking</artifactId>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
|
|
||||||
|
<artifactId>balking</artifactId>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.balking.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -5,9 +5,7 @@ folder: bridge
|
|||||||
permalink: /patterns/bridge/
|
permalink: /patterns/bridge/
|
||||||
categories: Structural
|
categories: Structural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Gang of Four
|
||||||
- Gang Of Four
|
|
||||||
- Difficulty-Intermediate
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Also known as
|
## Also known as
|
||||||
@ -179,6 +177,9 @@ hammer.unwield();
|
|||||||
// The item's glow fades.
|
// The item's glow fades.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Use the Bridge pattern when
|
Use the Bridge pattern when
|
||||||
|
|
||||||
@ -193,4 +194,5 @@ Use the Bridge pattern when
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
* [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)
|
||||||
|
* [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)
|
||||||
|
BIN
bridge/etc/bridge.urm.png
Normal file
After Width: | Height: | Size: 43 KiB |
58
bridge/etc/bridge.urm.puml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.bridge {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
interface Enchantment {
|
||||||
|
+ apply() {abstract}
|
||||||
|
+ onActivate() {abstract}
|
||||||
|
+ onDeactivate() {abstract}
|
||||||
|
}
|
||||||
|
class FlyingEnchantment {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ FlyingEnchantment()
|
||||||
|
+ apply()
|
||||||
|
+ onActivate()
|
||||||
|
+ onDeactivate()
|
||||||
|
}
|
||||||
|
class Hammer {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- enchantment : Enchantment
|
||||||
|
+ Hammer(enchantment : Enchantment)
|
||||||
|
+ getEnchantment() : Enchantment
|
||||||
|
+ swing()
|
||||||
|
+ unwield()
|
||||||
|
+ wield()
|
||||||
|
}
|
||||||
|
class SoulEatingEnchantment {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ SoulEatingEnchantment()
|
||||||
|
+ apply()
|
||||||
|
+ onActivate()
|
||||||
|
+ onDeactivate()
|
||||||
|
}
|
||||||
|
class Sword {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- enchantment : Enchantment
|
||||||
|
+ Sword(enchantment : Enchantment)
|
||||||
|
+ getEnchantment() : Enchantment
|
||||||
|
+ swing()
|
||||||
|
+ unwield()
|
||||||
|
+ wield()
|
||||||
|
}
|
||||||
|
interface Weapon {
|
||||||
|
+ getEnchantment() : Enchantment {abstract}
|
||||||
|
+ swing() {abstract}
|
||||||
|
+ unwield() {abstract}
|
||||||
|
+ wield() {abstract}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sword --> "-enchantment" Enchantment
|
||||||
|
Hammer --> "-enchantment" Enchantment
|
||||||
|
FlyingEnchantment ..|> Enchantment
|
||||||
|
Hammer ..|> Weapon
|
||||||
|
SoulEatingEnchantment ..|> Enchantment
|
||||||
|
Sword ..|> Weapon
|
||||||
|
@enduml
|
102
bridge/pom.xml
@ -1,47 +1,59 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
<project
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
<modelVersion>4.0.0</modelVersion>
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
<parent>
|
||||||
THE SOFTWARE.
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
-->
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
</parent>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<artifactId>bridge</artifactId>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<dependencies>
|
||||||
<parent>
|
<dependency>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<scope>test</scope>
|
||||||
</parent>
|
</dependency>
|
||||||
<artifactId>bridge</artifactId>
|
<dependency>
|
||||||
<dependencies>
|
<groupId>org.mockito</groupId>
|
||||||
<dependency>
|
<artifactId>mockito-core</artifactId>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<scope>test</scope>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
</dependency>
|
||||||
<scope>test</scope>
|
</dependencies>
|
||||||
</dependency>
|
<build>
|
||||||
<dependency>
|
<plugins>
|
||||||
<groupId>org.mockito</groupId>
|
<plugin>
|
||||||
<artifactId>mockito-core</artifactId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<scope>test</scope>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
</dependency>
|
<executions>
|
||||||
</dependencies>
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.bridge.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -5,9 +5,7 @@ folder: builder
|
|||||||
permalink: /patterns/builder/
|
permalink: /patterns/builder/
|
||||||
categories: Creational
|
categories: Creational
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Gang of Four
|
||||||
- Gang Of Four
|
|
||||||
- Difficulty-Intermediate
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
@ -113,6 +111,9 @@ And then it can be used as:
|
|||||||
var mage = new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER).build();
|
var mage = new Hero.Builder(Profession.MAGE, "Riobard").withHairColor(HairColor.BLACK).withWeapon(Weapon.DAGGER).build();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Use the Builder pattern when
|
Use the Builder pattern when
|
||||||
|
|
||||||
@ -130,5 +131,7 @@ Use the Builder pattern when
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
* [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 (2nd Edition)](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)
|
* [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb)
|
||||||
|
* [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)
|
||||||
|
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)
|
||||||
|
BIN
builder/etc/builder.urm.png
Normal file
After Width: | Height: | Size: 93 KiB |
100
builder/etc/builder.urm.puml
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.builder {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
enum Armor {
|
||||||
|
+ CHAIN_MAIL {static}
|
||||||
|
+ CLOTHES {static}
|
||||||
|
+ LEATHER {static}
|
||||||
|
+ PLATE_MAIL {static}
|
||||||
|
- title : String
|
||||||
|
+ toString() : String
|
||||||
|
+ valueOf(name : String) : Armor {static}
|
||||||
|
+ values() : Armor[] {static}
|
||||||
|
}
|
||||||
|
enum HairColor {
|
||||||
|
+ BLACK {static}
|
||||||
|
+ BLOND {static}
|
||||||
|
+ BROWN {static}
|
||||||
|
+ RED {static}
|
||||||
|
+ WHITE {static}
|
||||||
|
+ toString() : String
|
||||||
|
+ valueOf(name : String) : HairColor {static}
|
||||||
|
+ values() : HairColor[] {static}
|
||||||
|
}
|
||||||
|
enum HairType {
|
||||||
|
+ BALD {static}
|
||||||
|
+ CURLY {static}
|
||||||
|
+ LONG_CURLY {static}
|
||||||
|
+ LONG_STRAIGHT {static}
|
||||||
|
+ SHORT {static}
|
||||||
|
- title : String
|
||||||
|
+ toString() : String
|
||||||
|
+ valueOf(name : String) : HairType {static}
|
||||||
|
+ values() : HairType[] {static}
|
||||||
|
}
|
||||||
|
class Hero {
|
||||||
|
- armor : Armor
|
||||||
|
- hairColor : HairColor
|
||||||
|
- hairType : HairType
|
||||||
|
- name : String
|
||||||
|
- profession : Profession
|
||||||
|
- weapon : Weapon
|
||||||
|
- Hero(builder : Builder)
|
||||||
|
+ getArmor() : Armor
|
||||||
|
+ getHairColor() : HairColor
|
||||||
|
+ getHairType() : HairType
|
||||||
|
+ getName() : String
|
||||||
|
+ getProfession() : Profession
|
||||||
|
+ getWeapon() : Weapon
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
class Builder {
|
||||||
|
- armor : Armor
|
||||||
|
- hairColor : HairColor
|
||||||
|
- hairType : HairType
|
||||||
|
- name : String
|
||||||
|
- profession : Profession
|
||||||
|
- weapon : Weapon
|
||||||
|
+ Builder(profession : Profession, name : String)
|
||||||
|
+ build() : Hero
|
||||||
|
+ withArmor(armor : Armor) : Builder
|
||||||
|
+ withHairColor(hairColor : HairColor) : Builder
|
||||||
|
+ withHairType(hairType : HairType) : Builder
|
||||||
|
+ withWeapon(weapon : Weapon) : Builder
|
||||||
|
}
|
||||||
|
enum Profession {
|
||||||
|
+ MAGE {static}
|
||||||
|
+ PRIEST {static}
|
||||||
|
+ THIEF {static}
|
||||||
|
+ WARRIOR {static}
|
||||||
|
+ toString() : String
|
||||||
|
+ valueOf(name : String) : Profession {static}
|
||||||
|
+ values() : Profession[] {static}
|
||||||
|
}
|
||||||
|
enum Weapon {
|
||||||
|
+ AXE {static}
|
||||||
|
+ BOW {static}
|
||||||
|
+ DAGGER {static}
|
||||||
|
+ SWORD {static}
|
||||||
|
+ WARHAMMER {static}
|
||||||
|
+ toString() : String
|
||||||
|
+ valueOf(name : String) : Weapon {static}
|
||||||
|
+ values() : Weapon[] {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Hero --> "-profession" Profession
|
||||||
|
Builder ..+ Hero
|
||||||
|
Hero --> "-armor" Armor
|
||||||
|
Builder --> "-hairColor" HairColor
|
||||||
|
Builder --> "-weapon" Weapon
|
||||||
|
Builder --> "-hairType" HairType
|
||||||
|
Hero --> "-hairColor" HairColor
|
||||||
|
Builder --> "-profession" Profession
|
||||||
|
Hero --> "-weapon" Weapon
|
||||||
|
Hero --> "-hairType" HairType
|
||||||
|
Builder --> "-armor" Armor
|
||||||
|
@enduml
|
@ -1,42 +1,54 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
<project
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
<modelVersion>4.0.0</modelVersion>
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
<parent>
|
||||||
THE SOFTWARE.
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
-->
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
</parent>
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<artifactId>builder</artifactId>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<dependencies>
|
||||||
<parent>
|
<dependency>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<scope>test</scope>
|
||||||
</parent>
|
</dependency>
|
||||||
<artifactId>builder</artifactId>
|
</dependencies>
|
||||||
<dependencies>
|
<build>
|
||||||
<dependency>
|
<plugins>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<plugin>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<scope>test</scope>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
</dependency>
|
<executions>
|
||||||
</dependencies>
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.builder.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -3,10 +3,9 @@ layout: pattern
|
|||||||
title: Business Delegate
|
title: Business Delegate
|
||||||
folder: business-delegate
|
folder: business-delegate
|
||||||
permalink: /patterns/business-delegate/
|
permalink: /patterns/business-delegate/
|
||||||
categories: Business Tier
|
categories: Structural
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Decoupling
|
||||||
- Difficulty-Intermediate
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
@ -15,6 +14,7 @@ presentation and business tiers. By using the pattern we gain loose coupling
|
|||||||
between the tiers and encapsulate knowledge about how to locate, connect to,
|
between the tiers and encapsulate knowledge about how to locate, connect to,
|
||||||
and interact with the business objects that make up the application.
|
and interact with the business objects that make up the application.
|
||||||
|
|
||||||
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
@ -26,4 +26,4 @@ Use the Business Delegate pattern when
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
|
* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31)
|
||||||
|
57
business-delegate/etc/business-delegate.urm.puml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.business.delegate {
|
||||||
|
class App {
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class BusinessDelegate {
|
||||||
|
- businessService : BusinessService
|
||||||
|
- lookupService : BusinessLookup
|
||||||
|
- serviceType : ServiceType
|
||||||
|
+ BusinessDelegate()
|
||||||
|
+ doTask()
|
||||||
|
+ setLookupService(businessLookup : BusinessLookup)
|
||||||
|
+ setServiceType(serviceType : ServiceType)
|
||||||
|
}
|
||||||
|
class BusinessLookup {
|
||||||
|
- ejbService : EjbService
|
||||||
|
- jmsService : JmsService
|
||||||
|
+ BusinessLookup()
|
||||||
|
+ getBusinessService(serviceType : ServiceType) : BusinessService
|
||||||
|
+ setEjbService(ejbService : EjbService)
|
||||||
|
+ setJmsService(jmsService : JmsService)
|
||||||
|
}
|
||||||
|
interface BusinessService {
|
||||||
|
+ doProcessing() {abstract}
|
||||||
|
}
|
||||||
|
class Client {
|
||||||
|
- businessDelegate : BusinessDelegate
|
||||||
|
+ Client(businessDelegate : BusinessDelegate)
|
||||||
|
+ doTask()
|
||||||
|
}
|
||||||
|
class EjbService {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ EjbService()
|
||||||
|
+ doProcessing()
|
||||||
|
}
|
||||||
|
class JmsService {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ JmsService()
|
||||||
|
+ doProcessing()
|
||||||
|
}
|
||||||
|
enum ServiceType {
|
||||||
|
+ EJB {static}
|
||||||
|
+ JMS {static}
|
||||||
|
+ valueOf(name : String) : ServiceType {static}
|
||||||
|
+ values() : ServiceType[] {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BusinessLookup --> "-ejbService" EjbService
|
||||||
|
BusinessDelegate --> "-serviceType" ServiceType
|
||||||
|
Client --> "-businessDelegate" BusinessDelegate
|
||||||
|
BusinessDelegate --> "-businessService" BusinessService
|
||||||
|
BusinessDelegate --> "-lookupService" BusinessLookup
|
||||||
|
BusinessLookup --> "-jmsService" JmsService
|
||||||
|
EjbService ..|> BusinessService
|
||||||
|
JmsService ..|> BusinessService
|
||||||
|
@enduml
|
@ -1,36 +1,28 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>business-delegate</artifactId>
|
<artifactId>business-delegate</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -45,4 +37,23 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.business.delegate.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.iluwatar.business.delegate {
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
@ -5,13 +5,15 @@ folder: bytecode
|
|||||||
permalink: /patterns/bytecode/
|
permalink: /patterns/bytecode/
|
||||||
categories: Behavioral
|
categories: Behavioral
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Game programming
|
||||||
- Difficulty-Beginner
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
Allows to encode behaviour as instructions for virtual machine.
|
Allows to encode behaviour as instructions for virtual machine.
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Use the Bytecode pattern when you have a lot of behavior you need to define and your
|
Use the Bytecode pattern when you have a lot of behavior you need to define and your
|
||||||
game’s implementation language isn’t a good fit because:
|
game’s implementation language isn’t a good fit because:
|
||||||
|
BIN
bytecode/etc/bytecode.urm.png
Normal file
After Width: | Height: | Size: 67 KiB |
69
bytecode/etc/bytecode.urm.puml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.bytecode {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
- interpretInstruction(instruction : String, vm : VirtualMachine) {static}
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
enum Instruction {
|
||||||
|
+ ADD {static}
|
||||||
|
+ DIVIDE {static}
|
||||||
|
+ GET_AGILITY {static}
|
||||||
|
+ GET_HEALTH {static}
|
||||||
|
+ GET_WISDOM {static}
|
||||||
|
+ LITERAL {static}
|
||||||
|
+ PLAY_SOUND {static}
|
||||||
|
+ SET_AGILITY {static}
|
||||||
|
+ SET_HEALTH {static}
|
||||||
|
+ SET_WISDOM {static}
|
||||||
|
+ SPAWN_PARTICLES {static}
|
||||||
|
- value : int
|
||||||
|
+ getInstruction(value : int) : Instruction {static}
|
||||||
|
+ getIntValue() : int
|
||||||
|
+ valueOf(name : String) : Instruction {static}
|
||||||
|
+ values() : Instruction[] {static}
|
||||||
|
}
|
||||||
|
class VirtualMachine {
|
||||||
|
- stack : Stack<Integer>
|
||||||
|
- wizards : Wizard[]
|
||||||
|
+ VirtualMachine()
|
||||||
|
+ execute(bytecode : int[])
|
||||||
|
+ getAgility(wizard : int) : int
|
||||||
|
+ getHealth(wizard : int) : int
|
||||||
|
+ getStack() : Stack<Integer>
|
||||||
|
+ getWisdom(wizard : int) : int
|
||||||
|
+ getWizards() : Wizard[]
|
||||||
|
+ setAgility(wizard : int, amount : int)
|
||||||
|
+ setHealth(wizard : int, amount : int)
|
||||||
|
+ setWisdom(wizard : int, amount : int)
|
||||||
|
}
|
||||||
|
class Wizard {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- agility : int
|
||||||
|
- health : int
|
||||||
|
- numberOfPlayedSounds : int
|
||||||
|
- numberOfSpawnedParticles : int
|
||||||
|
- wisdom : int
|
||||||
|
+ Wizard()
|
||||||
|
+ getAgility() : int
|
||||||
|
+ getHealth() : int
|
||||||
|
+ getNumberOfPlayedSounds() : int
|
||||||
|
+ getNumberOfSpawnedParticles() : int
|
||||||
|
+ getWisdom() : int
|
||||||
|
+ playSound()
|
||||||
|
+ setAgility(agility : int)
|
||||||
|
+ setHealth(health : int)
|
||||||
|
+ setWisdom(wisdom : int)
|
||||||
|
+ spawnParticles()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
package com.iluwatar.bytecode.util {
|
||||||
|
class InstructionConverterUtil {
|
||||||
|
+ InstructionConverterUtil()
|
||||||
|
+ convertToByteCode(instructions : String) : int[] {static}
|
||||||
|
- isValidInstruction(instruction : String) : boolean {static}
|
||||||
|
- isValidInt(value : String) : boolean {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@enduml
|
@ -1,45 +1,56 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!-- The MIT License Copyright © 2014-2019 Ilkka Seppälä Permission is hereby
|
||||||
|
granted, free of charge, to any person obtaining a copy of this software
|
||||||
The MIT License
|
and associated documentation files (the "Software"), to deal in the Software
|
||||||
Copyright © 2014-2019 Ilkka Seppälä
|
without restriction, including without limitation the rights to use, copy,
|
||||||
|
modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
subject to the following conditions: The above copyright notice and this
|
||||||
in the Software without restriction, including without limitation the rights
|
permission notice shall be included in all copies or substantial portions
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
furnished to do so, subject to the following conditions:
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||||
|
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
The above copyright notice and this permission notice shall be included in
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
all copies or substantial portions of the Software.
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE. -->
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>bytecode</artifactId>
|
<artifactId>bytecode</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.bytecode.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -3,11 +3,10 @@ layout: pattern
|
|||||||
title: Caching
|
title: Caching
|
||||||
folder: caching
|
folder: caching
|
||||||
permalink: /patterns/caching/
|
permalink: /patterns/caching/
|
||||||
categories: Other
|
categories: Behavioral
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Performance
|
||||||
- Difficulty-Intermediate
|
- Cloud distributed
|
||||||
- Performance
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
@ -15,6 +14,7 @@ To avoid expensive re-acquisition of resources by not releasing
|
|||||||
the resources immediately after their use. The resources retain their identity, are kept in some
|
the resources immediately after their use. The resources retain their identity, are kept in some
|
||||||
fast-access storage, and are re-used to avoid having to acquire them again.
|
fast-access storage, and are re-used to avoid having to acquire them again.
|
||||||
|
|
||||||
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
@ -26,4 +26,4 @@ Use the Caching pattern(s) when
|
|||||||
|
|
||||||
* [Write-through, write-around, write-back: Cache explained](http://www.computerweekly.com/feature/Write-through-write-around-write-back-Cache-explained)
|
* [Write-through, write-around, write-back: Cache explained](http://www.computerweekly.com/feature/Write-through-write-around-write-back-Cache-explained)
|
||||||
* [Read-Through, Write-Through, Write-Behind, and Refresh-Ahead Caching](https://docs.oracle.com/cd/E15357_01/coh.360/e15723/cache_rtwtwbra.htm#COHDG5177)
|
* [Read-Through, Write-Through, Write-Behind, and Refresh-Ahead Caching](https://docs.oracle.com/cd/E15357_01/coh.360/e15723/cache_rtwtwbra.htm#COHDG5177)
|
||||||
* [Cache-Aside](https://msdn.microsoft.com/en-us/library/dn589799.aspx)
|
* [Cache-Aside pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/cache-aside)
|
||||||
|
119
caching/etc/caching.urm.puml
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.caching.constants {
|
||||||
|
class CachingConstants {
|
||||||
|
+ ADD_INFO : String {static}
|
||||||
|
+ USER_ACCOUNT : String {static}
|
||||||
|
+ USER_ID : String {static}
|
||||||
|
+ USER_NAME : String {static}
|
||||||
|
+ CachingConstants()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
package com.iluwatar.caching {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
+ useCacheAsideStategy()
|
||||||
|
+ useReadAndWriteThroughStrategy()
|
||||||
|
+ useReadThroughAndWriteAroundStrategy()
|
||||||
|
+ useReadThroughAndWriteBehindStrategy()
|
||||||
|
}
|
||||||
|
class AppManager {
|
||||||
|
- cachingPolicy : CachingPolicy {static}
|
||||||
|
- AppManager()
|
||||||
|
+ find(userId : String) : UserAccount {static}
|
||||||
|
- findAside(userId : String) : UserAccount {static}
|
||||||
|
+ initCacheCapacity(capacity : int) {static}
|
||||||
|
+ initCachingPolicy(policy : CachingPolicy) {static}
|
||||||
|
+ initDb(useMongoDb : boolean) {static}
|
||||||
|
+ printCacheContent() : String {static}
|
||||||
|
+ save(userAccount : UserAccount) {static}
|
||||||
|
- saveAside(userAccount : UserAccount) {static}
|
||||||
|
}
|
||||||
|
class CacheStore {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- cache : LruCache {static}
|
||||||
|
- CacheStore()
|
||||||
|
+ clearCache() {static}
|
||||||
|
+ flushCache() {static}
|
||||||
|
+ get(userId : String) : UserAccount {static}
|
||||||
|
+ initCapacity(capacity : int) {static}
|
||||||
|
+ invalidate(userId : String) {static}
|
||||||
|
+ print() : String {static}
|
||||||
|
+ readThrough(userId : String) : UserAccount {static}
|
||||||
|
+ readThroughWithWriteBackPolicy(userId : String) : UserAccount {static}
|
||||||
|
+ set(userId : String, userAccount : UserAccount) {static}
|
||||||
|
+ writeAround(userAccount : UserAccount) {static}
|
||||||
|
+ writeBehind(userAccount : UserAccount) {static}
|
||||||
|
+ writeThrough(userAccount : UserAccount) {static}
|
||||||
|
}
|
||||||
|
enum CachingPolicy {
|
||||||
|
+ AROUND {static}
|
||||||
|
+ ASIDE {static}
|
||||||
|
+ BEHIND {static}
|
||||||
|
+ THROUGH {static}
|
||||||
|
- policy : String
|
||||||
|
+ getPolicy() : String
|
||||||
|
+ valueOf(name : String) : CachingPolicy {static}
|
||||||
|
+ values() : CachingPolicy[] {static}
|
||||||
|
}
|
||||||
|
class DbManager {
|
||||||
|
- db : MongoDatabase {static}
|
||||||
|
- mongoClient : MongoClient {static}
|
||||||
|
- useMongoDB : boolean {static}
|
||||||
|
- virtualDB : Map<String, UserAccount> {static}
|
||||||
|
- DbManager()
|
||||||
|
+ connect() {static}
|
||||||
|
+ createVirtualDb() {static}
|
||||||
|
+ readFromDb(userId : String) : UserAccount {static}
|
||||||
|
+ updateDb(userAccount : UserAccount) {static}
|
||||||
|
+ upsertDb(userAccount : UserAccount) {static}
|
||||||
|
+ writeToDb(userAccount : UserAccount) {static}
|
||||||
|
}
|
||||||
|
class LruCache {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
~ cache : Map<String, Node>
|
||||||
|
~ capacity : int
|
||||||
|
~ end : Node
|
||||||
|
~ head : Node
|
||||||
|
+ LruCache(capacity : int)
|
||||||
|
+ clear()
|
||||||
|
+ contains(userId : String) : boolean
|
||||||
|
+ get(userId : String) : UserAccount
|
||||||
|
+ getCacheDataInListForm() : List<UserAccount>
|
||||||
|
+ getLruData() : UserAccount
|
||||||
|
+ invalidate(userId : String)
|
||||||
|
+ isFull() : boolean
|
||||||
|
+ remove(node : Node)
|
||||||
|
+ set(userId : String, userAccount : UserAccount)
|
||||||
|
+ setCapacity(newCapacity : int)
|
||||||
|
+ setHead(node : Node)
|
||||||
|
}
|
||||||
|
~class Node {
|
||||||
|
~ next : Node
|
||||||
|
~ previous : Node
|
||||||
|
~ userAccount : UserAccount
|
||||||
|
~ userId : String
|
||||||
|
+ Node(this$0 : String, userId : UserAccount)
|
||||||
|
}
|
||||||
|
class UserAccount {
|
||||||
|
- additionalInfo : String
|
||||||
|
- userId : String
|
||||||
|
- userName : String
|
||||||
|
+ UserAccount(userId : String, userName : String, additionalInfo : String)
|
||||||
|
+ getAdditionalInfo() : String
|
||||||
|
+ getUserId() : String
|
||||||
|
+ getUserName() : String
|
||||||
|
+ setAdditionalInfo(additionalInfo : String)
|
||||||
|
+ setUserId(userId : String)
|
||||||
|
+ setUserName(userName : String)
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Node --+ LruCache
|
||||||
|
LruCache --> "-head" Node
|
||||||
|
Node --> "-previous" Node
|
||||||
|
AppManager --> "-cachingPolicy" CachingPolicy
|
||||||
|
Node --> "-userAccount" UserAccount
|
||||||
|
CacheStore --> "-cache" LruCache
|
||||||
|
@enduml
|
@ -29,7 +29,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>caching</artifactId>
|
<artifactId>caching</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mongodb</groupId>
|
<groupId>org.mongodb</groupId>
|
||||||
<artifactId>mongodb-driver</artifactId>
|
<artifactId>mongodb-driver</artifactId>
|
||||||
<version>3.0.4</version>
|
<version>3.12.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mongodb</groupId>
|
<groupId>org.mongodb</groupId>
|
||||||
@ -69,6 +69,21 @@
|
|||||||
<skipTests>false</skipTests>
|
<skipTests>false</skipTests>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.caching.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -3,19 +3,72 @@ layout: pattern
|
|||||||
title: Callback
|
title: Callback
|
||||||
folder: callback
|
folder: callback
|
||||||
permalink: /patterns/callback/
|
permalink: /patterns/callback/
|
||||||
categories: Other
|
categories: Idiom
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Reactive
|
||||||
- Difficulty-Beginner
|
|
||||||
- Functional
|
|
||||||
- Idiom
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
Callback is a piece of executable code that is passed as an
|
Callback is a piece of executable code that is passed as an argument to other code, which is expected to call back
|
||||||
argument to other code, which is expected to call back (execute) the argument
|
(execute) the argument at some convenient time.
|
||||||
at some convenient time.
|
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
Real world example
|
||||||
|
|
||||||
|
> 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.
|
||||||
|
|
||||||
|
In plain words
|
||||||
|
|
||||||
|
> Callback is a method passed to the executor which will be called at defined moment.
|
||||||
|
|
||||||
|
Wikipedia says
|
||||||
|
|
||||||
|
> 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.
|
||||||
|
|
||||||
|
**Programmatic Example**
|
||||||
|
|
||||||
|
Callback is a simple interface with single method.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface Callback {
|
||||||
|
|
||||||
|
void call();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Next we define a task that will execute the callback after the task execution has finished.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public abstract class Task {
|
||||||
|
|
||||||
|
final void executeWith(Callback callback) {
|
||||||
|
execute();
|
||||||
|
Optional.ofNullable(callback).ifPresent(Callback::call);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class SimpleTask extends Task {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = getLogger(SimpleTask.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
LOGGER.info("Perform some important activity and after call the callback method.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally here's how we execute a task and receive a callback when it's finished.
|
||||||
|
|
||||||
|
```java
|
||||||
|
var task = new SimpleTask();
|
||||||
|
task.executeWith(() -> LOGGER.info("I'm done now."));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
|
28
callback/etc/callback.urm.puml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.callback {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
interface Callback {
|
||||||
|
+ call() {abstract}
|
||||||
|
}
|
||||||
|
class LambdasApp {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- LambdasApp()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class SimpleTask {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ SimpleTask()
|
||||||
|
+ execute()
|
||||||
|
}
|
||||||
|
abstract class Task {
|
||||||
|
+ Task()
|
||||||
|
+ execute() {abstract}
|
||||||
|
~ executeWith(callback : Callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SimpleTask --|> Task
|
||||||
|
@enduml
|
@ -29,7 +29,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>callback</artifactId>
|
<artifactId>callback</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -39,4 +39,23 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.callback.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -33,7 +33,7 @@ public abstract class Task {
|
|||||||
/**
|
/**
|
||||||
* Execute with callback.
|
* Execute with callback.
|
||||||
*/
|
*/
|
||||||
final void executeWith(final Callback callback) {
|
final void executeWith(Callback callback) {
|
||||||
execute();
|
execute();
|
||||||
Optional.ofNullable(callback).ifPresent(Callback::call);
|
Optional.ofNullable(callback).ifPresent(Callback::call);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.iluwatar.callback {
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
@ -5,9 +5,7 @@ folder: chain
|
|||||||
permalink: /patterns/chain/
|
permalink: /patterns/chain/
|
||||||
categories: Behavioral
|
categories: Behavioral
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Gang of Four
|
||||||
- Gang Of Four
|
|
||||||
- Difficulty-Intermediate
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
@ -141,6 +139,9 @@ king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner"));
|
|||||||
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); // Orc soldier handling request "collect tax"
|
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); // Orc soldier handling request "collect tax"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Use Chain of Responsibility when
|
Use Chain of Responsibility when
|
||||||
|
|
||||||
@ -156,4 +157,5 @@ Use Chain of Responsibility when
|
|||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
* [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)
|
||||||
|
* [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)
|
||||||
|
BIN
chain/etc/chain.urm.png
Normal file
After Width: | Height: | Size: 59 KiB |
61
chain/etc/chain.urm.puml
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.chain {
|
||||||
|
class App {
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class OrcCommander {
|
||||||
|
+ OrcCommander(handler : RequestHandler)
|
||||||
|
+ handleRequest(req : Request)
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
class OrcKing {
|
||||||
|
- chain : RequestHandler
|
||||||
|
+ OrcKing()
|
||||||
|
- buildChain()
|
||||||
|
+ makeRequest(req : Request)
|
||||||
|
}
|
||||||
|
class OrcOfficer {
|
||||||
|
+ OrcOfficer(handler : RequestHandler)
|
||||||
|
+ handleRequest(req : Request)
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
class OrcSoldier {
|
||||||
|
+ OrcSoldier(handler : RequestHandler)
|
||||||
|
+ handleRequest(req : Request)
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
class Request {
|
||||||
|
- handled : boolean
|
||||||
|
- requestDescription : String
|
||||||
|
- requestType : RequestType
|
||||||
|
+ Request(requestType : RequestType, requestDescription : String)
|
||||||
|
+ getRequestDescription() : String
|
||||||
|
+ getRequestType() : RequestType
|
||||||
|
+ isHandled() : boolean
|
||||||
|
+ markHandled()
|
||||||
|
+ toString() : String
|
||||||
|
}
|
||||||
|
abstract class RequestHandler {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
- next : RequestHandler
|
||||||
|
+ RequestHandler(next : RequestHandler)
|
||||||
|
+ handleRequest(req : Request)
|
||||||
|
# printHandling(req : Request)
|
||||||
|
+ toString() : String {abstract}
|
||||||
|
}
|
||||||
|
enum RequestType {
|
||||||
|
+ COLLECT_TAX {static}
|
||||||
|
+ DEFEND_CASTLE {static}
|
||||||
|
+ TORTURE_PRISONER {static}
|
||||||
|
+ valueOf(name : String) : RequestType {static}
|
||||||
|
+ values() : RequestType[] {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OrcKing --> "-chain" RequestHandler
|
||||||
|
RequestHandler --> "-next" RequestHandler
|
||||||
|
Request --> "-requestType" RequestType
|
||||||
|
OrcCommander --|> RequestHandler
|
||||||
|
OrcOfficer --|> RequestHandler
|
||||||
|
OrcSoldier --|> RequestHandler
|
||||||
|
@enduml
|
@ -29,7 +29,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>chain</artifactId>
|
<artifactId>chain</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -39,4 +39,23 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.chain.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
26
chain/src/main/java/com/iluwatar/chain/module-info.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.iluwatar.chain {
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
@ -3,11 +3,11 @@ layout: pattern
|
|||||||
title: Circuit Breaker
|
title: Circuit Breaker
|
||||||
folder: circuit-breaker
|
folder: circuit-breaker
|
||||||
permalink: /patterns/circuit-breaker/
|
permalink: /patterns/circuit-breaker/
|
||||||
categories: Other
|
categories: Behavioral
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Performance
|
||||||
- Performance
|
- Decoupling
|
||||||
- Difficulty-Intermediate
|
- Cloud distributed
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
@ -165,6 +165,8 @@ How does the above pattern prevent failures? Let's understand via this finite st
|
|||||||
- 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```)
|
- 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```)
|
||||||
- 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.
|
- 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.
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Use the Circuit Breaker pattern when
|
Use the Circuit Breaker pattern when
|
||||||
@ -177,6 +179,7 @@ Use the Circuit Breaker pattern when
|
|||||||
- [Retry Pattern](https://github.com/iluwatar/java-design-patterns/tree/master/retry)
|
- [Retry Pattern](https://github.com/iluwatar/java-design-patterns/tree/master/retry)
|
||||||
|
|
||||||
## Real world examples
|
## Real world examples
|
||||||
|
|
||||||
* [Spring Circuit Breaker module](https://spring.io/guides/gs/circuit-breaker)
|
* [Spring Circuit Breaker module](https://spring.io/guides/gs/circuit-breaker)
|
||||||
* [Netflix Hystrix API](https://github.com/Netflix/Hystrix)
|
* [Netflix Hystrix API](https://github.com/Netflix/Hystrix)
|
||||||
|
|
||||||
@ -185,4 +188,4 @@ Use the Circuit Breaker pattern when
|
|||||||
* [Understanding Circuit Breaker Pattern](https://itnext.io/understand-circuitbreaker-design-pattern-with-simple-practical-example-92a752615b42)
|
* [Understanding Circuit Breaker Pattern](https://itnext.io/understand-circuitbreaker-design-pattern-with-simple-practical-example-92a752615b42)
|
||||||
* [Martin Fowler on Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html)
|
* [Martin Fowler on Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html)
|
||||||
* [Fault tolerance in a high volume, distributed system](https://medium.com/netflix-techblog/fault-tolerance-in-a-high-volume-distributed-system-91ab4faae74a)
|
* [Fault tolerance in a high volume, distributed system](https://medium.com/netflix-techblog/fault-tolerance-in-a-high-volume-distributed-system-91ab4faae74a)
|
||||||
* [Microsoft docs](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker)
|
* [Circuit Breaker pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker)
|
||||||
|
BIN
circuit-breaker/etc/circuit-breaker.urm.png
Normal file
After Width: | Height: | Size: 44 KiB |
44
circuit-breaker/etc/circuit-breaker.urm.puml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.circuitbreaker {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class CircuitBreaker {
|
||||||
|
~ failureCount : int
|
||||||
|
- failureThreshold : int
|
||||||
|
- futureTime : long
|
||||||
|
~ lastFailureTime : long
|
||||||
|
- retryTimePeriod : long
|
||||||
|
- state : State
|
||||||
|
- timeout : long
|
||||||
|
~ CircuitBreaker(timeout : long, failureThreshold : int, retryTimePeriod : long)
|
||||||
|
+ call(serviceToCall : String, serverStartTime : long) : String
|
||||||
|
+ getState() : String
|
||||||
|
- recordFailure()
|
||||||
|
- reset()
|
||||||
|
# setState()
|
||||||
|
+ setStateForBypass(state : State)
|
||||||
|
}
|
||||||
|
class DelayedService {
|
||||||
|
- delay : int
|
||||||
|
+ DelayedService()
|
||||||
|
+ DelayedService(delay : int)
|
||||||
|
+ response(serverStartTime : long) : String
|
||||||
|
}
|
||||||
|
class MonitoringService {
|
||||||
|
+ MonitoringService()
|
||||||
|
+ localResourceResponse() : String
|
||||||
|
+ remoteResourceResponse(circuitBreaker : CircuitBreaker, serverStartTime : long) : String
|
||||||
|
}
|
||||||
|
enum State {
|
||||||
|
+ CLOSED {static}
|
||||||
|
+ HALF_OPEN {static}
|
||||||
|
+ OPEN {static}
|
||||||
|
+ valueOf(name : String) : State {static}
|
||||||
|
+ values() : State[] {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CircuitBreaker --> "-state" State
|
||||||
|
@enduml
|
@ -27,7 +27,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>circuit-breaker</artifactId>
|
<artifactId>circuit-breaker</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -37,4 +37,23 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.circuitbreaker.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -3,17 +3,16 @@ layout: pattern
|
|||||||
title: Collection Pipeline
|
title: Collection Pipeline
|
||||||
folder: collection-pipeline
|
folder: collection-pipeline
|
||||||
permalink: /patterns/collection-pipeline/
|
permalink: /patterns/collection-pipeline/
|
||||||
categories: Other
|
categories: Functional
|
||||||
tags:
|
tags:
|
||||||
- Java
|
- Reactive
|
||||||
- Difficulty-Beginner
|
|
||||||
- Functional
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
Collection Pipeline introduces Function Composition and Collection Pipeline, two functional-style patterns that you can combine to iterate collections in your code.
|
Collection Pipeline introduces Function Composition and Collection Pipeline, two functional-style patterns that you can combine to iterate collections in your code.
|
||||||
In functional programming, it's common to sequence complex operations through a series of smaller modular functions or operations. The series is called a composition of functions, or a function composition. When a collection of data flows through a function composition, it becomes a collection pipeline. Function Composition and Collection Pipeline are two design patterns frequently used in functional-style programming.
|
In functional programming, it's common to sequence complex operations through a series of smaller modular functions or operations. The series is called a composition of functions, or a function composition. When a collection of data flows through a function composition, it becomes a collection pipeline. Function Composition and Collection Pipeline are two design patterns frequently used in functional-style programming.
|
||||||
|
|
||||||
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
@ -27,4 +26,4 @@ Use the Collection Pipeline pattern when
|
|||||||
|
|
||||||
* [Function composition and the Collection Pipeline pattern](https://www.ibm.com/developerworks/library/j-java8idioms2/index.html)
|
* [Function composition and the Collection Pipeline pattern](https://www.ibm.com/developerworks/library/j-java8idioms2/index.html)
|
||||||
* [Martin Fowler](https://martinfowler.com/articles/collection-pipeline/)
|
* [Martin Fowler](https://martinfowler.com/articles/collection-pipeline/)
|
||||||
* [Java8 Streams](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html)
|
* [Java8 Streams](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html)
|
||||||
|
52
collection-pipeline/etc/collection-pipeline.urm.puml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.collectionpipeline {
|
||||||
|
class App {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ App()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
}
|
||||||
|
class Car {
|
||||||
|
- category : Category
|
||||||
|
- make : String
|
||||||
|
- model : String
|
||||||
|
- year : int
|
||||||
|
+ Car(make : String, model : String, yearOfMake : int, category : Category)
|
||||||
|
+ equals(obj : Object) : boolean
|
||||||
|
+ getCategory() : Category
|
||||||
|
+ getMake() : String
|
||||||
|
+ getModel() : String
|
||||||
|
+ getYear() : int
|
||||||
|
+ hashCode() : int
|
||||||
|
}
|
||||||
|
class CarFactory {
|
||||||
|
- CarFactory()
|
||||||
|
+ createCars() : List<Car> {static}
|
||||||
|
}
|
||||||
|
enum Category {
|
||||||
|
+ CONVERTIBLE {static}
|
||||||
|
+ JEEP {static}
|
||||||
|
+ SEDAN {static}
|
||||||
|
+ valueOf(name : String) : Category {static}
|
||||||
|
+ values() : Category[] {static}
|
||||||
|
}
|
||||||
|
class FunctionalProgramming {
|
||||||
|
- FunctionalProgramming()
|
||||||
|
+ getGroupingOfCarsByCategory(cars : List<Car>) : Map<Category, List<Car>> {static}
|
||||||
|
+ getModelsAfter2000(cars : List<Car>) : List<String> {static}
|
||||||
|
+ getSedanCarsOwnedSortedByDate(persons : List<Person>) : List<Car> {static}
|
||||||
|
}
|
||||||
|
class ImperativeProgramming {
|
||||||
|
- ImperativeProgramming()
|
||||||
|
+ getGroupingOfCarsByCategory(cars : List<Car>) : Map<Category, List<Car>> {static}
|
||||||
|
+ getModelsAfter2000(cars : List<Car>) : List<String> {static}
|
||||||
|
+ getSedanCarsOwnedSortedByDate(persons : List<Person>) : List<Car> {static}
|
||||||
|
}
|
||||||
|
class Person {
|
||||||
|
- cars : List<Car>
|
||||||
|
+ Person(cars : List<Car>)
|
||||||
|
+ getCars() : List<Car>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Person --> "-cars" Car
|
||||||
|
Car --> "-category" Category
|
||||||
|
@enduml
|
@ -27,7 +27,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.iluwatar</groupId>
|
<groupId>com.iluwatar</groupId>
|
||||||
<artifactId>java-design-patterns</artifactId>
|
<artifactId>java-design-patterns</artifactId>
|
||||||
<version>1.22.0-SNAPSHOT</version>
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>collection-pipeline</artifactId>
|
<artifactId>collection-pipeline</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -37,4 +37,23 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.iluwatar.collectionpipeline.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
|
|
||||||
package com.iluwatar.collectionpipeline;
|
package com.iluwatar.collectionpipeline;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imperative-style programming to iterate over the list and get the names of cars made later than
|
* Imperative-style programming to iterate over the list and get the names of cars made later than
|
||||||
@ -57,11 +57,27 @@ public class ImperativeProgramming {
|
|||||||
* @return {@link List} of {@link String} of car models built after year 2000
|
* @return {@link List} of {@link String} of car models built after year 2000
|
||||||
*/
|
*/
|
||||||
public static List<String> getModelsAfter2000(List<Car> cars) {
|
public static List<String> getModelsAfter2000(List<Car> cars) {
|
||||||
return cars.stream()
|
List<Car> carsSortedByYear = new ArrayList<>();
|
||||||
.filter(car -> car.getYear() > 2000)
|
|
||||||
.sorted(Comparator.comparingInt(Car::getYear))
|
for (Car car : cars) {
|
||||||
.map(Car::getModel)
|
if (car.getYear() > 2000) {
|
||||||
.collect(Collectors.toList());
|
carsSortedByYear.add(car);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(carsSortedByYear, new Comparator<Car>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Car car1, Car car2) {
|
||||||
|
return car1.getYear() - car2.getYear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
List<String> models = new ArrayList<>();
|
||||||
|
for (Car car : carsSortedByYear) {
|
||||||
|
models.add(car.getModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,7 +87,17 @@ public class ImperativeProgramming {
|
|||||||
* @return {@link Map} with category as key and cars belonging to that category as value
|
* @return {@link Map} with category as key and cars belonging to that category as value
|
||||||
*/
|
*/
|
||||||
public static Map<Category, List<Car>> getGroupingOfCarsByCategory(List<Car> cars) {
|
public static Map<Category, List<Car>> getGroupingOfCarsByCategory(List<Car> cars) {
|
||||||
return cars.stream().collect(Collectors.groupingBy(Car::getCategory));
|
Map<Category, List<Car>> groupingByCategory = new HashMap<>();
|
||||||
|
for (Car car : cars) {
|
||||||
|
if (groupingByCategory.containsKey(car.getCategory())) {
|
||||||
|
groupingByCategory.get(car.getCategory()).add(car);
|
||||||
|
} else {
|
||||||
|
List<Car> categoryCars = new ArrayList<>();
|
||||||
|
categoryCars.add(car);
|
||||||
|
groupingByCategory.put(car.getCategory(), categoryCars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groupingByCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,11 +108,25 @@ public class ImperativeProgramming {
|
|||||||
* @return {@link List} of {@link Car} to belonging to the group
|
* @return {@link List} of {@link Car} to belonging to the group
|
||||||
*/
|
*/
|
||||||
public static List<Car> getSedanCarsOwnedSortedByDate(List<Person> persons) {
|
public static List<Car> getSedanCarsOwnedSortedByDate(List<Person> persons) {
|
||||||
return persons.stream()
|
List<Car> cars = new ArrayList<>();
|
||||||
.map(Person::getCars)
|
for (Person person : persons) {
|
||||||
.flatMap(Collection::stream)
|
cars.addAll(person.getCars());
|
||||||
.filter(car -> car.getCategory() == Category.SEDAN)
|
}
|
||||||
.sorted(Comparator.comparingInt(Car::getYear))
|
|
||||||
.collect(Collectors.toList());
|
List<Car> sedanCars = new ArrayList<>();
|
||||||
|
for (Car car : cars) {
|
||||||
|
if (Category.SEDAN.equals(car.getCategory())) {
|
||||||
|
sedanCars.add(car);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sedanCars.sort(new Comparator<Car>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Car o1, Car o2) {
|
||||||
|
return o1.getYear() - o2.getYear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return sedanCars;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module com.iluwatar.collectionpipeline {
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
36
combinator/README.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
layout: pattern
|
||||||
|
title: Combinator
|
||||||
|
folder: combinator
|
||||||
|
permalink: /patterns/combinator/
|
||||||
|
categories: Idiom
|
||||||
|
tags:
|
||||||
|
- Reactive
|
||||||
|
---
|
||||||
|
|
||||||
|
## Also known as
|
||||||
|
Composition pattern
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
The functional pattern representing a style of organizing libraries centered around the idea of combining functions.
|
||||||
|
Putting it simply, there is some type T, some functions for constructing "primitive" values of type T,
|
||||||
|
and some "combinators" which can combine values of type T in various ways to build up more complex values of type T.
|
||||||
|
|
||||||
|
## Class diagram
|
||||||
|

|
||||||
|
|
||||||
|
## Applicability
|
||||||
|
Use the combinator pattern when:
|
||||||
|
|
||||||
|
- You are able to create a more complex value from more plain values but having the same type(a combination of them)
|
||||||
|
|
||||||
|
## Real world examples
|
||||||
|
|
||||||
|
- java.util.function.Function#compose
|
||||||
|
- java.util.function.Function#andThen
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
- [Example for java](https://gtrefs.github.io/code/combinator-pattern/)
|
||||||
|
- [Combinator pattern](https://wiki.haskell.org/Combinator_pattern)
|
||||||
|
- [Combinatory logic](https://wiki.haskell.org/Combinatory_logic)
|
BIN
combinator/etc/combinator.urm.png
Normal file
After Width: | Height: | Size: 22 KiB |
26
combinator/etc/combinator.urm.puml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
@startuml
|
||||||
|
package com.iluwatar.combinator {
|
||||||
|
class CombinatorApp {
|
||||||
|
- LOGGER : Logger {static}
|
||||||
|
+ CombinatorApp()
|
||||||
|
+ main(args : String[]) {static}
|
||||||
|
- text() : String {static}
|
||||||
|
}
|
||||||
|
interface Finder {
|
||||||
|
+ and(andFinder : Finder) : Finder
|
||||||
|
+ contains(word : String) : Finder {static}
|
||||||
|
+ find(String) : List<String> {abstract}
|
||||||
|
+ not(notFinder : Finder) : Finder
|
||||||
|
+ or(orFinder : Finder) : Finder
|
||||||
|
}
|
||||||
|
class Finders {
|
||||||
|
- Finders()
|
||||||
|
+ advancedFinder(query : String, orQuery : String, notQuery : String) : Finder {static}
|
||||||
|
+ expandedFinder(queries : String[]) : Finder {static}
|
||||||
|
+ filteredFinder(query : String, excludeQueries : String[]) : Finder {static}
|
||||||
|
- identMult() : Finder {static}
|
||||||
|
- identSum() : Finder {static}
|
||||||
|
+ specializedFinder(queries : String[]) : Finder {static}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@enduml
|
44
combinator/pom.xml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
The MIT License
|
||||||
|
Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
|
<version>1.23.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>combinator</artifactId>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.iluwatar.combinator;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The functional pattern representing a style of organizing libraries
|
||||||
|
* centered around the idea of combining functions.
|
||||||
|
* Putting it simply, there is some type T, some functions
|
||||||
|
* for constructing "primitive" values of type T,
|
||||||
|
* and some "combinators" which can combine values of type T
|
||||||
|
* in various ways to build up more complex values of type T.
|
||||||
|
* The class {@link Finder} defines a simple function {@link Finder#find(String)}
|
||||||
|
* and connected functions
|
||||||
|
* {@link Finder#or(Finder)},
|
||||||
|
* {@link Finder#not(Finder)},
|
||||||
|
* {@link Finder#and(Finder)}
|
||||||
|
* Using them the became possible to get more complex functions {@link Finders}
|
||||||
|
*/
|
||||||
|
public class CombinatorApp {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger.
|
||||||
|
*/
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(CombinatorApp.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* main.
|
||||||
|
* @param args args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
var queriesOr = new String[]{"many", "Annabel"};
|
||||||
|
var finder = Finders.expandedFinder(queriesOr);
|
||||||
|
var res = finder.find(text());
|
||||||
|
LOGGER.info("the result of expanded(or) query[{}] is {}", queriesOr, res);
|
||||||
|
|
||||||
|
var queriesAnd = new String[]{"Annabel", "my"};
|
||||||
|
finder = Finders.specializedFinder(queriesAnd);
|
||||||
|
res = finder.find(text());
|
||||||
|
LOGGER.info("the result of specialized(and) query[{}] is {}", queriesAnd, res);
|
||||||
|
|
||||||
|
finder = Finders.advancedFinder("it was","kingdom","sea");
|
||||||
|
res = finder.find(text());
|
||||||
|
LOGGER.info("the result of advanced query is {}", res);
|
||||||
|
|
||||||
|
res = Finders.filteredFinder(" was ", "many", "child").find(text());
|
||||||
|
LOGGER.info("the result of filtered query is {}", res);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String text() {
|
||||||
|
return
|
||||||
|
"It was many and many a year ago,\n"
|
||||||
|
+ "In a kingdom by the sea,\n"
|
||||||
|
+ "That a maiden there lived whom you may know\n"
|
||||||
|
+ "By the name of ANNABEL LEE;\n"
|
||||||
|
+ "And this maiden she lived with no other thought\n"
|
||||||
|
+ "Than to love and be loved by me.\n"
|
||||||
|
+ "I was a child and she was a child,\n"
|
||||||
|
+ "In this kingdom by the sea;\n"
|
||||||
|
+ "But we loved with a love that was more than love-\n"
|
||||||
|
+ "I and my Annabel Lee;\n"
|
||||||
|
+ "With a love that the winged seraphs of heaven\n"
|
||||||
|
+ "Coveted her and me.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
93
combinator/src/main/java/com/iluwatar/combinator/Finder.java
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License
|
||||||
|
* Copyright © 2014-2019 Ilkka Seppälä
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.iluwatar.combinator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functional interface to find lines in text.
|
||||||
|
*/
|
||||||
|
public interface Finder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function to find lines in text.
|
||||||
|
* @param text full tet
|
||||||
|
* @return result of searching
|
||||||
|
*/
|
||||||
|
List<String> find(String text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple implementation of function {@link #find(String)}.
|
||||||
|
* @param word for searching
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
static Finder contains(String word) {
|
||||||
|
return txt -> Stream.of(txt.split("\n"))
|
||||||
|
.filter(line -> line.toLowerCase().contains(word.toLowerCase()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* combinator not.
|
||||||
|
* @param notFinder finder to combine
|
||||||
|
* @return new finder including previous finders
|
||||||
|
*/
|
||||||
|
default Finder not(Finder notFinder) {
|
||||||
|
return txt -> {
|
||||||
|
List<String> res = this.find(txt);
|
||||||
|
res.removeAll(notFinder.find(txt));
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* combinator or.
|
||||||
|
* @param orFinder finder to combine
|
||||||
|
* @return new finder including previous finders
|
||||||
|
*/
|
||||||
|
default Finder or(Finder orFinder) {
|
||||||
|
return txt -> {
|
||||||
|
List<String> res = this.find(txt);
|
||||||
|
res.addAll(orFinder.find(txt));
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* combinator or.
|
||||||
|
* @param andFinder finder to combine
|
||||||
|
* @return new finder including previous finders
|
||||||
|
*/
|
||||||
|
default Finder and(Finder andFinder) {
|
||||||
|
return
|
||||||
|
txt -> this
|
||||||
|
.find(txt)
|
||||||
|
.stream()
|
||||||
|
.flatMap(line -> andFinder.find(line).stream())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|