Compare commits
264 Commits
1.22.0
...
all-contri
Author | SHA1 | Date | |
---|---|---|---|
d41077f355 | |||
e4473e5c88 | |||
7af544998d | |||
0a2c87d49a | |||
15eb49e574 | |||
661f9e1373 | |||
7908d38604 | |||
41020982de | |||
43569ecd66 | |||
fb6507ceda | |||
29f799c815 | |||
55bb1f11e0 | |||
8364b289b4 | |||
417f21ed3d | |||
5381387026 | |||
f95aadc8f5 | |||
402b753480 | |||
6a28d09a3c | |||
1e38edec15 | |||
ec7a2025f0 | |||
de79019ece | |||
f2ac53edca | |||
c9e30390d3 | |||
f49f9a15b6 | |||
f878bf63aa | |||
51ef7176b1 | |||
047285aed7 | |||
4db3a1cfb2 | |||
075fbe7433 | |||
1f0a24cefa | |||
69341ff712 | |||
a1b2ab129e | |||
87c2644842 | |||
1d025b7019 | |||
34a36cb519 | |||
62ac59afda | |||
beffc87deb | |||
706c5092c1 | |||
e222a69964 | |||
9483888b5e | |||
73d55afd58 | |||
1f900d164d | |||
5d21a03acd | |||
6c9b912620 | |||
7fdcd2ec5a | |||
dafe495610 | |||
6f0035e7c2 | |||
652a68b134 | |||
b5fac5cf86 | |||
ecb7b44f97 | |||
1841fba831 | |||
325f0d93b2 | |||
efd8c8156e | |||
ae57ec75f3 | |||
47acedaaf7 | |||
65d627b2ed | |||
b4e4cf9cfe | |||
b67a019c48 | |||
1bbae5fd5a | |||
d11b2f06ea | |||
2a66fec6fe | |||
a475df845b | |||
1bc77a80f2 | |||
9b5ae765fc | |||
8e268cf261 | |||
fe2f8f74a1 | |||
e2a42b0051 | |||
54bb02f691 | |||
a70213f852 | |||
19929d9e72 | |||
09880e3850 | |||
96bfb8bd9f | |||
a727a1d05b | |||
46fdc5a54f | |||
8137609e2f | |||
e924c9399a | |||
d791c78501 | |||
ba485e2c3e | |||
be54dc1c7e | |||
ec80402fe5 | |||
d1de465780 | |||
c2fb591749 | |||
c5479cc882 | |||
7968615ad4 | |||
c0d7c8922e | |||
5a23fab795 | |||
8c21809dad | |||
37bffb4a99 | |||
8182405796 | |||
39e5436ed5 | |||
8d6791490b | |||
eb8ddde98f | |||
0358fcec4c | |||
023865ad4c | |||
60ab9fa3ce | |||
f85e4db0be | |||
2b095bec28 | |||
cfba28f9a4 | |||
c0d2c7fdb0 | |||
96344142e9 | |||
0bc3756250 | |||
d94199f5ff | |||
b805a7526e | |||
0cff538c27 | |||
452981669b | |||
2706c8fc37 | |||
03ebd5f353 | |||
5b269d5af1 | |||
0563ac7645 | |||
a5ff32c13e | |||
97adc13a1b | |||
d8f12529f2 | |||
4c766b9e71 | |||
c85d764e39 | |||
f360b64877 | |||
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 |
1076
.all-contributorsrc
Normal file
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)
|
||||
|
||||
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
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
205
README.md
@ -4,10 +4,13 @@
|
||||
|
||||
# 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://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)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors-)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
# Introduction
|
||||
|
||||
@ -31,19 +34,20 @@ programming tutorials how to implement a specific pattern. We use the most
|
||||
popular battle-proven open source Java technologies.
|
||||
|
||||
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,
|
||||
and Do The Simplest Thing That Could Possibly Work principles. Complexity and
|
||||
patterns should only be introduced when they are needed for practical
|
||||
extensibility.
|
||||
|
||||
Once you are familiar with these concepts you can start drilling down into
|
||||
patterns by any of the following approaches
|
||||
Once you are familiar with these concepts you can start drilling down into the
|
||||
[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.
|
||||
- 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
|
||||
in your architectures and have as much fun learning them as we had developing them.
|
||||
@ -57,3 +61,192 @@ you and answer your questions in the [Gitter chatroom](https://gitter.im/iluwata
|
||||
# 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>
|
||||
</tr>
|
||||
<tr>
|
||||
<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>
|
||||
<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>
|
||||
</tr>
|
||||
<tr>
|
||||
<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>
|
||||
</tr>
|
||||
<tr>
|
||||
<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>
|
||||
<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>
|
||||
</tr>
|
||||
<tr>
|
||||
<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>
|
||||
<td align="center"><a href="https://github.com/nikhilbarar"><img src="https://avatars2.githubusercontent.com/u/37332144?v=4" width="100px;" alt=""/><br /><sub><b>nikhilbarar</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=nikhilbarar" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://colinbut.com"><img src="https://avatars2.githubusercontent.com/u/10725674?v=4" width="100px;" alt=""/><br /><sub><b>Colin But</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=colinbut" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/ruslanpa"><img src="https://avatars2.githubusercontent.com/u/1503411?v=4" width="100px;" alt=""/><br /><sub><b>Ruslan</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ruslanpa" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/JuhoKang"><img src="https://avatars1.githubusercontent.com/u/4745294?v=4" width="100px;" alt=""/><br /><sub><b>Juho Kang</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=JuhoKang" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/dheeraj-mummareddy"><img src="https://avatars2.githubusercontent.com/u/7002230?v=4" width="100px;" alt=""/><br /><sub><b>Dheeraj Mummareddy</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=dheeraj-mummareddy" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.bernardosulzbach.com"><img src="https://avatars0.githubusercontent.com/u/8271090?v=4" width="100px;" alt=""/><br /><sub><b>Bernardo Sulzbach</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=bernardosulzbach" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/4lexis"><img src="https://avatars0.githubusercontent.com/u/19871727?v=4" width="100px;" alt=""/><br /><sub><b>Aleksandar Dudukovic</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=4lexis" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.yusufaytas.com"><img src="https://avatars2.githubusercontent.com/u/1049483?v=4" width="100px;" alt=""/><br /><sub><b>Yusuf Aytaş</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=yusufaytas" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://futurehomes.hu"><img src="https://avatars2.githubusercontent.com/u/1001491?v=4" width="100px;" alt=""/><br /><sub><b>Mihály Kuprivecz</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=qpi" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/kapinuss"><img src="https://avatars0.githubusercontent.com/u/17639945?v=4" width="100px;" alt=""/><br /><sub><b>Stanislav Kapinus</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=kapinuss" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/gvsharma"><img src="https://avatars1.githubusercontent.com/u/6648152?v=4" width="100px;" alt=""/><br /><sub><b>GVSharma</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=gvsharma" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/SrdjanPaunovic"><img src="https://avatars1.githubusercontent.com/u/22815104?v=4" width="100px;" alt=""/><br /><sub><b>Srđan Paunović</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=SrdjanPaunovic" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://sideris.xyz/"><img src="https://avatars3.githubusercontent.com/u/5484694?v=4" width="100px;" alt=""/><br /><sub><b>Petros G. Sideris</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=sideris" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.linkedin.com/in/pramodgupta3/"><img src="https://avatars1.githubusercontent.com/u/2184241?v=4" width="100px;" alt=""/><br /><sub><b>Pramod Gupta</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3AIAmPramod" title="Reviewed Pull Requests">👀</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://amarnath510.github.io/portfolio"><img src="https://avatars0.githubusercontent.com/u/4599623?v=4" width="100px;" alt=""/><br /><sub><b>Amarnath Chandana</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Amarnath510" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/Anurag870"><img src="https://avatars1.githubusercontent.com/u/6295975?v=4" width="100px;" alt=""/><br /><sub><b>Anurag870</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Anurag870" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://theerroris.me"><img src="https://avatars0.githubusercontent.com/u/1685953?v=4" width="100px;" alt=""/><br /><sub><b>Wes Gilleland</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Deathnerd" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/Harshrajsinh"><img src="https://avatars2.githubusercontent.com/u/22811531?v=4" width="100px;" alt=""/><br /><sub><b>Harshraj Thakor</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Harshrajsinh" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/MaVdbussche"><img src="https://avatars1.githubusercontent.com/u/26136934?v=4" width="100px;" alt=""/><br /><sub><b>Martin Vandenbussche</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=MaVdbussche" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://alexsomai.com"><img src="https://avatars1.githubusercontent.com/u/5720977?v=4" width="100px;" alt=""/><br /><sub><b>Alexandru Somai</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=alexsomai" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/amogozov"><img src="https://avatars3.githubusercontent.com/u/7372215?v=4" width="100px;" alt=""/><br /><sub><b>Artur Mogozov</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=amogozov" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/anthonycampbell"><img src="https://avatars3.githubusercontent.com/u/10249255?v=4" width="100px;" alt=""/><br /><sub><b>anthony</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=anthonycampbell" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="http://ccygnus.com/"><img src="https://avatars1.githubusercontent.com/u/9342724?v=4" width="100px;" alt=""/><br /><sub><b>Christian Cygnus</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=christophercolumbusdog" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://about.me/dzmitryh"><img src="https://avatars2.githubusercontent.com/u/5390492?v=4" width="100px;" alt=""/><br /><sub><b>Dima Gubin</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=dzmitryh" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/jjjimenez100"><img src="https://avatars3.githubusercontent.com/u/22243493?v=4" width="100px;" alt=""/><br /><sub><b>Joshua Jimenez</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=jjjimenez100" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://about.me/kaiwinter"><img src="https://avatars0.githubusercontent.com/u/110982?v=4" width="100px;" alt=""/><br /><sub><b>Kai Winter</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=kaiwinter" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/lbroman"><img src="https://avatars1.githubusercontent.com/u/86007?v=4" width="100px;" alt=""/><br /><sub><b>lbroman</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=lbroman" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://przemeknowak.com"><img src="https://avatars1.githubusercontent.com/u/3254609?v=4" width="100px;" alt=""/><br /><sub><b>Przemek</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=pnowy" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/prafful1"><img src="https://avatars0.githubusercontent.com/u/14350274?v=4" width="100px;" alt=""/><br /><sub><b>Prafful Agarwal</b></sub></a><br /><a href="#content-prafful1" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://github.com/sankypanhale"><img src="https://avatars1.githubusercontent.com/u/6478783?v=4" width="100px;" alt=""/><br /><sub><b>Sanket Panhale</b></sub></a><br /><a href="#content-sankypanhale" title="Content">🖋</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/staillebois"><img src="https://avatars0.githubusercontent.com/u/23701200?v=4" width="100px;" alt=""/><br /><sub><b>staillebois</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=staillebois" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/valdar-hu"><img src="https://avatars3.githubusercontent.com/u/17962817?v=4" width="100px;" alt=""/><br /><sub><b>Krisztián Nagy</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=valdar-hu" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.vanogrid.com"><img src="https://avatars0.githubusercontent.com/u/4307918?v=4" width="100px;" alt=""/><br /><sub><b>Alexander Ivanov</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=vanogrid" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/yosfik"><img src="https://avatars3.githubusercontent.com/u/4850270?v=4" width="100px;" alt=""/><br /><sub><b>Yosfik Alqadri</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=yosfik" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/7agustibm"><img src="https://avatars0.githubusercontent.com/u/8149332?v=4" width="100px;" alt=""/><br /><sub><b>Agustí Becerra Milà</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=7agustibm" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/Juaanma"><img src="https://avatars3.githubusercontent.com/u/7390500?v=4" width="100px;" alt=""/><br /><sub><b>Juan Manuel Suárez</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Juaanma" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://www.devsedge.net/"><img src="https://avatars0.githubusercontent.com/u/9956006?v=4" width="100px;" alt=""/><br /><sub><b>Luigi Cortese</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=LuigiCortese" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/Rzeposlaw"><img src="https://avatars2.githubusercontent.com/u/18425745?v=4" width="100px;" alt=""/><br /><sub><b>Katarzyna Rzepecka</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Rzeposlaw" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="http://adamski.pro"><img src="https://avatars1.githubusercontent.com/u/6537430?v=4" width="100px;" alt=""/><br /><sub><b>adamski.pro</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=akrystian" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/baislsl"><img src="https://avatars0.githubusercontent.com/u/17060584?v=4" width="100px;" alt=""/><br /><sub><b>Shengli Bai</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=baislsl" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/besok"><img src="https://avatars2.githubusercontent.com/u/29834592?v=4" width="100px;" alt=""/><br /><sub><b>Boris</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=besok" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/dmitraver"><img src="https://avatars3.githubusercontent.com/u/1798156?v=4" width="100px;" alt=""/><br /><sub><b>Dmitry Avershin</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=dmitraver" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/fanofxiaofeng"><img src="https://avatars0.githubusercontent.com/u/3983683?v=4" width="100px;" alt=""/><br /><sub><b>靳阳</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=fanofxiaofeng" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/hoangnam2261"><img src="https://avatars2.githubusercontent.com/u/31692990?v=4" width="100px;" alt=""/><br /><sub><b>hoangnam2261</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=hoangnam2261" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/jarpit96"><img src="https://avatars2.githubusercontent.com/u/10098713?v=4" width="100px;" alt=""/><br /><sub><b>Arpit Jain</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=jarpit96" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://joningi.net"><img src="https://avatars2.githubusercontent.com/u/6115148?v=4" width="100px;" alt=""/><br /><sub><b>Jón Ingi Sveinbjörnsson</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=joningiwork" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/kirill-vlasov"><img src="https://avatars3.githubusercontent.com/u/16112495?v=4" width="100px;" alt=""/><br /><sub><b>Kirill Vlasov</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=kirill-vlasov" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://mitchell-irvin.com"><img src="https://avatars0.githubusercontent.com/u/16233245?v=4" width="100px;" alt=""/><br /><sub><b>Mitchell Irvin</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=mitchellirvin" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://ranjeet-floyd.github.io"><img src="https://avatars0.githubusercontent.com/u/1992972?v=4" width="100px;" alt=""/><br /><sub><b>Ranjeet</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ranjeet-floyd" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://alwayswithme.github.io"><img src="https://avatars3.githubusercontent.com/u/3234786?v=4" width="100px;" alt=""/><br /><sub><b>PhoenixYip</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Alwayswithme" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/MSaifAsif"><img src="https://avatars1.githubusercontent.com/u/6280554?v=4" width="100px;" alt=""/><br /><sub><b>M Saif Asif</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=MSaifAsif" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/kanwarpreet25"><img src="https://avatars0.githubusercontent.com/u/39183641?v=4" width="100px;" alt=""/><br /><sub><b>kanwarpreet25</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=kanwarpreet25" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://leonmak.me"><img src="https://avatars3.githubusercontent.com/u/13071508?v=4" width="100px;" alt=""/><br /><sub><b>Leon Mak</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=leonmak" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://www.wramdemark.se"><img src="https://avatars2.githubusercontent.com/u/7052193?v=4" width="100px;" alt=""/><br /><sub><b>Per Wramdemark</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=perwramdemark" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/waisuan"><img src="https://avatars2.githubusercontent.com/u/10975700?v=4" width="100px;" alt=""/><br /><sub><b>Evan Sia Wai Suan</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=waisuan" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/AnaghaSasikumar"><img src="https://avatars2.githubusercontent.com/u/42939261?v=4" width="100px;" alt=""/><br /><sub><b>AnaghaSasikumar</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=AnaghaSasikumar" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://christofferh.com"><img src="https://avatars1.githubusercontent.com/u/767643?v=4" width="100px;" alt=""/><br /><sub><b>Christoffer Hamberg</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=christofferh" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/dgruntz"><img src="https://avatars0.githubusercontent.com/u/1516800?v=4" width="100px;" alt=""/><br /><sub><b>Dominik Gruntz</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=dgruntz" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://bitbucket.org/hannespernpeintner/"><img src="https://avatars3.githubusercontent.com/u/1679437?v=4" width="100px;" alt=""/><br /><sub><b>Hannes</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=hannespernpeintner" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/leogtzr"><img src="https://avatars0.githubusercontent.com/u/1211969?v=4" width="100px;" alt=""/><br /><sub><b>Leo Gutiérrez Ramírez</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=leogtzr" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/npczwh"><img src="https://avatars0.githubusercontent.com/u/14066422?v=4" width="100px;" alt=""/><br /><sub><b>Zhang WH</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=npczwh" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/oconnelc"><img src="https://avatars0.githubusercontent.com/u/1112973?v=4" width="100px;" alt=""/><br /><sub><b>Christopher O'Connell</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=oconnelc" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/giorgosmav21"><img src="https://avatars2.githubusercontent.com/u/22855493?v=4" width="100px;" alt=""/><br /><sub><b>George Mavroeidis</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=giorgosmav21" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/hbothra15"><img src="https://avatars1.githubusercontent.com/u/7418012?v=4" width="100px;" alt=""/><br /><sub><b>Hemant Bothra</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=hbothra15" title="Code">💻</a> <a href="#design-hbothra15" title="Design">🎨</a></td>
|
||||
<td align="center"><a href="https://www.kevinpeters.net/about/"><img src="https://avatars1.githubusercontent.com/u/12736734?v=4" width="100px;" alt=""/><br /><sub><b>Kevin Peters</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=igeligel" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://llorllale.github.io/"><img src="https://avatars1.githubusercontent.com/u/2019896?v=4" width="100px;" alt=""/><br /><sub><b>George Aristy</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=llorllale" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/mookkiah"><img src="https://avatars1.githubusercontent.com/u/8975264?v=4" width="100px;" alt=""/><br /><sub><b>Mahendran Mookkiah</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=mookkiah" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/Azureyjt"><img src="https://avatars2.githubusercontent.com/u/18476317?v=4" width="100px;" alt=""/><br /><sub><b>Azureyjt</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Azureyjt" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/vehpsr"><img src="https://avatars2.githubusercontent.com/u/3133265?v=4" width="100px;" alt=""/><br /><sub><b>gans</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=vehpsr" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/ThatGuyWithTheHat"><img src="https://avatars0.githubusercontent.com/u/24470582?v=4" width="100px;" alt=""/><br /><sub><b>Matt</b></sub></a><br /><a href="#content-ThatGuyWithTheHat" title="Content">🖋</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://www.linkedin.com/in/gopinathlangote/"><img src="https://avatars2.githubusercontent.com/u/10210778?v=4" width="100px;" alt=""/><br /><sub><b>Gopinath Langote</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=gopinath-langote" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/hoswey"><img src="https://avatars3.githubusercontent.com/u/3689445?v=4" width="100px;" alt=""/><br /><sub><b>Hoswey</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=hoswey" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/amit2103"><img src="https://avatars3.githubusercontent.com/u/7566692?v=4" width="100px;" alt=""/><br /><sub><b>Amit Pandey</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=amit2103" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/gwildor28"><img src="https://avatars0.githubusercontent.com/u/16000365?v=4" width="100px;" alt=""/><br /><sub><b>gwildor28</b></sub></a><br /><a href="#content-gwildor28" title="Content">🖋</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://t.me/paul_docker"><img src="https://avatars1.githubusercontent.com/u/2404785?v=4" width="100px;" alt=""/><br /><sub><b>田浩</b></sub></a><br /><a href="#content-llitfkitfk" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://twitter.com/StPitsios"><img src="https://avatars1.githubusercontent.com/u/6773603?v=4" width="100px;" alt=""/><br /><sub><b>Stamatis Pitsios</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=pitsios-s" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/qza"><img src="https://avatars3.githubusercontent.com/u/233149?v=4" width="100px;" alt=""/><br /><sub><b>qza</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=qza" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://tschis.github.io"><img src="https://avatars1.githubusercontent.com/u/20662669?v=4" width="100px;" alt=""/><br /><sub><b>Rodolfo Forte</b></sub></a><br /><a href="#content-Tschis" title="Content">🖋</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/ankurkaushal"><img src="https://avatars2.githubusercontent.com/u/2236616?v=4" width="100px;" alt=""/><br /><sub><b>Ankur Kaushal</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ankurkaushal" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.linkedin.com/in/ovidijus-okinskas/"><img src="https://avatars0.githubusercontent.com/u/20372387?v=4" width="100px;" alt=""/><br /><sub><b>Ovidijus Okinskas</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=okinskas" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/robertt240"><img src="https://avatars1.githubusercontent.com/u/9137432?v=4" width="100px;" alt=""/><br /><sub><b>Robert Kasperczyk</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=robertt240" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/trautonen"><img src="https://avatars3.githubusercontent.com/u/1641063?v=4" width="100px;" alt=""/><br /><sub><b>Tapio Rautonen</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=trautonen" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="http://vk.com/yuri.orlov"><img src="https://avatars0.githubusercontent.com/u/1595733?v=4" width="100px;" alt=""/><br /><sub><b>Yuri Orlov</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=yorlov" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.linkedin.com/in/varunu28/"><img src="https://avatars0.githubusercontent.com/u/7676016?v=4" width="100px;" alt=""/><br /><sub><b>Varun Upadhyay</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=varunu28" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/PalAditya"><img src="https://avatars2.githubusercontent.com/u/25523604?v=4" width="100px;" alt=""/><br /><sub><b>Aditya Pal</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=PalAditya" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/grzesiekkedzior"><img src="https://avatars3.githubusercontent.com/u/23739158?v=4" width="100px;" alt=""/><br /><sub><b>grzesiekkedzior</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=grzesiekkedzior" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/sivasubramanim"><img src="https://avatars2.githubusercontent.com/u/51107434?v=4" width="100px;" alt=""/><br /><sub><b>Sivasubramani M</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=sivasubramanim" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/d4gg4d"><img src="https://avatars2.githubusercontent.com/u/99457?v=4" width="100px;" alt=""/><br /><sub><b>Sami Airaksinen</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=d4gg4d" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/vertti"><img src="https://avatars0.githubusercontent.com/u/557751?v=4" width="100px;" alt=""/><br /><sub><b>Janne Sinivirta</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=vertti" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/Bobo1239"><img src="https://avatars1.githubusercontent.com/u/2302947?v=4" width="100px;" alt=""/><br /><sub><b>Boris-Chengbiao Zhou</b></sub></a><br /><a href="#content-Bobo1239" title="Content">🖋</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://jahhein.github.io"><img src="https://avatars2.githubusercontent.com/u/10779515?v=4" width="100px;" alt=""/><br /><sub><b>Jacob Hein</b></sub></a><br /><a href="#content-Jahhein" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://github.com/iamrichardjones"><img src="https://avatars3.githubusercontent.com/u/14842151?v=4" width="100px;" alt=""/><br /><sub><b>Richard Jones</b></sub></a><br /><a href="#content-iamrichardjones" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://rachelcarmena.github.io"><img src="https://avatars0.githubusercontent.com/u/22792183?v=4" width="100px;" alt=""/><br /><sub><b>Rachel M. Carmena</b></sub></a><br /><a href="#content-rachelcarmena" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://zd-zero.github.io"><img src="https://avatars0.githubusercontent.com/u/21978370?v=4" width="100px;" alt=""/><br /><sub><b>Zaerald Denze Lungos</b></sub></a><br /><a href="#content-zd-zero" title="Content">🖋</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://webpro.nl"><img src="https://avatars1.githubusercontent.com/u/456426?v=4" width="100px;" alt=""/><br /><sub><b>Lars Kappert</b></sub></a><br /><a href="#content-webpro" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://xiaod.info"><img src="https://avatars2.githubusercontent.com/u/21277644?v=4" width="100px;" alt=""/><br /><sub><b>Mike Liu</b></sub></a><br /><a href="#translation-xiaod-dev" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/charlesfinley"><img src="https://avatars1.githubusercontent.com/u/6307904?v=4" width="100px;" alt=""/><br /><sub><b>Matt Dolan</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=charlesfinley" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/MananS77"><img src="https://avatars3.githubusercontent.com/u/21033516?v=4" width="100px;" alt=""/><br /><sub><b>Manan</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3AMananS77" title="Reviewed Pull Requests">👀</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/nishant"><img src="https://avatars2.githubusercontent.com/u/15331971?v=4" width="100px;" alt=""/><br /><sub><b>Nishant Arora</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=nishant" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-enable -->
|
||||
<!-- prettier-ignore-end -->
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
@ -5,25 +5,186 @@ folder: abstract-document
|
||||
permalink: /patterns/abstract-document/
|
||||
categories: Structural
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Intermediate
|
||||
- Extensibility
|
||||
---
|
||||
|
||||
## Intent
|
||||
Achieve flexibility of untyped languages and keep the type-safety
|
||||
|
||||
Use dynamic properties and achieve flexibility of untyped languages while keeping type-safety.
|
||||
|
||||
## Explanation
|
||||
|
||||
The Abstract Document pattern enables handling additional, non-static properties. This pattern
|
||||
uses concept of traits to enable type safety and separate properties of different classes into
|
||||
set of interfaces.
|
||||
|
||||
Real world example
|
||||
|
||||
> Consider a car that consists of multiple parts. However we don't know if the specific car really has all the parts, or just some of them. Our cars are dynamic and extremely flexible.
|
||||
|
||||
In plain words
|
||||
|
||||
> Abstract Document pattern allows attaching properties to objects without them knowing about it.
|
||||
|
||||
Wikipedia says
|
||||
|
||||
> An object-oriented structural design pattern for organizing objects in loosely typed key-value stores and exposing
|
||||
the data using typed views. The purpose of the pattern is to achieve a high degree of flexibility between components
|
||||
in a strongly typed language where new properties can be added to the object-tree on the fly, without losing the
|
||||
support of type-safety. The pattern makes use of traits to separate different properties of a class into different
|
||||
interfaces.
|
||||
|
||||
**Programmatic Example**
|
||||
|
||||
Let's first define the base classes `Document` and `AbstractDocument`. They basically make the object hold a property
|
||||
map and any amount of child objects.
|
||||
|
||||
```java
|
||||
public interface Document {
|
||||
|
||||
Void put(String key, Object value);
|
||||
|
||||
Object get(String key);
|
||||
|
||||
<T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor);
|
||||
}
|
||||
|
||||
public abstract class AbstractDocument implements Document {
|
||||
|
||||
private final Map<String, Object> properties;
|
||||
|
||||
protected AbstractDocument(Map<String, Object> properties) {
|
||||
Objects.requireNonNull(properties, "properties map is required");
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void put(String key, Object value) {
|
||||
properties.put(key, value);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String key) {
|
||||
return properties.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Stream<T> children(String key, Function<Map<String, Object>, T> constructor) {
|
||||
return Stream.ofNullable(get(key))
|
||||
.filter(Objects::nonNull)
|
||||
.map(el -> (List<Map<String, Object>>) el)
|
||||
.findAny()
|
||||
.stream()
|
||||
.flatMap(Collection::stream)
|
||||
.map(constructor);
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
Next we define an enum `Property` and a set of interfaces for type, price, model and parts. This allows us to create
|
||||
static looking interface to our `Car` class.
|
||||
|
||||
```java
|
||||
public enum Property {
|
||||
|
||||
PARTS, TYPE, PRICE, MODEL
|
||||
}
|
||||
|
||||
public interface HasType extends Document {
|
||||
|
||||
default Optional<String> getType() {
|
||||
return Optional.ofNullable((String) get(Property.TYPE.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public interface HasPrice extends Document {
|
||||
|
||||
default Optional<Number> getPrice() {
|
||||
return Optional.ofNullable((Number) get(Property.PRICE.toString()));
|
||||
}
|
||||
}
|
||||
public interface HasModel extends Document {
|
||||
|
||||
default Optional<String> getModel() {
|
||||
return Optional.ofNullable((String) get(Property.MODEL.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public interface HasParts extends Document {
|
||||
|
||||
default Stream<Part> getParts() {
|
||||
return children(Property.PARTS.toString(), Part::new);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now we are ready to introduce the `Car`.
|
||||
|
||||
```java
|
||||
public class Car extends AbstractDocument implements HasModel, HasPrice, HasParts {
|
||||
|
||||
public Car(Map<String, Object> properties) {
|
||||
super(properties);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And finally here's how we construct and use the `Car` in a full example.
|
||||
|
||||
```java
|
||||
LOGGER.info("Constructing parts and car");
|
||||
|
||||
var wheelProperties = Map.of(
|
||||
Property.TYPE.toString(), "wheel",
|
||||
Property.MODEL.toString(), "15C",
|
||||
Property.PRICE.toString(), 100L);
|
||||
|
||||
var doorProperties = Map.of(
|
||||
Property.TYPE.toString(), "door",
|
||||
Property.MODEL.toString(), "Lambo",
|
||||
Property.PRICE.toString(), 300L);
|
||||
|
||||
var carProperties = Map.of(
|
||||
Property.MODEL.toString(), "300SL",
|
||||
Property.PRICE.toString(), 10000L,
|
||||
Property.PARTS.toString(), List.of(wheelProperties, doorProperties));
|
||||
|
||||
var car = new Car(carProperties);
|
||||
|
||||
LOGGER.info("Here is our car:");
|
||||
LOGGER.info("-> model: {}", car.getModel().orElseThrow());
|
||||
LOGGER.info("-> price: {}", car.getPrice().orElseThrow());
|
||||
LOGGER.info("-> parts: ");
|
||||
car.getParts().forEach(p -> LOGGER.info("\t{}/{}/{}",
|
||||
p.getType().orElse(null),
|
||||
p.getModel().orElse(null),
|
||||
p.getPrice().orElse(null))
|
||||
);
|
||||
|
||||
// Constructing parts and car
|
||||
// Here is our car:
|
||||
// model: 300SL
|
||||
// price: 10000
|
||||
// parts:
|
||||
// wheel/15C/100
|
||||
// door/Lambo/300
|
||||
```
|
||||
|
||||
## Class diagram
|
||||
|
||||

|
||||
|
||||
|
||||
## Applicability
|
||||
|
||||
Use the Abstract Document Pattern when
|
||||
|
||||
* there is a need to add new properties on the fly
|
||||
* you want a flexible way to organize domain in tree like structure
|
||||
* you want more loosely coupled system
|
||||
|
||||
* There is a need to add new properties on the fly
|
||||
* You want a flexible way to organize domain in tree like structure
|
||||
* You want more loosely coupled system
|
||||
|
||||
## Credits
|
||||
|
||||
* [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)
|
||||
* [Pattern-Oriented Software Architecture Volume 4: A Pattern Language for Distributed Computing (v. 4)](https://www.amazon.com/gp/product/0470059028/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0470059028&linkId=e3aacaea7017258acf184f9f3283b492)
|
||||
|
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"?>
|
||||
<!--
|
||||
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>abstract-document</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- 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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>abstract-document</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</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.abstractdocument.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -32,7 +32,6 @@ import java.util.stream.Stream;
|
||||
*/
|
||||
public interface HasParts extends Document {
|
||||
|
||||
|
||||
default Stream<Part> getParts() {
|
||||
return children(Property.PARTS.toString(), Part::new);
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ import java.util.Optional;
|
||||
*/
|
||||
public interface HasPrice extends Document {
|
||||
|
||||
|
||||
default Optional<Number> getPrice() {
|
||||
return Optional.ofNullable((Number) get(Property.PRICE.toString()));
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ import java.util.Optional;
|
||||
*/
|
||||
public interface HasType extends Document {
|
||||
|
||||
|
||||
default Optional<String> getType() {
|
||||
return Optional.ofNullable((String) get(Property.TYPE.toString()));
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -47,7 +47,7 @@ public class AbstractDocumentTest {
|
||||
}
|
||||
}
|
||||
|
||||
private DocumentImplementation document = new DocumentImplementation(new HashMap<>());
|
||||
private final DocumentImplementation document = new DocumentImplementation(new HashMap<>());
|
||||
|
||||
@Test
|
||||
public void shouldPutAndGetValue() {
|
||||
|
@ -5,9 +5,7 @@ folder: abstract-factory
|
||||
permalink: /patterns/abstract-factory/
|
||||
categories: Creational
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
- Difficulty-Intermediate
|
||||
- Gang of Four
|
||||
---
|
||||
|
||||
## Also known as
|
||||
@ -157,6 +155,9 @@ public static void main(String[] args) {
|
||||
}
|
||||
```
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
|
||||
## Applicability
|
||||
Use the Abstract Factory pattern when
|
||||
@ -197,4 +198,5 @@ Use the Abstract Factory pattern when
|
||||
|
||||
## 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"?>
|
||||
<!--
|
||||
|
||||
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.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>abstract-factory</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- 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>abstract-factory</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</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.abstractfactory.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</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;
|
||||
}
|
@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test;
|
||||
*/
|
||||
public class AbstractFactoryTest {
|
||||
|
||||
private App app = new App();
|
||||
private final App app = new App();
|
||||
private KingdomFactory elfFactory;
|
||||
private KingdomFactory orcFactory;
|
||||
|
||||
|
@ -5,17 +5,18 @@ folder: acyclic-visitor
|
||||
permalink: /patterns/acyclic-visitor/
|
||||
categories: Behavioral
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Intermediate
|
||||
- Extensibility
|
||||
---
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
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 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.
|
||||
@ -24,11 +25,13 @@ This pattern can be used:
|
||||
|
||||
## Consequences
|
||||
The good:
|
||||
|
||||
* No dependency cycles between class hierarchies.
|
||||
* 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.
|
||||
|
||||
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.
|
||||
* 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 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.
|
||||
|
||||
-->
|
||||
<!-- 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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
|
||||
<artifactId>acyclic-visitor</artifactId>
|
||||
|
||||
<properties>
|
||||
@ -53,19 +44,40 @@
|
||||
<dependency>
|
||||
<groupId>uk.org.lidalia</groupId>
|
||||
<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>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.9.5</version>
|
||||
<version>1.10.19</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</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>
|
||||
|
@ -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;
|
||||
}
|
@ -37,7 +37,7 @@ import uk.org.lidalia.slf4jtest.TestLoggerFactory;
|
||||
*/
|
||||
public class ConfigureForDosVisitorTest {
|
||||
|
||||
private TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class);
|
||||
private final TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class);
|
||||
|
||||
@Test
|
||||
public void testVisitForZoom() {
|
||||
|
@ -5,9 +5,7 @@ folder: adapter
|
||||
permalink: /patterns/adapter/
|
||||
categories: Structural
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
- Difficulty-Beginner
|
||||
- Gang of Four
|
||||
---
|
||||
|
||||
## Also known as
|
||||
@ -58,7 +56,7 @@ And captain expects an implementation of `RowingBoat` interface to be able to mo
|
||||
```java
|
||||
public class Captain {
|
||||
|
||||
private RowingBoat rowingBoat;
|
||||
private final RowingBoat rowingBoat;
|
||||
// default constructor and setter for rowingBoat
|
||||
public Captain(RowingBoat rowingBoat) {
|
||||
this.rowingBoat = rowingBoat;
|
||||
@ -77,7 +75,7 @@ public class FishingBoatAdapter implements RowingBoat {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class);
|
||||
|
||||
private FishingBoat boat;
|
||||
private final FishingBoat boat;
|
||||
|
||||
public FishingBoatAdapter() {
|
||||
boat = new FishingBoat();
|
||||
@ -97,6 +95,9 @@ var captain = new Captain(new FishingBoatAdapter());
|
||||
captain.row();
|
||||
```
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
Use the Adapter pattern when
|
||||
|
||||
@ -128,5 +129,7 @@ An object adapter
|
||||
|
||||
## Credits
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
|
||||
* [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](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"?>
|
||||
<!--
|
||||
|
||||
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.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>adapter</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- 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>adapter</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</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.adapter.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -29,7 +29,7 @@ package com.iluwatar.adapter;
|
||||
*/
|
||||
public class FishingBoatAdapter implements RowingBoat {
|
||||
|
||||
private FishingBoat boat;
|
||||
private final FishingBoat boat;
|
||||
|
||||
public FishingBoatAdapter() {
|
||||
boat = new FishingBoat();
|
||||
|
@ -5,8 +5,7 @@ folder: aggregator-microservices
|
||||
permalink: /patterns/aggregator-microservices/
|
||||
categories: Architectural
|
||||
tags:
|
||||
- Java
|
||||
- Spring
|
||||
- Cloud distributed
|
||||
---
|
||||
|
||||
## 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
|
||||
of other microservices.
|
||||
|
||||
## Class diagram
|
||||
|
||||

|
||||
|
||||
## Applicability
|
||||
@ -26,4 +27,4 @@ Use the Aggregator Microservices pattern when you need a unified API for various
|
||||
|
||||
## 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"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<!-- 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>aggregator-microservices</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>aggregator-service</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
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>aggregator-microservices</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>aggregator-service</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- 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.aggregator.microservices.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</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"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<!-- 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>aggregator-microservices</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
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>aggregator-microservices</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>information-microservice</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>information-microservice</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<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>
|
||||
|
@ -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"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<!-- 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>aggregator-microservices</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>inventory-microservice</artifactId>
|
||||
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>aggregator-microservices</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>inventory-microservice</artifactId>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<packaging>jar</packaging>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<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>
|
||||
|
@ -29,7 +29,7 @@
|
||||
<parent>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>aggregator-microservices</artifactId>
|
||||
|
@ -5,8 +5,8 @@ folder: ambassador
|
||||
permalink: /patterns/ambassador/
|
||||
categories: Structural
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Intermediate
|
||||
- Decoupling
|
||||
- Cloud distributed
|
||||
---
|
||||
|
||||
## Intent
|
||||
@ -23,8 +23,7 @@ In plain words
|
||||
|
||||
Microsoft documentation states
|
||||
|
||||
> 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.
|
||||
> 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.
|
||||
|
||||
**Programmatic Example**
|
||||
|
||||
@ -150,6 +149,9 @@ public class App {
|
||||
}
|
||||
```
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
Ambassador is applicable when working with a legacy remote service that cannot
|
||||
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"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<!-- 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.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ambassador</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
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>ambassador</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.ambassador.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -48,7 +48,7 @@ class RemoteServiceTest {
|
||||
}
|
||||
|
||||
private static class StaticRandomProvider implements RandomProvider {
|
||||
private double value;
|
||||
private final double value;
|
||||
|
||||
StaticRandomProvider(double value) {
|
||||
this.value = value;
|
||||
|
@ -5,26 +5,155 @@ folder: api-gateway
|
||||
permalink: /patterns/api-gateway/
|
||||
categories: Architectural
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Intermediate
|
||||
- Spring
|
||||
- Cloud distributed
|
||||
- Decoupling
|
||||
- Microservices
|
||||
---
|
||||
|
||||
## Intent
|
||||
|
||||
Aggregate calls to microservices in a single location: the API Gateway. The user makes a single
|
||||
call to the API Gateway, and the API Gateway then calls each relevant microservice.
|
||||
Aggregate calls to microservices in a single location: the API Gateway. The user makes a single call to the API Gateway,
|
||||
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
|
||||
|
||||
Use the API Gateway pattern when
|
||||
|
||||
* you're also using the Microservices pattern and need a single point of aggregation for your
|
||||
microservice calls
|
||||
* You're using microservices architecture and need a single point of aggregation for your microservice calls.
|
||||
|
||||
## Credits
|
||||
|
||||
* [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/)
|
||||
* [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>
|
||||
<artifactId>api-gateway</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>api-gateway-service</artifactId>
|
||||
@ -68,6 +68,21 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</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>
|
||||
</build>
|
||||
</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>
|
||||
<artifactId>api-gateway</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>image-microservice</artifactId>
|
||||
@ -63,6 +63,21 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</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>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -29,7 +29,7 @@
|
||||
<parent>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<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>
|
||||
<artifactId>api-gateway</artifactId>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@ -65,6 +65,21 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</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>
|
||||
</build>
|
||||
</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(7, cash.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinus() {
|
||||
//Arrange
|
||||
var cash = new Cash(8);
|
||||
//Act
|
||||
var result = cash.minus(5);
|
||||
//Assert
|
||||
assertTrue(result);
|
||||
assertEquals(3, cash.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsufficientMinus() {
|
||||
//Arrange
|
||||
var cash = new Cash(1);
|
||||
//Act
|
||||
var result = cash.minus(6);
|
||||
//Assert
|
||||
assertFalse(result);
|
||||
assertEquals(1, cash.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() {
|
||||
//Arrange
|
||||
var cash = new Cash(5);
|
||||
//Act
|
||||
cash.plus(6);
|
||||
var result = cash.minus(3);
|
||||
//Assert
|
||||
assertTrue(result);
|
||||
assertEquals(8, cash.count());
|
||||
}
|
||||
}
|
@ -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(7, cash.count());
|
||||
//test minus
|
||||
cash = new Cash(8);
|
||||
assertTrue(cash.minus(5));
|
||||
assertEquals(3, cash.count());
|
||||
assertFalse(cash.minus(6));
|
||||
assertEquals(3, cash.count());
|
||||
//test update
|
||||
cash.plus(5);
|
||||
assertTrue(cash.minus(5));
|
||||
assertEquals(3, cash.count());
|
||||
}
|
||||
}
|
@ -5,9 +5,6 @@ folder: async-method-invocation
|
||||
permalink: /patterns/async-method-invocation/
|
||||
categories: Concurrency
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Intermediate
|
||||
- Functional
|
||||
- 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
|
||||
callbacks or waiting until everything is done.
|
||||
|
||||
# Class diagram
|
||||

|
||||
|
||||
## 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"?>
|
||||
<!--
|
||||
|
||||
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.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>async-method-invocation</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- 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>async-method-invocation</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</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.async.method.invocation.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -100,7 +100,7 @@ public class ThreadAsyncExecutor implements AsyncExecutor {
|
||||
void setValue(T value) {
|
||||
this.value = value;
|
||||
this.state = COMPLETED;
|
||||
this.callback.ifPresent(ac -> ac.onComplete(value, Optional.<Exception>empty()));
|
||||
this.callback.ifPresent(ac -> ac.onComplete(value, Optional.empty()));
|
||||
synchronized (lock) {
|
||||
lock.notifyAll();
|
||||
}
|
||||
|
@ -5,14 +5,14 @@ folder: balking
|
||||
permalink: /patterns/balking/
|
||||
categories: Concurrency
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Beginner
|
||||
- Decoupling
|
||||
---
|
||||
|
||||
## Intent
|
||||
Balking Pattern is used to prevent an object from executing certain code if it is an
|
||||
incomplete or inappropriate state
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## 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"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<!-- 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.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<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>
|
||||
|
||||
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>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>
|
||||
|
@ -5,9 +5,7 @@ folder: bridge
|
||||
permalink: /patterns/bridge/
|
||||
categories: Structural
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
- Difficulty-Intermediate
|
||||
- Gang of Four
|
||||
---
|
||||
|
||||
## Also known as
|
||||
@ -179,6 +177,9 @@ hammer.unwield();
|
||||
// The item's glow fades.
|
||||
```
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
Use the Bridge pattern when
|
||||
|
||||
@ -193,4 +194,5 @@ Use the Bridge pattern when
|
||||
|
||||
## 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"?>
|
||||
<!--
|
||||
|
||||
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.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>bridge</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- 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>bridge</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</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.bridge.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -5,9 +5,7 @@ folder: builder
|
||||
permalink: /patterns/builder/
|
||||
categories: Creational
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
- Difficulty-Intermediate
|
||||
- Gang of Four
|
||||
---
|
||||
|
||||
## 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();
|
||||
```
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
Use the Builder pattern when
|
||||
|
||||
@ -130,5 +131,7 @@ Use the Builder pattern when
|
||||
|
||||
## Credits
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
* [Effective Java (2nd Edition)](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
|
||||
* [Effective Java](https://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"?>
|
||||
<!--
|
||||
|
||||
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.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>builder</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- 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>builder</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.builder.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -3,10 +3,9 @@ layout: pattern
|
||||
title: Business Delegate
|
||||
folder: business-delegate
|
||||
permalink: /patterns/business-delegate/
|
||||
categories: Business Tier
|
||||
categories: Structural
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Intermediate
|
||||
- Decoupling
|
||||
---
|
||||
|
||||
## 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,
|
||||
and interact with the business objects that make up the application.
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
@ -26,4 +26,4 @@ Use the Business Delegate pattern when
|
||||
|
||||
## 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"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<!-- 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">
|
||||
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.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>business-delegate</artifactId>
|
||||
<dependencies>
|
||||
@ -45,4 +37,23 @@
|
||||
<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.business.delegate.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -28,7 +28,7 @@ package com.iluwatar.business.delegate;
|
||||
*/
|
||||
public class Client {
|
||||
|
||||
private BusinessDelegate businessDelegate;
|
||||
private final BusinessDelegate businessDelegate;
|
||||
|
||||
public Client(BusinessDelegate businessDelegate) {
|
||||
this.businessDelegate = businessDelegate;
|
||||
|
@ -28,5 +28,5 @@ package com.iluwatar.business.delegate;
|
||||
*/
|
||||
public enum ServiceType {
|
||||
|
||||
EJB, JMS;
|
||||
EJB, JMS
|
||||
}
|
||||
|
@ -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/
|
||||
categories: Behavioral
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Beginner
|
||||
- Game programming
|
||||
---
|
||||
|
||||
## Intent
|
||||
Allows to encode behaviour as instructions for virtual machine.
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
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:
|
||||
|
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"?>
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<!-- 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.22.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
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>bytecode</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<artifactId>bytecode</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.bytecode.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -30,9 +30,9 @@ import java.util.Stack;
|
||||
*/
|
||||
public class VirtualMachine {
|
||||
|
||||
private Stack<Integer> stack = new Stack<>();
|
||||
private final Stack<Integer> stack = new Stack<>();
|
||||
|
||||
private Wizard[] wizards = new Wizard[2];
|
||||
private final Wizard[] wizards = new Wizard[2];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -104,7 +104,7 @@ public class VirtualMachineTest {
|
||||
bytecode[2] = LITERAL.getIntValue();
|
||||
bytecode[3] = 50; // health amount
|
||||
bytecode[4] = SET_HEALTH.getIntValue();
|
||||
bytecode[5] = LITERAL.getIntValue();;
|
||||
bytecode[5] = LITERAL.getIntValue();
|
||||
bytecode[6] = wizardNumber;
|
||||
bytecode[7] = GET_HEALTH.getIntValue();
|
||||
|
||||
|
@ -3,11 +3,10 @@ layout: pattern
|
||||
title: Caching
|
||||
folder: caching
|
||||
permalink: /patterns/caching/
|
||||
categories: Other
|
||||
categories: Behavioral
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Intermediate
|
||||
- Performance
|
||||
- Performance
|
||||
- Cloud distributed
|
||||
---
|
||||
|
||||
## 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
|
||||
fast-access storage, and are re-used to avoid having to acquire them again.
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## 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)
|
||||
* [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>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>caching</artifactId>
|
||||
<dependencies>
|
||||
@ -41,7 +41,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver</artifactId>
|
||||
<version>3.0.4</version>
|
||||
<version>3.12.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
@ -69,6 +69,21 @@
|
||||
<skipTests>false</skipTests>
|
||||
</configuration>
|
||||
</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>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -29,7 +29,7 @@ package com.iluwatar.caching;
|
||||
public enum CachingPolicy {
|
||||
THROUGH("through"), AROUND("around"), BEHIND("behind"), ASIDE("aside");
|
||||
|
||||
private String policy;
|
||||
private final String policy;
|
||||
|
||||
CachingPolicy(String policy) {
|
||||
this.policy = policy;
|
||||
|
@ -3,19 +3,72 @@ layout: pattern
|
||||
title: Callback
|
||||
folder: callback
|
||||
permalink: /patterns/callback/
|
||||
categories: Other
|
||||
categories: Idiom
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Beginner
|
||||
- Functional
|
||||
- Idiom
|
||||
- Reactive
|
||||
---
|
||||
|
||||
## Intent
|
||||
Callback is a piece of executable code that is passed as an
|
||||
argument to other code, which is expected to call back (execute) the argument
|
||||
at some convenient time.
|
||||
Callback is a piece of executable code that is passed as an argument to other code, which is expected to call back
|
||||
(execute) the argument 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
|
||||
|
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>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>callback</artifactId>
|
||||
<dependencies>
|
||||
@ -39,4 +39,23 @@
|
||||
<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.callback.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -33,7 +33,7 @@ public abstract class Task {
|
||||
/**
|
||||
* Execute with callback.
|
||||
*/
|
||||
final void executeWith(final Callback callback) {
|
||||
final void executeWith(Callback callback) {
|
||||
execute();
|
||||
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/
|
||||
categories: Behavioral
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
- Difficulty-Intermediate
|
||||
- Gang of Four
|
||||
---
|
||||
|
||||
## Intent
|
||||
@ -67,7 +65,7 @@ Then the request handler hierarchy
|
||||
```java
|
||||
public abstract class RequestHandler {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
|
||||
private RequestHandler next;
|
||||
private final RequestHandler next;
|
||||
|
||||
public RequestHandler(RequestHandler next) {
|
||||
this.next = next;
|
||||
@ -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"
|
||||
```
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
## Applicability
|
||||
Use Chain of Responsibility when
|
||||
|
||||
@ -156,4 +157,5 @@ Use Chain of Responsibility when
|
||||
|
||||
## 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>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.22.0-SNAPSHOT</version>
|
||||
<version>1.23.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>chain</artifactId>
|
||||
<dependencies>
|
||||
@ -39,4 +39,23 @@
|
||||
<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.chain.App</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -33,7 +33,7 @@ public abstract class RequestHandler {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
|
||||
|
||||
private RequestHandler next;
|
||||
private final RequestHandler next;
|
||||
|
||||
public RequestHandler(RequestHandler next) {
|
||||
this.next = next;
|
||||
|
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;
|
||||
}
|