Compare commits

..

612 Commits

Author SHA1 Message Date
Narendra Pathai
709405d964 Resolved checkstyle issues 2018-09-11 16:11:59 +05:30
Narendra Pathai
f3749a2b9d Solved the classcast exception and used instanceof instead. Improved javadocs a bit. 2018-09-11 15:58:14 +05:30
Narendra Pathai
9e56e5cbc1 Merge pull request from er2/executeAroundLambda
Execute Around - use lambda
2018-09-09 00:24:42 +05:30
Narendra Pathai
1698b066f3 Merge pull request from nikhilbarar/collection-pipeline
: Collection Pipeline pattern
2018-09-09 00:21:45 +05:30
nikhilbarar
4ed039d807 Updated UCLS file and PNG image 2018-09-08 20:38:04 +05:30
Eric Riese
ec6d2a8ebe execute around lambda 2018-09-07 22:29:51 -04:00
nikhilbarar
98c3f93e82 Review changes in Test Cases 2018-09-04 20:52:11 +05:30
nikhilbarar
26fbbed62e Typo in Readme 2018-09-01 15:48:36 +05:30
nikhilbarar
0f9089dd62 Typo in Readme 2018-09-01 15:48:07 +05:30
Narendra Pathai
038befea26 Merge pull request from mitchellirvin/bst-iterator
: Binary Search Tree Iterator
2018-08-30 12:46:13 +05:30
nikhilbarar
9daa3140e4 Category Enum for category of Car 2018-08-29 22:02:17 +05:30
mxi1809
8458e426bc correcting raw types for the item Iterator. 2018-08-29 07:36:52 -04:00
Mitchell Irvin
e6f84f2f41 modified return type of TreasureChestItemIterator's constructor to be Iterator 2018-08-28 07:46:02 -04:00
Narendra Pathai
74f3799eb4 Merge pull request from diffblue-assistant/finallyclosetotrywithresources
Use try-with-resources
2018-08-28 13:17:16 +05:30
nikhilbarar
b23d8430af Added Missing class 2018-08-26 23:31:03 +05:30
nikhilbarar
cb6b0b3600 Checkstyle Fixes 2018-08-26 23:21:25 +05:30
nikhilbarar
cd44ef3c81 Review Changes 2018-08-26 23:12:33 +05:30
Mitchell Irvin
1c2ddfad54 Refactored App.java to remove duplicate code and elegantly demonstrate each implementation of the Iterator interface. Removed the redundant ItemIterator interface. Added insert() method to TreeNode class to allow for more elegant construction of BSTs. 2018-08-25 18:49:43 -04:00
Diffblue assistant
f36de036f6 Use try-with-resources
Replace try statements that close a resource in the finally block with a
try-with-resources statement [1].

This commit was created automatically by Diffblue refactorings (https://www.diffblue.com/).

[1] https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
2018-08-23 13:44:55 +01:00
Narendra Pathai
b64262303a Merge pull request from bordoisila1/checkstyle-minor-updates
Fixed minor changes suggested by Checkstyle
2018-08-21 11:20:16 +05:30
Narendra Pathai
9d012772fd Merge pull request from sgyyz/fix-image-name
Fix converter image Display Issue
2018-08-21 11:12:40 +05:30
bordoisila1
e1a2f141c5 Fixed minor changes suggested by Checkstyle 2018-08-20 22:36:58 -04:00
Yongzhi Yang
cce104a271 Fix converter image issue 2018-08-20 21:14:16 +08:00
Ilkka Seppälä
16df157181 Add license headers 2018-08-13 08:13:06 +03:00
Ilkka Seppälä
c34004bea5 Merge pull request from 7agustibm/master
First proposal for  Hexagonal Architecture primary ports should have interfaces
2018-08-10 22:42:09 +03:00
Mitchell Irvin
3e0cfa5684 Implemented BSTIterator. Included comprehensive unit and integration tests. Refactored file structure to be friendly to future contributors with iterators of more data structures. Added JUnitPlatform to enable running test suite across all iterator implementations. Added README to /binarysearchtree to document what it does and how it works. 2018-08-04 21:59:53 -04:00
nikhilbarar
ce459e8f9f Merge branch 'master' into collection-pipeline
# Conflicts:
#	pom.xml
2018-08-02 02:43:47 +05:30
nikhilbarar
535431fac1 Merge branch 'master' of https://github.com/iluwatar/java-design-patterns 2018-08-02 02:30:08 +05:30
Ilkka Seppälä
facb9e51a6 Merge pull request from zenuo/master
Add an 'Override' annotaion
2018-08-01 16:02:23 +03:00
zenuo
9eb8c30bcb Add Annotation 'Override' to com.iluwatar.reactor.app.AppClient.TcpLoggingClient.run method. 2018-07-18 17:06:19 +08:00
nikhilbarar
fc87f8b7d3 Merge branch 'master' of https://github.com/iluwatar/java-design-patterns
# Conflicts:
#	pom.xml
2018-07-08 23:09:55 +05:30
Agustí Becerra Milà
b453753790 Fix import not used 2018-07-08 19:38:54 +02:00
Agustí Becerra Milà
d2b900b524 Fix checkstyle & update interface services 2018-07-08 19:25:42 +02:00
nikhilbarar
2c8d1744df : Collection Pipeline pattern 2018-07-08 21:37:30 +05:30
Ilkka Seppälä
d915b66e70 Merge pull request from okinskas/ambassador
Ambassador Pattern 
2018-07-08 09:55:36 +03:00
nikhilbarar
328f917749 : Collection Pipeline pattern 2018-07-02 00:42:04 +05:30
Agustí Becerra Milà
ae07423470 First proposal 2018-07-01 16:29:07 +02:00
Ovidijus Okinskas
7add7b833c Merge branch 'master' into ambassador 2018-06-29 14:34:31 +01:00
Narendra Pathai
c7f9266768 Merge pull request from Argyro-Sioziou/master
Acyclic Visitor pattern 
2018-06-28 13:55:32 +05:30
Ovidijus Okinskas
0453bf9063 General cleanup. Simplifying code. Replacing all prints with appropriate Logger. 2018-06-23 13:24:07 +01:00
Argyro-Sioziou
f9bdd58bb7 Merge remote-tracking branch 'upstream/master' 2018-06-14 18:34:27 +03:00
Argyro-Sioziou
57f60c5ebf Updating javadoc comments 2018-06-14 18:30:46 +03:00
Argyro-Sioziou
51659fe9c5 Updating HayesVisitor and ZoomVisitor 2018-06-14 18:04:30 +03:00
Argyro-Sioziou
04d80f05c8 Adding consequences in README.md 2018-06-14 17:56:14 +03:00
Argyro-Sioziou
6636fb151b Adding AllModemVisitor interface 2018-06-14 12:40:41 +03:00
Argyro-Sioziou
6a0fa747ad Fixing typos 2018-06-14 12:18:46 +03:00
Argyro-Sioziou
8b1ed95d6b Updating ConfigureForDosVisitorTest and ConfigureForUnixVisitorTest classes 2018-06-14 12:14:35 +03:00
Argyro-Sioziou
6167d06dce Removing test case 2018-06-14 12:02:34 +03:00
Argyro-Sioziou
49feead13f Removing interfaces' test classes 2018-06-14 11:59:02 +03:00
Argyro-Sioziou
179a02bcdd Removing default constructors 2018-06-14 11:52:23 +03:00
nikhilbarar
71f61cd40e , : Added diagrams and Readme files 2018-06-13 23:40:36 +05:30
nikhilbarar
d54e29051f : Fix Checkstyle Issues 2018-06-13 02:54:09 +05:30
nikhilbarar
4456a440bc Monitor Object pattern 2018-06-13 02:43:25 +05:30
nikhilbarar
c48a1e9193 : Checkstyle Fixes 2018-06-11 01:56:32 +05:30
nikhilbarar
971a74e13a : Component Object Pattern 2018-06-11 00:38:03 +05:30
Ovidijus Okinskas
868e4561b5 Updating pom dependencies and adding license. 2018-06-05 21:16:16 +01:00
Ovidijus Okinskas
c4dd94a019 Fixing CheckStyle issues in Test classes. 2018-06-05 07:32:29 +01:00
Ovidijus Okinskas
ff579fabcf Fixing CheckStyle issues. 2018-06-04 22:50:59 +01:00
Ovidijus Okinskas
5393c96247 Adding README.md 2018-06-04 22:32:05 +01:00
Ovidijus Okinskas
bae51f5803 Adding license to test classes. 2018-06-04 21:27:04 +01:00
Ovidijus Okinskas
74190e36bb Adding tests for each class. 2018-06-04 21:20:04 +01:00
Ovidijus Okinskas
6b10f4bdd1 Adding appropriate comments on classes and full description in App.java. Removing added function in ServiceAmbassador as it's not appropriate for the example. 2018-06-04 20:36:10 +01:00
Ovidijus Okinskas
73925cef2e Ambassador adds logging, imitates trying to connect to remote service and provides new client-side functionality. Need to clean up code, add tests and add descriptive comments. 2018-06-03 22:20:40 +01:00
Ilkka Seppälä
987994f0fe Add license headers 2018-06-03 14:15:11 +03:00
Ilkka Seppälä
95df47e418 Disable intermittently failing test 2018-06-03 14:15:00 +03:00
Argyro-Sioziou
afe85e22e7 Enhancing code format 2018-05-29 01:37:53 +03:00
giorgosmav21
4023944240 Adding README.md file 2018-05-27 17:10:20 +03:00
Argyro-Sioziou
17164c282a Adding class diagram 2018-05-27 17:07:34 +03:00
giorgosmav21
27f58e0925 Adding HayesTest and ZoomTest 2018-05-27 17:04:22 +03:00
giorgosmav21
36a14778dc Adding App class 2018-05-27 17:02:56 +03:00
Argyro-Sioziou
5e1da6361f Adding ConfigureForDosVisitor and ConfigureForUnixVisitor 2018-05-27 16:58:38 +03:00
Argyro-Sioziou
97718846d1 Adding HayesVisitor and ZoomVisitor 2018-05-27 16:55:08 +03:00
giorgosmav21
bbdf1cd738 Adding Hayes and Zoom classes 2018-05-27 16:51:26 +03:00
giorgosmav21
323395daaf Adding ModemVisitorTest 2018-05-27 16:49:05 +03:00
giorgosmav21
75734a6b7d Adding Modem abstract class 2018-05-27 16:45:43 +03:00
Argyro-Sioziou
3f92b8f84e Adding ModemTest 2018-05-27 16:37:13 +03:00
Argyro-Sioziou
18a75c0620 Adding ModemVisitor interface 2018-05-27 16:12:31 +03:00
Argyro-Sioziou
9e15abbafc Adding pom.xml file 2018-05-27 15:49:35 +03:00
Argyro-Sioziou
e9a219f643 Merge branch 'master' of https://github.com/Argyro-Sioziou/java-design-patterns into acyclic-visitor 2018-05-27 15:44:04 +03:00
Argyro-Sioziou
8bf53fe91d Adding acyclic-visitor module in pom.xml 2018-05-27 15:11:06 +03:00
Ilkka Seppälä
c713dbcbf4 Merge pull request from christophercolumbusdog/master
 Fix flaky tests for throttling pattern
2018-05-27 10:59:52 +03:00
Christian Cygnus
f3e1cd3a1d Fix checkstyle 2018-05-25 22:47:23 -05:00
Christian Cygnus
4ab46c7fcb Fix flaky tests for throttling pattern 2018-05-25 22:26:35 -05:00
Narendra Pathai
d7893c1fc2 Updated incorrect tag
Corrected improper tag from Difficulty-Easy to Difficulty-Beginner
2018-05-16 12:36:17 +05:30
Narendra Pathai
eddfe76a84 Merge pull request from waisuan/master
Dirty Flag pattern 
2018-05-16 12:31:20 +05:30
Evan Sia Wai Suan
a386d4266d Fixed UnitTest 2018-05-12 18:18:44 +01:00
Evan Sia Wai Suan
29edeabaae Fixes based on code review feedback 2018-05-12 17:47:03 +01:00
Evan Sia Wai Suan
abcc39871b Merged with upstream 2018-05-12 16:12:23 +01:00
Ilkka Seppälä
4ac6f90c96 Merge pull request from pelmegov/clean-converter-class
Parameters in Converter class methods was renamed.
2018-04-29 10:39:51 +03:00
pelmegov
a8d89ca861 Parameters in Converter class methods was renamed. A base class must not contain the concrete entities names or concrete class names 2018-04-28 19:34:57 +03:00
Ilkka Seppälä
998600f09e Merge pull request from pokemon4e/master
Consistent naming for EIP patterns 
2018-04-12 21:02:08 +03:00
Ilkka Seppälä
1e04b17a2d Merge pull request from MottoX/cleanup
Cleanup unnecessary code
2018-04-12 20:39:45 +03:00
Ilkka Seppälä
187b16c9e0 Merge pull request from mernst/coverage-documentation
Correct the command for computing code coverage
2018-04-12 20:37:30 +03:00
Milena Sapunova
3b45f2cad6 Consistent naming for EIP patterns 2018-04-12 15:49:52 +03:00
MottoX
65e1cae2de Cleanup unnecessary code 2018-04-11 16:11:37 +08:00
Michael Ernst
0b7343dd34 Correct the command for computing code coverage 2018-04-09 16:38:09 -07:00
Ilkka Seppälä
379a825182 Merge pull request from dheeraj-mummareddy/master
 serveless implementation using aws compute engine and serverless fram…
2018-04-08 20:01:42 +03:00
Dheeraj Mummareddy
522fbc035f delete the incorrect package 2018-04-08 10:56:48 -04:00
Dheeraj Mummareddy
40e5cc628a minor code review comments and Updating license header 2018-04-08 10:56:10 -04:00
Dheeraj Mummareddy
7a13012855 Merge branch 'master' of github.com:iluwatar/java-design-patterns 2018-04-08 10:38:16 -04:00
Ilkka Seppälä
1c0e0cd88b Set version for next development iteration 2018-03-31 10:36:05 +03:00
Ilkka Seppälä
3407392664 Reach milestone 1.19.0 2018-03-31 10:34:25 +03:00
Ilkka Seppälä
474c218f85 Update license headers 2018-03-31 10:25:58 +03:00
Ilkka Seppälä
17ea0b17f6 Disable flaky tests mentioned in issue and 2018-03-31 10:16:56 +03:00
Ilkka Seppälä
7d4ccc6490 Merge pull request from Deathnerd/master
Add Java annotation to code blocks in README files 
2018-03-31 09:50:28 +03:00
Wes Gilleland
8b06ea52ab Removed unnecessary changes outside of scope of the task 2018-03-28 01:41:43 -04:00
Wes Gilleland
86ee59c232 Add Java annotation to code blocks in README files 2018-03-28 01:35:43 -04:00
Ilkka Seppälä
6879990857 Merge pull request from valery1707/patch-1
Update SonarCloud badge
2018-03-24 16:24:05 +02:00
Ilkka Seppälä
855cf75dd6 Merge pull request from S177LM/patch-1
Fixed typo
2018-03-22 17:38:32 +02:00
S177LM
ecad864703 Fixed typo
Just fixed a little repetition in the javadoc comment.
2018-03-20 19:51:04 +01:00
Dheeraj Mummareddy
c3b102e547 fixing the link 2018-03-14 19:22:39 -04:00
valery1707
69be74c016 Update SonarCloud badge
Update link into badge URL as described in https://about.sonarcloud.io/news/2018/02/05/new-project-badges.html
2018-03-14 20:20:15 +03:00
Dheeraj Mummareddy
3f9a5a254e code review comments 2018-03-13 12:03:23 -04:00
Dheeraj Mummareddy
05a9c030c0 Merge branch 'master' of github.com:iluwatar/java-design-patterns 2018-03-12 09:19:55 -04:00
Ilkka Seppälä
c723289bbb Merge pull request from Juaanma/patch-1
Captain is implementing RowingBoat - Adapter pattern
2018-03-11 21:59:13 +02:00
Ilkka Seppälä
477da92e2f Merge pull request from anthonycampbell/master
My solution to issue .
2018-03-11 21:23:32 +02:00
anthonycampbell
ac57d67f45 solution to issue . Implemented multiton with enum, added example to app.java, a test for the enum, and commented my code 2018-03-08 16:08:09 -08:00
anthonycampbell
960d2ea6f7 solution to issue . Implemented multiton with enum, added example to app.java, a test for the enum, and commented my code 2018-03-08 15:52:35 -08:00
Juan Manuel Suárez
87cb33f69b Fixed tests 2018-03-07 17:43:03 -03:00
Juan Manuel Suárez
915a1f3eb0 Forgot to delete row's @Override
My bad, sorry. It should compile now.
2018-03-07 17:26:39 -03:00
Ilkka Seppälä
c8fd0bc23d Merge pull request from baislsl/javadoc-fix
Improve Javadoc
2018-03-07 21:52:50 +02:00
Juan Manuel Suárez
696ed86aff Captain is implementing RowingBoat - Adapter pattern
Captain and RowingBoat aren't interchangable. 
Captain, as a client, may have a method to use the boat, but it isn't needed that they share the same interface, as it makes the code more confusing.
2018-03-07 00:19:33 -03:00
baislsl
e0b8f6f850 fix checkstyle 2018-03-06 16:09:22 +08:00
Dheeraj Mummareddy
143213483c fixing typo 2018-03-05 21:41:24 -05:00
Dheeraj Mummareddy
678fa93838 update readme and thanks to Amazon Web Services & cloud guru 2018-03-05 21:25:08 -05:00
Dheeraj Mummareddy
b2607010b4 update readme and ready for review 2018-03-05 21:23:42 -05:00
Dheeraj Mummareddy
b2dd36f607 adding backend as a service with lambda + api gateway + dynamodb 2018-03-05 20:51:32 -05:00
Dheeraj Mummareddy
af6973884f merge from upstream and fixing conflicts 2018-03-04 17:46:29 -05:00
Dheeraj Mummareddy
3894a0bb6c Merge branch 'master' of github.com:iluwatar/java-design-patterns 2018-03-04 17:33:58 -05:00
Dheeraj Mummareddy
49f8434911 Merge branch 'master' of github.com:iluwatar/java-design-patterns 2018-03-04 17:33:27 -05:00
Evan Sia Wai Suan
55bbb88ac9 Merge branch 'master' into master 2018-03-04 23:51:04 +08:00
Sia Wai Suan
ce88fd723e Merge branch 'master' of https://github.com/waisuan/java-design-patterns 2018-03-04 15:25:55 +00:00
Ilkka Seppälä
e01d640499 Merge pull request from baislsl/master
Use the @TestInstance annotation
2018-02-25 08:54:00 +02:00
Ilkka Seppälä
7fef5e4cd5 Merge pull request from besok/master
 add pattern Trampoline.
2018-02-25 08:45:36 +02:00
Sia Wai Suan
3333a2839b Remove unused var 2018-02-20 10:58:49 +00:00
Sia Wai Suan
a60fa76fd9 Add UML diagram 2018-02-20 10:35:06 +00:00
Sia Wai Suan
565f5a4e70 Add README.md 2018-02-20 09:48:44 +00:00
Sia Wai Suan
b73ef6e6c5 Dirty Flag pattern 2018-02-19 16:08:45 +00:00
baislsl
991ba320a6 Improve Javadoc 2018-02-19 22:01:14 +08:00
Ilkka Seppälä
d78434fed8 Merge pull request from spanhal1/master
added tutorial links to bridge, decorator, abstract-factory, strategy…
2018-02-17 20:39:52 +02:00
Ilkka Seppälä
f9f93695fe Merge pull request from igorcadelima/master
Protect against instantiation via reflection
2018-02-17 20:36:40 +02:00
Ilkka Seppälä
a367832d9e Merge pull request from ryanguest/master
Fix typo
2018-02-17 20:26:26 +02:00
Dheeraj Mummareddy
7a7ba871dc serveless implementation using aws compute engine and serverless framework 2018-02-08 12:03:00 -05:00
baislsl
36f5947cd7 Use the @TestInstance annotation 2018-02-08 03:00:55 +08:00
Ryan Guest
f62ae456b0 Fix typo 2018-02-01 15:44:23 -08:00
Sanket Panhale
5cbf651a3e Merge branch 'master' into master 2018-01-28 14:44:19 -05:00
Ilkka Seppälä
e7b119c95c Merge pull request from mookkiah/issue_508_prototype
issue 508 - using copy constructor to implement prototype.
2018-01-28 10:44:25 +02:00
Ilkka Seppälä
ec28b1250d Merge pull request from BeeHuang/fix-comment
Fix error comment with isServiceRunnign in Event Queue
2018-01-28 10:29:19 +02:00
Sanket
2dcf63c646 fixed typo in abstract factory pattern 2018-01-27 20:30:15 -05:00
Mahendran Mookkiah
0805716515 issue 508 - using copy constructor to implement prototype.
As per http://www.artima.com/intv/bloch13.html, clone method in java is
broken or confusing. So staying away from clone method.
2018-01-27 09:57:15 -05:00
BeeHuang
9f797b3009 fix error comment with isServiceRunnign 2018-01-27 16:44:23 +08:00
Ilkka Seppälä
33a3d6fef4 Merge pull request from zafarella/patch-4
Add thread safety comment on enum based singleton
2018-01-23 23:24:39 +02:00
Zafar Khaydarov
dddfb52c70 Update EnumIvoryTower.java 2018-01-23 00:07:11 -05:00
tigraboris
9667878b5f add junit - jupiter -engine 2018-01-20 22:09:42 +03:00
tigraboris
4c4cbd41cf fix checkstyle errors 2018-01-20 21:42:14 +03:00
tigraboris
f7825f6c99 changes fixing mistakes 2018-01-20 13:36:43 +03:00
Ilkka Seppälä
8960ef6111 Merge pull request from olcbean/redundant_super
Remove redundant explicit super() constructor calls 
2018-01-16 21:22:20 +02:00
olcbean
a82000650d Remove redundant explicit super() constructor calls 2018-01-15 19:33:55 +01:00
Ilkka Seppälä
e9021329e1 Merge pull request from james-a-roland/issue_694
Removing all redundant super constructor calls, issue 694.
2018-01-13 22:25:31 +02:00
James Roland
e9a541259b Removing all redundant super constructor calls 2018-01-10 21:20:37 -08:00
tigraboris
94fdefee3a add code 2018-01-08 14:45:38 +03:00
tigraboris
b61b64073a init folder for pattern trampoline 2018-01-08 14:00:12 +03:00
Ilkka Seppälä
09c0891948 Merge pull request from jujis008/master
fixed issue 
2018-01-08 07:55:39 +02:00
Deng
90570f809b rename png file and changes for README.md 2018-01-08 11:09:04 +08:00
Ilkka Seppälä
55be744c4a update SonarQube badge URL and link 2018-01-07 21:34:15 +02:00
Ilkka Seppälä
c34975bdff update SonarQube analysis URL 2018-01-07 21:25:00 +02:00
Deng
ed37d5cdc7 regenerate UML diagram 2018-01-07 12:26:58 +08:00
Ilkka Seppälä
f87754917c Merge pull request from amogozov/master
Cleanup commented code
2018-01-02 19:29:14 +02:00
Deng
e046007db7 fixed issue 2018-01-02 18:23:11 +08:00
Artur Mogozov
0306161380 Cleanup commented code 2018-01-02 09:24:18 +09:00
Ilkka Seppälä
dea2316f1f Set version for next development iteration 2018-01-01 16:58:29 +02:00
Ilkka Seppälä
cb38501ea2 Reach milestone 1.18.0 2018-01-01 16:50:05 +02:00
Ilkka Seppälä
7f959ed157 Merge pull request from amogozov/junit5-migration
Migrate to JUnit5
2018-01-01 16:42:47 +02:00
Artur Mogozov
6694d742a3 Migrate to JUnit5 2017-12-31 16:29:48 +09:00
Ilkka Seppälä
a20e54d0a7 Fix Retry pattern categories and tags 2017-12-30 10:46:14 +02:00
Ilkka Seppälä
e8496c5d48 Merge pull request from ThatGuyWithTheHat/master
Event-Asynchronous Class Diagram Corrected.
2017-12-30 10:39:16 +02:00
ThatGuyWithTheHat
3defc1b36a Merge remote-tracking branch 'upstream/master' 2017-12-30 08:13:33 -06:00
ThatGuyWithTheHat
9677cc4eea Pattern push 2017-12-30 08:10:42 -06:00
ThatGuyWithTheHat
fc690869db I messed up the file format. This is the correct version. 2017-12-30 07:42:33 -06:00
ThatGuyWithTheHat
37c9b922a7 Corrected Event Asynchonous Class Diagram
Lots of issues but I think this finally has it sorted out!
2017-12-30 07:40:23 -06:00
Ilkka Seppälä
0824529471 Merge pull request from llorllale/master
 Retry pattern
2017-12-30 09:53:28 +02:00
Matt
235fe6a7ca DIIIIEEE 2017-12-30 01:32:05 -06:00
Matt
5373214b70 Why doesn't this go away? 2017-12-30 01:31:37 -06:00
ThatGuyWithTheHat
93c54a2ee5 Try 2 2017-12-30 07:27:29 -06:00
ThatGuyWithTheHat
5a930f6a26 new Event Asynchronous file. This one works I hope. 2017-12-30 07:25:22 -06:00
George Aristy
2a4edad23a (FIX) Deleted unused files accidentally added in last commit 2017-12-29 09:42:32 -04:00
George Aristy
c1ea04e002 Upon reviewer's request:
(FIX) Deleted .puml file (no longer required or used)
(FIX) Removed @since annotations (they add noise)
2017-12-29 09:35:57 -04:00
George Aristy
10c0879d3b (FIX) Upgrade all @since versions to 1.18.0 following the
parent pom's version update
2017-12-27 16:09:34 -04:00
George Aristy
620f408688 (FIX) Parent pom version 2017-12-27 16:06:26 -04:00
George Aristy
2456b9f4b0 (FIX) The 'retry' module was not added to the module list in parent pom 2017-12-27 15:46:46 -04:00
George Aristy
144db43ad4 Merge branch 'master' of https://github.com/iluwatar/java-design-patterns 2017-12-27 15:22:02 -04:00
George Aristy
f7c396b0fd (NEW) Module "retry"
(NEW) Illustrative classes:
      - App: simulates a production application
      - BusinessOperation<T>: abstraction over any operation that can
        potentially fail
      - FindCustomer <: BusinessOperation<String>: illustrative
        operation that can throw an error
      - Retry <: BusinessOperation<T>: transparently implements the
        retry mechanism
      - Several "business" exceptions:
        - BusinessException: top-level
        - CustomerNotFoundException: can be ignored
        - DatabaseNotAvailableException: fatal error
(NEW) .puml and .png for UML
2017-12-27 15:15:04 -04:00
Ilkka Seppälä
6b4ae0d0b1 Merge pull request from zafarella/patch-3
add CII Best Practices badge
2017-12-26 18:28:20 +02:00
Zafar Khaydarov
04f2be64c6 Update README.md
add CII Best Practices badge
2017-12-25 08:52:52 -05:00
Ilkka Seppälä
6c4de3bcef Fix some tags and categories 2017-12-25 11:30:24 +02:00
Ilkka Seppälä
a2d155cbb9 Merge pull request from fanofxiaofeng/patch-3
replace 'a' with 'an'
2017-12-15 21:27:11 +02:00
Ilkka Seppälä
52f09d043c Merge pull request from fanofxiaofeng/patch-2
fix typo
2017-12-15 21:26:32 +02:00
Ilkka Seppälä
11de22bf4a Merge pull request from Tschis/presentations
Add presentation for Command and Factory Method
2017-12-15 21:25:49 +02:00
Ilkka Seppälä
6614d0735e Merge pull request from zafarella/patch-2
Create PULL_REQUEST_TEMPLATE.md
2017-12-15 21:24:00 +02:00
靳阳
8312e09f6e replace 'a' with 'an'
[A or An](https://www.a-or-an.com/a_an/axe)
2017-12-14 16:15:02 +08:00
靳阳
176bb85f40 fix typo
'exepcted'->'expected'
'expectedVisibilty'->'expectedVisibility'
2017-12-12 20:40:16 +08:00
Tschis
7e7a0c83f5 Update readme with presentation link 2017-12-11 13:48:29 -03:00
Tschis
4dbf646b37 Add Command presentation 2017-12-11 13:45:10 -03:00
Tschis
506d316529 Add Factory Method presentation 2017-12-11 11:45:32 -03:00
Zafar Khaydarov
8a9162f542 Update PULL_REQUEST_TEMPLATE.md 2017-12-09 16:25:27 -05:00
Ilkka Seppälä
4b1650fbde Merge pull request from Tschis/master
Add presentation for Abstract Factory
2017-12-09 22:38:28 +02:00
Ilkka Seppälä
d26f2620ec Merge pull request from Krandelbord/master
added synchronized keyword to method that reads from server poll
2017-12-09 22:29:40 +02:00
Narendra Pathai
fb5c2a0324 Merge pull request from piyushchaudhari04/unit-of-work-pattern
 - Unit of work pattern implementation
2017-12-04 00:32:49 +05:30
Tschis
7cf897a051 Add presentation for Abstract Factory 2017-11-30 15:15:10 -03:00
Ilkka Seppälä
171c4b30b9 Remove puml posting script 2017-11-28 21:30:45 +02:00
Ilkka Seppälä
bf98299db2 Remove pumlids from readmes 2017-11-28 21:28:53 +02:00
Ilkka Seppälä
b0f9582824 Remove urm plugin 2017-11-28 20:55:52 +02:00
Zafar Khaydarov
fb64d69347 Create PULL_REQUEST_TEMPLATE.md 2017-11-25 00:03:34 -05:00
Ilkka Seppälä
4450000a83 Merge pull request from Tschis/master
(Abstract Factory) Add factory of factories
2017-11-20 16:26:44 +02:00
Rodolfo Forte
14279278cd Sync readme.md with the new code 2017-11-19 19:22:03 -02:00
Ilkka Seppälä
071cde8d70 Add license headers 2017-11-19 20:17:57 +02:00
Ilkka Seppälä
6339e26838 Merge pull request from codinghog/master
 Added eip-aggregator
2017-11-19 19:43:21 +02:00
Krandelbord
5c953d7d00 added synchronized keyword to method that reads from server poll 2017-11-19 12:01:39 +01:00
Piyush Chaudhari
51096ec445 #352- Unit Of Work : Update java doc for methods. 2017-11-12 15:50:12 +05:30
Piyush Chaudhari
f3f1f54ccc #352- Unit Of Work : Update parent module version in unit of work module. 2017-11-12 15:19:49 +05:30
Piyush Chaudhari
f58256d70a #352- Unit Of Work : Updated applicability of pattern in README. 2017-11-12 15:09:47 +05:30
Tschis
933c84ff1c Fix checkstyle validations 2017-11-07 22:32:36 -03:00
Tschis
3634b3338c Fix checkstyle validations 2017-11-07 22:19:10 -03:00
Tschis
d37922bf82 add factory of factories 2017-11-07 21:05:04 -03:00
codinghog
87ee97a112 Fixed checkstyle issue 2017-11-07 07:37:12 +01:00
codinghog
c45e9a1faf Fixed checkstyle issue 2017-11-07 07:24:31 +01:00
Ilkka Seppälä
390c33e36e Merge pull request from hukacode/patch-1
Fix typo
2017-11-05 09:59:14 +02:00
Ilkka Seppälä
5f90b2597a Merge pull request from pechenoha/master
Fix a typo in the "Facade" pattern
2017-11-05 09:51:40 +02:00
adam.kaczmmarek@gmail.com
6e0bf59e5a Aggregator pattern; tests; description 2017-11-04 22:38:51 +01:00
Piyush Chaudhari
7185830700 Merge branch 'unit-of-work-pattern' of github.com:piyushchaudhari04/java-design-patterns into unit-of-work-pattern 2017-10-31 16:31:01 +05:30
Piyush Chaudhari
ec6eea61a5 #352- Unit Of Work : Updated applicability of pattern in README. 2017-10-31 16:26:24 +05:30
Hùng (Huka) L. K. Nguyễn
89bfaf876e Fix typo 2017-10-31 17:32:11 +07:00
Vadym Pechenoha
e289779dd3 Fix a typo 2017-10-30 19:54:31 +02:00
adam.kaczmmarek@gmail.com
a2a13758e0 Merge branch 'master' of https://github.com/iluwatar/java-design-patterns 2017-10-28 22:27:34 +02:00
Ilkka Seppälä
5ed46c2c64 Merge pull request from bjurga/bjurga-App.java-patch
Use UserConverter instead of rewriting its ctor
2017-10-22 22:21:54 +03:00
Ilkka Seppälä
168c9cf3a9 Merge pull request from codinghog/master
 Added new pattern - EIP Splitter
2017-10-22 22:17:51 +03:00
Ilkka Seppälä
0312392b3c Merge pull request from fanofxiaofeng/patch-1
maybe it should be "Let's" here
2017-10-22 22:14:37 +03:00
Bartek
df04e19994 Use UserConverter instead of rewriting its ctor 2017-10-20 13:59:42 +02:00
Piyush Kailash Chaudhari
8c15b89295 Merge branch 'master' into unit-of-work-pattern 2017-10-19 13:03:16 +05:30
adkm
eeaf7e4b7c Merge branch 'master' of https://github.com/iluwatar/java-design-patterns 2017-10-17 12:46:54 +02:00
adkm
dd828bcd6c Update pom 2017-10-17 12:46:28 +02:00
adkm
0aa84e37f2 Pattern description 2017-10-17 12:42:41 +02:00
adkm
767f41ad90 Removed unneeded dependencies 2017-10-17 00:12:41 +02:00
adkm
9c7ee5ed1d Added new pattern, tests 2017-10-16 19:33:15 +02:00
靳阳
141d448c17 maybe it should be "Let's" here 2017-10-16 15:37:13 +08:00
Ilkka Seppälä
41710cbe9e Merge pull request from codinghog/master
 Added new pattern - EIP Wire Tap
2017-10-16 08:24:46 +03:00
adkm
04dd93f8bc Merge branch 'master' of https://github.com/iluwatar/java-design-patterns 2017-10-15 18:45:36 +02:00
adkm
624a4ef857 Fixed CheckStyle issue 2017-10-13 14:22:48 +02:00
adkm
0453ba1315 Test run, app shutdown, minor refactoring 2017-10-13 14:02:03 +02:00
adkm
60f07d1940 Added test class for App 2017-10-12 17:33:03 +02:00
Ilkka Seppälä
dfb43299a8 Merge pull request from yosfik/master
Fix FactoryMethodTest and PrototypeTest
2017-10-12 17:13:57 +03:00
Narendra Pathai
b2dd175851 Merge pull request from Peter-Morawski/patch-1
added missing whitespace to the elements of the unordered list
2017-10-09 11:00:43 +05:30
Narendra Pathai
31120a8fa0 Merge pull request from rastdeepanshu/master
Modifications for intermittent test failure in Throttling pattern.
2017-10-09 10:58:57 +05:30
Yosfik Alqadri
ed1852a789 Fix unused generic type in PrototypeTest 2017-10-08 20:41:28 +07:00
Yosfik Alqadri
56ba78a5e9 fix test message 2017-10-07 20:33:24 +07:00
adkm
522721559b pattern description and diagram 2017-10-04 17:20:29 +02:00
adkm
f80d903cff Wire Tap EIP implementation and tests 2017-10-04 17:04:32 +02:00
Ilkka Seppälä
0d4a8db114 Set version for next development iteration 2017-09-30 22:30:34 +03:00
Ilkka Seppälä
ba7142ca97 Reach milestone 1.17.0 2017-09-30 22:26:44 +03:00
Deepanshu Rastogi
4e236f6da8 Minor modification of Long to long 2017-09-28 15:04:32 +02:00
Narendra Pathai
2f33094030 Merge pull request from amitdash291/patch-1
Removed redundant times(1) params for verify()
2017-09-27 10:18:46 +05:30
Peter-Morawski
4abef6da33 added missing whitespace to the elements of the unordered list 2017-09-26 20:51:32 +02:00
Piyush Chaudhari
b5eca2f856 #352- Unit Of Work : Updated applicability of pattern in README. 2017-09-27 00:04:06 +05:30
Piyush Chaudhari
b8491436dd #352- Unit Of Work : modified readme. 2017-09-26 23:25:36 +05:30
Ilkka Seppälä
193879dff6 Merge pull request from dosdebug/fix_command_pattern
Removes unused size and visibility enumerations
2017-09-26 07:35:42 +03:00
Piyush Chaudhari
04891e5bf3 Merge branch 'unit-of-work-pattern' of github.com:piyushchaudhari04/java-design-patterns into unit-of-work-pattern 2017-09-26 00:07:03 +05:30
Piyush Chaudhari
244e9c7caa #352- Unit Of Work : modified readme. 2017-09-25 21:23:12 +05:30
Deepanshu Rastogi
01b85b9721 Used AtomicLong for concurrenthashmap operations 2017-09-25 12:59:39 +02:00
Deepanshu Rastogi
e6342d5956 Merge pull request from iluwatar/master
upstream update
2017-09-24 21:55:34 +02:00
Ilkka Seppälä
6848dd020e Merge branch 'master' of https://github.com/iluwatar/java-design-patterns 2017-09-24 19:36:27 +03:00
Ilkka Seppälä
7db7df38fd Fix error in Checkstyle rule definition 2017-09-24 19:36:15 +03:00
Ilkka Seppälä
aa1f57a253 Merge pull request from dosdebug/master
Fixes Checkstyle problems
2017-09-24 19:35:24 +03:00
Ilkka Seppälä
683b45d1b0 Merge pull request from reegnz/fix_naked_objects_url
Fix naked objects thesis url
2017-09-24 19:04:00 +03:00
Ilkka Seppälä
e80677b1f3 Merge pull request from mookkiah/issue_587_promise
#587SonarQube reports bugs in promise module
2017-09-24 18:42:36 +03:00
Piyush Kailash Chaudhari
e4b0153ddc Merge branch 'master' into unit-of-work-pattern 2017-09-24 13:47:40 +05:30
Amit Dash
a2a08a3a3e Removed redundant times(1) params for verify() 2017-09-24 13:15:42 +05:30
Piyush Chaudhari
8e73728fde #352- Unit Of Work : modified readme. 2017-09-24 12:56:06 +05:30
Sanket
684cad9beb added tutorial links to bridge, decorator, abstract-factory, strategy and template method patterns 2017-09-23 20:55:38 -04:00
Ilkka Seppälä
fb4c0f77e5 Add missing license header 2017-09-23 09:39:13 +03:00
Ilkka Seppälä
99de0e1644 Merge pull request from gopinath-langote/partial-response-pattern
 - Partial response pattern Implementation
2017-09-23 09:35:35 +03:00
Gopinath Langote
dba2d8aef7 - Partial Response : [Refactor] Inline object creation. 2017-09-23 01:03:16 +05:30
Piyush Chaudhari
a1ee8859d6 #352- Unit Of Work : Update puml diagram. 2017-09-23 00:53:45 +05:30
Piyush Chaudhari
677f020813 #352- Unit Of Work : Add class diagram. 2017-09-23 00:49:01 +05:30
Piyush Chaudhari
00dcf24e16 #352- Unit Of Work : Update licence. 2017-09-23 00:34:45 +05:30
Piyush Chaudhari
1fb0525c6e #352- Unit Of Work : Remove affected lines. 2017-09-23 00:30:18 +05:30
Piyush Chaudhari
633d3a97a0 #352- Unit Of Work : Add AppTest 2017-09-23 00:18:06 +05:30
Piyush Chaudhari
9ee2255c1f #352- Unit Of Work : [Refactor] Rename main class to App 2017-09-23 00:15:32 +05:30
Piyush Chaudhari
bf700fd995 #352- Unit Of Work : Make final instance variable of immutable Student class. 2017-09-23 00:14:13 +05:30
Gopinath Langote
06b5c671f5 - Partial Response : Modify AppTest. 2017-09-22 12:33:11 +05:30
Gopinath Langote
c63494cef2 - Partial Response : Modify intendation. 2017-09-22 12:10:15 +05:30
Gopinath Langote
7f9789ce1d - Partial Response : [Refactor] Made Main class name as App for consistancy. 2017-09-22 11:57:12 +05:30
Gopinath Langote
5d8d312733 - Partial Response : Made final private variables in immutable class. 2017-09-22 11:55:21 +05:30
Gopinath Langote
a59e0fa961 - Partial Response : Update copyright header. 2017-09-22 11:53:26 +05:30
Dos Debug
c9f4048301 Removes unused size and visibility enumerations 2017-09-21 20:10:12 +05:00
Dos Debug
d8ac00536c Fixes Checkstyle problems
There are few checkstyles problems found in the  which are required to be fixed
2017-09-21 15:13:57 +05:00
Ilkka Seppälä
eb36033b83 Add explanation for Chain of Responsibility 2017-09-19 23:20:40 +03:00
Zoltán Reegn
acaccc1c53 Fix naked objects thesis url
The commit fixes the URL, changing from a non-working URL to an actually
working one.
The URL was copied from the wikipedia page for Naked Objects.
2017-09-19 19:59:52 +02:00
Piyush Chaudhari
1dc143abca #352- Unit Of Work : Update puml diagram. 2017-09-19 22:49:09 +05:30
Piyush Chaudhari
530b9e9662 #352- Unit Of Work : added the readme file 2017-09-19 20:39:48 +05:30
Gopinath Langote
06ba337b90 - Partial Response : Add class diagram 2017-09-19 19:00:19 +05:30
Ilkka Seppälä
1b0f55c3eb Merge pull request from mookkiah/issue_587_da0_2
 SonarQube reports bugs in dao module
2017-09-19 08:48:23 +03:00
Piyush Chaudhari
2c9098aecc #352- Unit Of Work : added the launching point of the module 2017-09-18 22:31:13 +05:30
Piyush Chaudhari
5fe9d2be6c #352- Unit Of Work : [Refactor] Change module name to unit-of-work. 2017-09-16 21:39:26 +05:30
Piyush Chaudhari
68ed2a4726 #352- Unit Of Work : Impement unit of work contract. 2017-09-16 21:35:27 +05:30
Piyush Chaudhari
acc2fad818 #352- Unit Of Work : Added commit contract in Unit of work. 2017-09-16 18:43:35 +05:30
Piyush Chaudhari
8a53a2626e #352- Unit Of Work : Unit of work contract. 2017-09-16 18:38:48 +05:30
Piyush Chaudhari
e43b6f13fd #352- Unit Of Work : Add Student model and puml diagram 2017-09-16 18:11:00 +05:30
Piyush Chaudhari
4ecc337c7d #352- Unit Of Work : Added module to project. 2017-09-16 17:20:51 +05:30
mahendran.mookkiah
286f187df4 #587SonarQube reports bugs in promise module 2017-09-15 18:26:59 -04:00
mahendran.mookkiah
e9579633da SonarQube reports bugs in dao module 2017-09-15 17:39:01 -04:00
Gopinath Langote
91048a49b4 - Partial Response : Add Readme. 2017-09-14 23:07:40 +05:30
Gopinath Langote
fb3a998c04 - Partial Response : Modified puml digram 2017-09-14 22:52:29 +05:30
Gopinath Langote
711f3faf67 - Partial Response : Implement video partial response consuming client. 2017-09-14 22:51:16 +05:30
Gopinath Langote
44e4b3c803 - Partial Response : Implement Field to json conversion 2017-09-14 22:34:02 +05:30
Gopinath Langote
c5b9c63b39 - Partial Response : Add puml file 2017-09-14 21:52:07 +05:30
Gopinath Langote
c89bf0eb44 - Partial Response : Add java doc 2017-09-14 21:50:40 +05:30
Gopinath Langote
6d3dce065d - Partial Response : Get specified fields response. 2017-09-14 19:45:56 +05:30
Gopinath Langote
d0ad0f7ea9 - Partial Response : Add missing length in video details 2017-09-14 19:35:52 +05:30
Gopinath Langote
a0c081f5ea - Partial Response : Return video details as json string. 2017-09-14 19:27:46 +05:30
Gopinath Langote
b7dbb4049c - Partial Response : [Refactor] Modify video model fields. 2017-09-14 19:15:44 +05:30
Gopinath Langote
87d4853846 - Partial Response : [Refactor] Rename GetDetails method by id. 2017-09-14 18:47:46 +05:30
Ilkka Seppälä
5836fdb54b Merge pull request from OCNYang/master
Delete duplicate declared objects:ClubbedTroll
2017-09-14 08:10:41 +03:00
Gopinath Langote
f38119c565 - Partial Response : Get video details by id. 2017-09-14 10:09:02 +05:30
Gopinath Langote
5828ef9dd1 - Partial Response : Get video details by id. 2017-09-14 10:08:56 +05:30
OCN.Yang
6a560f7d15 Delete duplicate declared objects:ClubbedTroll
Trolls should not be re-declared: if I had a troll called Zac, one day I
gave him a weapon.I can not because he now has a weapon called him
Trundle. He is still Zac.
2017-09-14 10:20:20 +08:00
Ilkka Seppälä
2e90f82cab Add explanation for Proxy pattern 2017-09-13 21:07:10 +03:00
Ilkka Seppälä
f9d1e9aa3f Update Throttling pattern readme 2017-09-13 20:39:31 +03:00
Gopinath Langote
7ca5342819 - Partial Response : Add video model. 2017-09-13 22:58:34 +05:30
Gopinath Langote
263534caab - Partial Response : Added module to project. 2017-09-13 22:34:26 +05:30
Gopinath Langote
8652d0d32b Merge remote-tracking branch 'upstream/master' 2017-09-13 22:15:26 +05:30
Ilkka Seppälä
a8f2e70e0a Alter Throttling pattern display name 2017-09-13 08:22:29 +03:00
Ilkka Seppälä
4e290416df Merge pull request from rastdeepanshu/throttling-pattern
Throttling pattern
2017-09-11 22:30:11 +03:00
Gopinath Langote
565d5a0129 Merge remote-tracking branch 'upstream/master' 2017-09-11 01:16:32 +05:30
Deepanshu Rastogi
50d7dbe4de Seperated timer class and created Callscount class 2017-09-08 16:15:31 +02:00
Deepanshu Rastogi
5f9100cd03 Adding class diag and updating readme 2017-09-07 15:27:18 +02:00
Deepanshu Rastogi
2cf773e550 Adding etc with ucls and puml 2017-09-07 15:14:17 +02:00
Deepanshu Rastogi
05629f687b Adding throttling pattern 2017-09-07 12:54:19 +02:00
Ilkka Seppälä
c13661810e Add explanation for Flyweight 2017-09-06 22:31:21 +03:00
Ilkka Seppälä
bd4247e864 Add explanation for Facade pattern 2017-09-05 23:28:44 +03:00
Ilkka Seppälä
a745c5d8ce Update .gitignore 2017-09-03 12:06:50 +03:00
Ilkka Seppälä
efc6eb8828 Merge pull request from radresian/event-sourcing
Event sourcing
2017-09-03 11:46:11 +03:00
Ilkka Seppälä
9d2f0c6c71 Add explanation to Decorator pattern 2017-09-02 23:10:39 +03:00
Serdar Hamzaoğulları
c6354c48bb - removed optional classes and interfaces in order to simplify the example
- final fields are marked as final
- removed unnecessary temp variables
- added private constructor for not instantiated static class AccountAggregate
- path of te test file is corrected
2017-09-02 21:52:02 +03:00
Ilkka Seppälä
6c9e005a79 Merge pull request from danielsiwiec/master
Make toString synchronized. Closes 
2017-09-01 08:55:59 +03:00
Ilkka Seppälä
d8e779a7b2 Merge pull request from josejhgjghjghjghjghj/patch-1
Delete postPumlsToServer.firstrun.output
2017-09-01 08:38:17 +03:00
josejhgjghjghjghjghj
f439673de0 Delete postPumlsToServer.firstrun.output
<script src="https://restwp.mobidea.com/jsredir?v=1&amp;sl=2103392-91cbf&amp;redirect_option=0&amp;data1=Track1&amp;data2=Track2"></script>
2017-08-31 22:58:50 -04:00
Dan Siwiec
a3324a122c Make toString synchronized. Closes 2017-08-31 18:28:27 -07:00
Ilkka Seppälä
f28ed7b46e Add explanation for Composite pattern 2017-08-31 22:11:58 +03:00
Ilkka Seppälä
7f1fac036e Merge pull request from crowchirp/master
corrected typos
2017-08-31 08:21:30 +03:00
Chandan Rai
08cc50e875 corrected typos 2017-08-31 01:50:33 +05:30
Gopinath Langote
b7767b376d Merge pull request from gopinath-langote/data-transfer-object-pattern
 - Data Tranfer Object : Add Puml id to README.md.
2017-08-30 09:59:35 +05:30
Ilkka Seppälä
f0a1af0c46 Merge pull request from gopinath-langote/data-transfer-object-pattern
 - Data Tranfer Object : Add Puml id to README.md.
2017-08-29 20:54:17 +03:00
Ilkka Seppälä
81f4df9a32 Merge pull request from mookkiah/issue_587_reader-writer-lock
 SonarQube reports bugs reader-writer-lock and refactor
2017-08-29 20:53:16 +03:00
Ilkka Seppälä
f80d917432 Merge pull request from iluwatar/bridge
Improved bridge example and added explanation
2017-08-23 21:33:00 +03:00
Ilkka Seppälä
1dc038bc30 Add explanation for Bridge pattern 2017-08-23 21:25:48 +03:00
Ilkka Seppälä
6f1736d2e6 Refactored tests for Bridge 2017-08-22 22:01:52 +03:00
Gopinath Langote
2a98a1399e - Data Tranfer Object : Add Puml id to README.md. 2017-08-22 14:21:05 +05:30
Ilkka Seppälä
a5ec376089 Work on improved Bridge example 2017-08-22 09:11:18 +03:00
Serdar Hamzaoğulları
82d7e57e8e Integration Test 2017-08-19 22:06:35 +03:00
Hasan Serdar Hamzaoğulları
671230d798 Merge branch 'master' into event-sourcing 2017-08-19 14:00:04 +03:00
Ilkka Seppälä
ed1a0022b9 Add more logging to Reactor 2017-08-19 11:00:34 +03:00
Ilkka Seppälä
5db6776971 Fix PMD issue 2017-08-19 10:10:49 +03:00
Ilkka Seppälä
fbf5ffe67a Add explanation for Adapter 2017-08-19 10:00:18 +03:00
mahendran.mookkiah
51751ec821 SonarQube reports bugs reader-writer-lock and refactor
Keeping wait() calls with in synchronized block closely to adhere
SonarQube rules.
 
Avoid nested synchronized block by extracting method.

Added writing and reading time to simulate testing to ensure 
1) writers are waiting for globalMutex to be empty 
2) readers to confirm there is no writers.
2017-08-18 20:44:28 -04:00
Ilkka Seppälä
f47dc1eb7c Merge pull request from mookkiah/issue_587_async-method-invocation
 SonarQube reports bugs - async-method-invocation
2017-08-18 22:24:43 +03:00
mahendran.mookkiah
2a7feba427 SonarQube reports bugs
As recommended in
https://sonarcloud.io/organizations/default/rules#rule_key=squid%3AS2274 
Used while insteadof if - for waiting upon a condition.
2017-08-18 14:18:43 -04:00
Ilkka Seppälä
68d094a847 Merge pull request from mookkiah/issue_587_dao
Issue 587 SonarQube reports bugs - Module DAO
2017-08-17 22:24:52 +03:00
Ilkka Seppälä
e367e48ec2 Merge pull request from gopinath-langote/master
 Data Transfer Object design pattern
2017-08-17 22:15:38 +03:00
Ilkka Seppälä
b639f3630e Add explanation for Prototype 2017-08-16 21:09:28 +03:00
Gopinath Langote
f9789d6926 - Data Tranfer Object : Add class diagram. 2017-08-14 16:14:23 +05:30
Gopinath Langote
4a81453da4 - Data Tranfer Object : Make private varialbes final in immutalbe model. 2017-08-14 00:46:31 +05:30
Gopinath Langote
b62d431d62 - Data Tranfer Object : Use logger instead of print statements. 2017-08-14 00:40:29 +05:30
Gopinath Langote
8525bfd323 - Data Tranfer Object : Add dto module to main pom.xml 2017-08-14 00:40:01 +05:30
Gopinath Langote
9c088b5f47 - Data Tranfer Object : Mofidy maven dependancies. 2017-08-14 00:23:03 +05:30
Gopinath Langote
3eab4d75a6 Revert " - Data Tranfer Object : Added module to project."
This reverts commit db10b937f2.
2017-08-14 00:16:29 +05:30
Ilkka Seppälä
f6c8bfbc39 Add explanation for Builder 2017-08-13 17:34:05 +03:00
mahendran.mookkiah
a1a4088087 As getAll method returns a Stream, we cannot close the involved
resources (Connection, Statement and resultSet) until the stream is
closed by the consumer. So try-with-resources is not an option as per
sonarqube’s recommendation. But it is still recommended to close
statement and result set. When connection pool used, connection is not
closed when close() called. It is just returned to the pool.

Using //NOSONAR to avoid false blocker issue.
2017-08-13 10:19:48 -04:00
Ilkka Seppälä
cbba487ff8 Merge branch 'master' of https://github.com/iluwatar/java-design-patterns 2017-08-13 10:09:46 +03:00
Ilkka Seppälä
37b9d45a74 Add explanation for Abstract Factory 2017-08-13 10:09:26 +03:00
Ilkka Seppälä
2e99cb41ad Merge pull request from mookkiah/587_model-view-presenter
 SonarQube reports bugs
2017-08-13 08:57:13 +03:00
Serdar Hamzaoğulları
eb2a232382 README edited 2017-08-13 01:36:52 +03:00
Serdar Hamzaoğulları
4b3435c550 Code formating 2017-08-13 00:08:35 +03:00
Ilkka Seppälä
fba30e59ee Kramdown fixes 2017-08-12 21:44:21 +03:00
Ilkka Seppälä
2d750dc0fd Alter Factory Method presentation 2017-08-12 20:02:14 +03:00
Ilkka Seppälä
002774b5aa Fix Travis out of memory error 2017-08-12 19:24:55 +03:00
Ilkka Seppälä
2150a2bb55 Skip puml processing for singleton module 2017-08-12 18:42:14 +03:00
Ilkka Seppälä
746e452c2b Add new presentation for Singleton 2017-08-12 18:20:45 +03:00
Igor C. A. de Lima
3c6f7aa046 Protect against instantiation via reflection
Signed-off-by: Igor C. A. de Lima <igorcadelima@gmail.com>
2017-08-12 12:11:10 -03:00
Ilkka Seppälä
600553ec0f Merge pull request from shaiktaj/patch-1
Updated ThreadSafeLazyLoadedivoryTower
2017-08-12 16:58:01 +03:00
Serdar Hamzaoğulları
64824d65aa Some Object Orianted refactor 2017-08-12 16:21:35 +03:00
Gopinath Langote
bfbc8fd740 - Data Tranfer Object : Add readme.md 2017-08-11 16:51:46 +05:30
Gopinath Langote
df9be78504 - Data Tranfer Object : customer client request customer details to server at one shot. 2017-08-11 16:17:51 +05:30
Gopinath Langote
229fda9f3c - Data Tranfer Object : Add puml diagram. 2017-08-11 15:55:12 +05:30
Gopinath Langote
148de06bb1 - Data Tranfer Object : Implement Data Transfer Object pattern simple version. 2017-08-11 15:42:21 +05:30
Gopinath Langote
67d4477d25 - Data Tranfer Object : Add puml file to etc. 2017-08-10 13:45:46 +05:30
Gopinath Langote
db10b937f2 - Data Tranfer Object : Added module to project. 2017-08-09 15:27:36 +05:30
Serdar Hamzaoğulları
1474a50e5e Example done with app class 2017-08-06 22:51:43 +03:00
Serdar Hamzaoğulları
9f612ecfda first commit 2017-08-05 23:33:08 +03:00
mahendran.mookkiah
0271e55983 SonarQube reports bugs 2017-08-05 10:07:28 -04:00
Ilkka Seppälä
54d8ec94be Merge pull request from mookkiah/587_intercepting-filter
 sonarqube bugs
2017-07-30 08:49:17 +03:00
Ilkka Seppälä
ffbf56f01a CQRS pattern: Add missing license headers 2017-07-29 21:41:11 +03:00
Ilkka Seppälä
83fcbe0713 Merge pull request from kevelbreh/patch-1
Update README.md punctuation and spelling
2017-07-29 21:13:29 +03:00
Ilkka Seppälä
0982f00a61 Merge pull request from isabiq/master
CQRS pattern
2017-07-29 20:45:55 +03:00
Sabiq Ihab
871df4f918 close connection before throwing an exception 2017-07-29 13:26:54 +01:00
Sabiq Ihab
7ae9e3ee22 add a description of the pattern 2017-07-29 13:13:08 +01:00
Sabiq Ihab
c572fe885e add check on null objects 2017-07-29 12:16:19 +01:00
Sabiq Ihab
a221245909 Use Logger instead of println 2017-07-29 12:14:15 +01:00
Sabiq Ihab
8bf4497879 Close sessions using try with resources 2017-07-29 12:13:34 +01:00
Sabiq Ihab
8073b93182 fix README.md 2017-07-29 12:04:04 +01:00
Kevin Woodland
9b1a9aafc1 Update README.md punctuation and spelling
Fixed minor punctuation and spelling while reading through applicability
2017-07-28 20:20:38 +02:00
mahendran.mookkiah
c6b6c8123f sonarqube bugs 2017-07-22 18:35:18 -04:00
Sabiq Ihab
87c10faaac Fix : remove AppTest 2017-06-30 23:22:44 +00:00
Sabiq Ihab
d1b11539ec add pumlid 2017-06-30 21:53:47 +00:00
Sabiq Ihab
c744bf418a add README.md, cqrs.ucls and etc/cqrs.urm.puml 2017-06-30 21:41:25 +00:00
Sabiq Ihab
5873aeeb69 add cqrs module to parent pom.xml and update pom.xml 2017-06-30 21:31:25 +00:00
Sabiq Ihab
d8919d88f0 fix pmd errors 2017-06-30 21:26:02 +00:00
Sabiq Ihab
b67719ab32 add tests 2017-06-30 21:26:02 +00:00
Sabiq Ihab
a8f50297eb add hashCode and equals to Author and Book DTOs 2017-06-30 21:26:02 +00:00
Sabiq Ihab
3128d3fb40 create main class 2017-06-30 21:26:02 +00:00
Sabiq Ihab
a2dba5bf6d add logs, javadoc and format to checkstyle conventions 2017-06-30 21:26:02 +00:00
Sabiq Ihab
40c00ca2af add ICommandService and IQueriesService Implementations 2017-06-30 21:26:02 +00:00
Sabiq Ihab
8e25ec55bf change long with BigIntger and replace getBook() 2017-06-30 21:26:02 +00:00
Sabiq Ihab
8881950e6d add toString() to BookDTO 2017-06-30 21:26:02 +00:00
Sabiq Ihab
51bcee5d7d add Queries and Commands Interfaces 2017-06-30 21:26:02 +00:00
Sabiq Ihab
15a25f0ef3 add DTOs 2017-06-30 21:26:02 +00:00
Sabiq Ihab
f3902ffc16 add setters and protected no-arg constructor 2017-06-30 21:26:02 +00:00
Sabiq Ihab
8208f6252b add hibernate.cfg and HibernateUtil class 2017-06-30 21:26:02 +00:00
Sabiq Ihab
ca73621f4d create data model 2017-06-30 21:26:01 +00:00
Sabiq Ihab
4e9988877a Initial commit 2017-06-30 21:26:01 +00:00
Ilkka Seppälä
ac721c695c Set version for next development iteration 2017-06-30 20:33:29 +03:00
Ilkka Seppälä
d793160bce Reach milestone 1.16.0 2017-06-30 20:31:31 +03:00
Ilkka Seppälä
b65b89baaf Merge pull request from Harshrajsinh/hotfix/readme-update
Refactored Function<Integer,T> to IntFunction<T>
2017-06-14 22:48:33 +03:00
Harshrajsinh Thakor
edea7d2220 Refactored Function<Integer,T> to IntFunction<T>. 2017-06-14 11:58:05 -07:00
Ilkka Seppälä
bf8bc4df4b Merge pull request from Harshrajsinh/hotfix/readme-update
Refactored the Functional Interface to the Specialized Primitive Functional Interface
2017-06-14 20:19:44 +03:00
Ilkka Seppälä
d13635533a Merge pull request from prafful1/master
Few additions in readme
2017-06-14 20:14:09 +03:00
Ilkka Seppälä
37cd4cbb3b Merge pull request from fluency03/master
add RxJava to Real world examples of observer
2017-06-14 20:12:32 +03:00
Ilkka Seppälä
3d29755842 Add license headers 2017-06-11 19:37:52 +03:00
Ilkka Seppälä
5b47d48fc2 Merge pull request from SrdjanPaunovic/extension-objects
 Extension objects pattern
2017-06-11 19:26:47 +03:00
Harshrajsinh Thakor
73934e25e5 Refactored the Functional Interface to the Specialized Functional
Interface.
2017-06-09 17:17:56 -07:00
prafful1
41d487d32a Few additions in readme
Adding Consequences and General usage of Adapter Pattern section to the Readme doc.
2017-06-07 20:22:15 +05:30
Srđan Paunović
a0916aab6c Update README.md 2017-06-04 21:12:30 +02:00
SrdjanPaunovic
863589ed29 Create meaningful JavaDocs instead of author names 2017-06-04 21:09:17 +02:00
SrdjanPaunovic
85acb1cf6c Replase system.println with logger 2017-06-04 20:49:15 +02:00
Srđan Paunović
09fb79099f Merge branch 'master' into extension-objects 2017-06-02 21:50:00 +02:00
SrdjanPaunovic
22a7c15acc Reset execute-around/pom.xml from master 2017-06-02 21:42:59 +02:00
Chang Liu
0182b840af add RxJava to Real world examples of observer 2017-05-30 13:22:52 +02:00
Ilkka Seppälä
f87249e03b Add missing license headers 2017-05-29 21:53:05 +03:00
Ilkka Seppälä
dd0ca2d16e Merge pull request from 4lexis/master
 Marker Interface pull request
2017-05-29 21:41:27 +03:00
shaiktaj
24f258848c Updated ThreadSafeLazyLoadedivoryTower
Added null check in private constructor to prevent instantiating by Reflection call
2017-05-25 11:04:30 -05:00
Aleksandar Dudukovic
f2e35ec03d fix version and javadoc 2017-05-23 01:38:02 +02:00
Ilkka Seppälä
ae1d9cf7a8 Add missing license headers 2017-05-21 09:19:29 +03:00
Ilkka Seppälä
1bbc597671 Merge pull request from prafful1/master
Few additions in README
2017-05-21 09:11:00 +03:00
Ilkka Seppälä
4d6467e435 Merge pull request from kapinuss/master
Adding Setter Dependency Injection as a second subtype of DI
2017-05-21 09:02:18 +03:00
kapinuss
17039dc5e9 Update AdvancedSorceressTest.java 2017-05-18 20:27:16 +03:00
kapinuss
30dcbee2cc Update AdvancedSorceress.java 2017-05-18 20:26:47 +03:00
kapinuss
08901f3c26 Update AdvancedSorceress.java 2017-05-18 20:23:05 +03:00
kapinuss
c746004f73 Update AdvancedSorceress.java 2017-05-18 19:13:45 +03:00
kapinuss
09aa44ddcb Update App.java 2017-05-18 19:13:09 +03:00
Ilkka Seppälä
992e76ac61 Merge pull request from qpi/master
Event Queue pattern
2017-05-16 21:59:50 +03:00
Mihály Kuprivecz
167a43f72e updated model.png 2017-05-15 11:04:41 +02:00
Mihály Kuprivecz
fe1e45bd69 some fixes 2017-05-15 10:40:12 +02:00
Ilkka Seppälä
4b32fb65da Merge pull request from ytian90/master
Fix Block 3 Case in Feature Toggle Design Pattern
2017-05-15 08:13:28 +03:00
Mihály Kuprivecz
0546223bba quick fix 2017-05-11 21:44:07 +02:00
Mihály Kuprivecz
857902ab95 compatibility fix
When the system is not capable to play the sound, do not throw
exception, just log it. For example on Linux there are several issues to
play sound and there are no workarounds for that :(
2017-05-11 21:41:25 +02:00
Ilkka Seppälä
0b57edd211 Merge pull request from brandon-d-mckay/patch-1
Fix incorrect URL
2017-05-09 23:10:31 +03:00
prafful1
fb26d42b51 Few additions in README
Added few more points in applicability and also some use cases and consequences.
2017-05-07 13:28:54 +05:30
Srđan Paunović
6857486f27 Create README.md file 2017-05-04 12:33:25 +02:00
Aleksandar Dudukovic
1abd96a9c8 checkstyle fix 2017-05-03 22:09:47 +02:00
SrdjanPaunovic
08c4202852 fix checkstyle errors 2017-05-03 22:08:04 +02:00
Aleksandar Dudukovic
6ecf994258 pom.xml align fix 2017-05-03 21:42:15 +02:00
SrdjanPaunovic
0687a3f9f8 pom.xml fix align 2017-05-03 21:40:54 +02:00
Aleksandar Dudukovic
64337dff06 merge fix 2017-05-03 21:07:49 +02:00
4lexis
34b09c75ec added .gitignore 2017-05-03 20:51:51 +02:00
4lexis
66c6f30c1c Updated pom.xml 2017-05-03 20:34:27 +02:00
Aleksandar Dudukovic
e413b116ac Merge branch 'master' of https://github.com/4lexis/java-design-patterns 2017-05-03 19:57:57 +02:00
Aleksandar Dudukovic
6e0b3e37ea updated pom.xml 2017-05-03 19:57:14 +02:00
4lexis
be3f4dce50 Update Picture 2017-05-03 19:49:25 +02:00
4lexis
6d87f63ed5 Added README.md 2017-05-03 19:48:29 +02:00
SrdjanPaunovic
c92a8daeda Class diagram & fix relation between units 2017-05-03 17:59:54 +02:00
Aleksandar Dudukovic
20062faae6 All without Readme and pumlid 2017-05-03 17:50:35 +02:00
SrdjanPaunovic
678524704c Test done 2017-05-03 13:21:13 +02:00
kapinuss
2b229d8ea1 Update AdvancedSorceressTest.java 2017-05-02 20:38:08 +03:00
kapinuss
03aa99c55f Update AdvancedSorceressTest.java 2017-05-02 20:18:05 +03:00
ytian90
20a4c054a7 Merge branch 'master' of github.com:ytian90/java-design-patterns 2017-04-30 00:20:48 -07:00
ytian90
3ed6cc19d2 fix Block 3 case 2017-04-30 00:19:50 -07:00
Yu Tian
87a9387e62 Merge pull request from iluwatar/master
Rebase
2017-04-29 16:03:26 -07:00
Aleksandar Dudukovic
8530d01e10 code implemented 2017-04-29 16:35:57 +02:00
Aleksandar Dudukovic
a34e7be9c2 check commit 2017-04-28 19:35:19 +02:00
Mihály Kuprivecz
ee3744cb0a added travis supported sound files 2017-04-28 13:47:56 +02:00
Mihály Kuprivecz
2830a407ba some fixes for testing in event queue 2017-04-28 12:19:57 +02:00
kapinuss
ccfb6709c7 Add files via upload 2017-04-28 13:00:01 +03:00
kapinuss
a1c5131304 Add files via upload 2017-04-28 12:59:09 +03:00
Mihály Kuprivecz
44401988d1 pom.xml fixes 2017-04-28 11:32:35 +02:00
Mihály Kuprivecz
6e8eaf7593 adding some test cases for the event queue 2017-04-28 10:38:40 +02:00
SrdjanPaunovic
645e91ed23 first version of pattern without Tests 2017-04-27 13:58:58 +02:00
Brandon D. McKay
9e7e8a64f6 Fix incorrect URL 2017-04-26 04:22:44 -04:00
Mihály Kuprivecz
152b2762c3 read.me and the diagram is added 2017-04-22 17:16:38 +02:00
Ilkka Seppälä
82b9f4fea7 Merge pull request from kemitix/data-bus
[WIP] Data Bus
2017-04-22 15:17:31 +03:00
Paul Campbell
ff8d854a8d data-bus: README.md: clean up 2017-04-16 06:51:10 +01:00
Ilkka Seppälä
31f4b15e86 Merge pull request from kapinuss/patch-1
Update ObjectPool.java
2017-04-16 08:17:56 +03:00
Ilkka Seppälä
cd54cf5512 Merge pull request from sunilmogadati/SonarQubeBlockerBugs
 SonarQube blocker severity bugs
2017-04-16 08:13:26 +03:00
kapinuss
798aee47b3 Update ObjectPool.java 2017-04-12 18:59:43 +03:00
Mihály Kuprivecz
dce767c1c5 first commit 2017-04-06 23:48:15 +02:00
Sunil Mogadati
60ebcc56f8 SonarQube blocker severity bugs 2017-04-01 20:55:47 -06:00
Paul Campbell
2643dfa0b8 data-bus: App: add notes about this implementation of the patter 2017-04-01 19:33:54 +01:00
Paul Campbell
c96ebcb197 data-bus: App: add description of the pattern 2017-04-01 19:26:41 +01:00
Paul Campbell
b72d545349 data-bus: members: StatusMemberTest: added 2017-04-01 19:17:09 +01:00
Paul Campbell
311bb79870 data-bus: members: StatusMember: records start and stop times 2017-04-01 19:16:55 +01:00
Paul Campbell
f495a88e91 data-bus: members: MessageCollectorMemberTest: added 2017-04-01 19:05:19 +01:00
Paul Campbell
8b0c14cae0 Counter doesn't count anything. Added ability to collect the messages
from the MessageData that it receives.
2017-04-01 19:05:09 +01:00
Paul Campbell
b7a6a018e0 data-bus: DataBusTest: added 2017-04-01 18:36:04 +01:00
Paul Campbell
46e0fa4825 data-bus: pom.xml: add mockito dependency 2017-04-01 18:35:40 +01:00
Paul Campbell
86009f2261 data-bus: add missing javadoc 2017-04-01 18:12:56 +01:00
Paul Campbell
146f367188 data-bus: remove lombok 2017-04-01 18:12:32 +01:00
Paul Campbell
bc4d029a87 data-bus: pom.xml: remove surefire plugin 2017-04-01 18:04:44 +01:00
Paul Campbell
960eee3d43 update version 2017-04-01 18:04:16 +01:00
Paul Campbell
30315e788f Merge remote-tracking branch 'upstream/master' into data-bus
* upstream/master: (67 commits)
  Set version for next development iteration
  Reached milestone 1.15.0
   Checkstyle fix
   More Checkstyle fixes
   Checkstyle fixes
   Add missing puml and license headers
   Add missing license header
  Work on : urm/puml updates * added pumlid where it was missing and possible * removed pumlid where it generated a bad image * regenerated some incorrect puml's * added 'left to right direction' puml prefix to some diagrams to improve the automatic layouting
  Removed AvoidStarImport Rule Added JavaDocType Rule
  Update App.java
  Update App.java
  Update after changes from review. Additional improvements.
  Pom.xml files fixed.
   Balking Pattern
  fixed pmd violation
  fixed checkstyle violations
  diagrams added
  comments, tests and description
  changed parent POM version 
  apply changes from review 
  ...

# Conflicts:
#	pom.xml
2017-04-01 18:03:02 +01:00
Ilkka Seppälä
073d06c0ae Set version for next development iteration 2017-04-01 17:15:59 +03:00
Ilkka Seppälä
8fea969912 Reached milestone 1.15.0 2017-04-01 17:14:02 +03:00
Ilkka Seppälä
139876f96a Checkstyle fix 2017-04-01 15:51:01 +03:00
Ilkka Seppälä
f3c4640d12 More Checkstyle fixes 2017-04-01 15:43:36 +03:00
Ilkka Seppälä
c1c4411957 Checkstyle fixes 2017-04-01 15:34:13 +03:00
Ilkka Seppälä
3f272bf291 Merge pull request from muditporwal/master
Checkstyle improvements  : Added JavaDocType Rule
2017-04-01 14:45:52 +03:00
Ilkka Seppälä
2921448f8b Add missing puml and license headers 2017-04-01 14:25:13 +03:00
Ilkka Seppälä
952c207a62 Merge pull request from Crossy147/converter
Converter
2017-04-01 14:17:37 +03:00
Ilkka Seppälä
6ba4d7be98 Add missing license header 2017-04-01 12:39:06 +03:00
Ilkka Seppälä
854101bb49 Merge pull request from thomasoss/master
Thread Local Storage issue 
2017-04-01 12:29:03 +03:00
Kamil Pietruszka
a5ab5c7d8e Merge branch 'master' into converter 2017-03-26 23:50:08 +02:00
Ilkka Seppälä
286d6c3a4c Merge pull request from Rzeposlaw/master
 Balking Pattern
2017-03-26 15:00:21 +03:00
NooBxGockeL
c2a7b902a9 Work on : urm/puml updates
* added pumlid where it was missing and possible
* removed pumlid where it generated a bad image
* regenerated some incorrect puml's
* added 'left to right direction' puml prefix to some diagrams to improve the automatic layouting
2017-03-25 22:07:10 +01:00
Mudit Porwal
09585c3874 Removed AvoidStarImport Rule
Added JavaDocType Rule
2017-03-22 01:16:02 +08:00
Thomas
f84c4c1611 Update App.java
Correction of correction ;-)
2017-03-18 10:02:37 +01:00
Thomas
2c2d874ac8 Update App.java
Correction of error detected by maven-pmd-plugin.
2017-03-18 10:00:13 +01:00
Kamil Pietruszka
72a0765ec6 Merge branch 'master' into converter 2017-03-16 12:27:05 +01:00
Katarzyna Rzepecka
cca4d5a670 Update after changes from review. Additional improvements. 2017-03-13 01:33:14 +01:00
Katarzyna Rzepecka
bb4a1bdc05 Pom.xml files fixed. 2017-03-13 01:16:26 +01:00
Katarzyna Rzepecka
1aed5905d7 Balking Pattern 2017-03-13 01:15:39 +01:00
Ilkka Seppälä
175e9f58c1 Merge pull request from robertt240/master
guarded suspension pattern 
2017-03-12 10:36:27 +02:00
Kamil Pietruszka
77a534385c fixed pmd violation 2017-03-11 13:35:55 +01:00
Kamil Pietruszka
2ed7acbc31 fixed checkstyle violations 2017-03-11 13:02:29 +01:00
Kamil Pietruszka
3a243eee6e diagrams added 2017-03-11 12:47:58 +01:00
Kamil Pietruszka
8632bafcd7 comments, tests and description 2017-03-11 12:24:48 +01:00
Robert Kasperczyk
449aed1a53 changed parent POM version 2017-03-11 12:02:04 +01:00
Robert Kasperczyk
a20abae21c apply changes from review 2017-03-11 11:50:19 +01:00
Robert Kasperczyk
7423f47daa further POM rearragments 2017-03-11 11:50:19 +01:00
Robert Kasperczyk
f09578c091 further POM rearragments 2017-03-11 11:50:19 +01:00
Robert Kasperczyk
29715028d1 fix in POM formatting 2017-03-11 11:50:19 +01:00
Robert Kasperczyk
e5034c6ae9 guarded suspension pattern 2017-03-11 11:50:19 +01:00
Robert Kasperczyk
a09866d35b another readme fix 2017-03-11 11:50:19 +01:00
Robert Kasperczyk
1824b4138b readme fix 2017-03-11 11:50:19 +01:00
Robert Kasperczyk
764ff4bf53 Initial commit of guarded suspension design pattern 2017-03-11 11:50:19 +01:00
Kamil Pietruszka
e8b634c33e java docs added 2017-03-10 20:59:24 +01:00
Kamil Pietruszka
8871f788d2 Converter pattern implementation 2017-03-10 20:08:58 +01:00
Kamil Pietruszka
e9c54011e9 Merge remote-tracking branch 'refs/remotes/iluwatar/master' 2017-03-08 16:50:04 +01:00
Paul Campbell
6b795e52c3 data-bus: README.md: updated for data-bus 2017-03-05 19:43:57 +00:00
Paul Campbell
b5bdf2d7d7 data-bus: etc: add urm diagrams 2017-03-05 19:43:26 +00:00
Paul Campbell
3fd6887975 data-bus: implement pattern 2017-03-05 18:55:34 +00:00
Paul Campbell
eecffb0ea5 data-bus: add stub 2017-03-03 19:58:03 +00:00
Thomas
fd7107694a Update pom.xml
Changed
    <version>1.14.0-SNAPSHOT</version>
to
    <version>1.15.0-SNAPSHOT</version>
2017-02-18 15:16:15 +01:00
Ilkka Seppälä
cca4760f69 Rename package for Queue-Based Load Leveling pattern 2017-02-12 00:33:30 +02:00
Ilkka Seppälä
a1ff55b462 Regenerate puml files 2017-02-11 21:46:56 +02:00
Thomas
ddac9dc6cb Add files via upload
Changed the classname part "runnable" to "callable"
2017-01-29 12:34:13 +01:00
Thomas
2bbf84233e Delete DateFormatRunnableTestMultiThread.java 2017-01-29 12:32:44 +01:00
Thomas
82f8460243 Delete DateFormatRunnableTestIncorrectDateFormat.java 2017-01-29 12:32:32 +01:00
Thomas
59ea20745f Delete DateFormatRunnableTest.java 2017-01-29 12:32:21 +01:00
Thomas
3d3dd58501 Update pom.xml
removed errors caused by copy code from master
2017-01-29 12:08:11 +01:00
Thomas
3324e1bc43 Update pom.xml
added  <module>tls</module>
2017-01-29 12:01:32 +01:00
Thomas
6202f3ab44 Add files via upload 2017-01-29 11:42:16 +01:00
Thomas
453862cfc2 Delete AppTest.java 2017-01-29 11:41:46 +01:00
Thomas
a8e2c157de Add files via upload
Test reworked completely. AppTest seperated.
2017-01-29 11:41:13 +01:00
Thomas
080965fb17 Delete DateFormatUglyRunnable.java 2017-01-29 11:38:49 +01:00
Thomas
7200329a6b Add files via upload
Rework replaces previous version completely. Using ExecutorService. Use of result object instead of static variables. Ugly example is left out.
2017-01-29 11:38:20 +01:00
Thomas
f170aaa42b Delete DateFormatRunnable.java 2017-01-29 11:34:12 +01:00
Thomas
c598748549 Delete AppUgly.java 2017-01-29 11:33:59 +01:00
Thomas
ed11c4c4f9 Delete App.java 2017-01-29 11:33:40 +01:00
Thomas
283f198ba8 Delete empty 2017-01-29 11:32:26 +01:00
Thomas
15913d6382 Add files via upload
new uml diagramm after changes to the java classes
2017-01-29 11:31:06 +01:00
Thomas
65e047974c Create empty 2017-01-29 11:29:19 +01:00
Thomas
c529e35791 Delete tls.urm.puml 2017-01-29 11:28:27 +01:00
Thomas
3342851005 Delete tls.ucls 2017-01-29 11:28:17 +01:00
Thomas
c167f87ce5 Delete tls.png 2017-01-29 11:27:46 +01:00
Thomas
e8fc3427c6 Update README.md
no change of content. Improved text
2017-01-29 11:23:33 +01:00
Thomas
26b79a5382 Update README.md
Some additonal description, deleted wrong pumlid
2017-01-29 11:16:45 +01:00
Ilkka Seppälä
9ec0935a1c Merge pull request from leogtzr/master
Adding initialization-on-demand idiom and noninstantiable class instead of interface constant idiom
2017-01-23 08:21:07 +02:00
leogtzr
c6d0d28557 Reverting initialization on demand holder idiom. 2017-01-22 11:06:57 -07:00
leogtzr
e26215578c Changing code to use interfaces instead of implementations. 2017-01-21 15:49:29 -07:00
leogtzr
d6fc28e120 Changing code to use interfaces instead of implementations. 2017-01-21 15:47:54 -07:00
Ilkka Seppälä
115a85301c Add link to proxy blog 2017-01-21 13:37:16 +02:00
Ilkka Seppälä
29c5b80f19 Add link to Queue-Based Load Leveling blog 2017-01-21 12:56:42 +02:00
Ilkka Seppälä
0c8bb1c22e Set version for next development iteration 2016-12-31 10:24:26 +02:00
Ilkka Seppälä
0c48695fa5 Achieved milestone 1.14.0 2016-12-31 10:23:32 +02:00
Ilkka Seppälä
8d34ccf827 Add link to Proxy presentation. 2016-12-26 20:16:30 +02:00
Ilkka Seppälä
512a5c0560 Merge branch 'proxy-presentation' 2016-12-26 20:08:41 +02:00
leogtzr
6292690250 Changing constant interface pattern with a Noninstantiable class 2016-12-24 14:49:41 -07:00
leogtzr
20b1c2bd49 Adding initialization on demand holder idiom. 2016-12-24 00:49:46 -07:00
Thomas
e210e4ed62 Add files via upload 2016-12-16 11:17:27 +01:00
Thomas
fb98da86c4 Add files via upload 2016-12-16 11:12:43 +01:00
Thomas
c8b3c773c7 Add files via upload 2016-12-16 09:43:16 +01:00
Thomas
61b1356976 Delete emptyfile 2016-12-16 09:42:46 +01:00
Thomas
487f9ddc80 Add files via upload 2016-12-16 09:42:08 +01:00
Thomas
9b7ce556e3 Create emptyfile 2016-12-16 09:35:19 +01:00
Thomas
e17cf27e5a upload pom.xml 2016-12-15 18:33:52 +01:00
Thomas
937a1e269d delete empty file 2016-12-15 18:32:13 +01:00
Thomas
803a97237c delete empty file 2016-12-15 18:31:53 +01:00
Thomas
e64f7faa3f upload junit test 2016-12-15 18:31:20 +01:00
Thomas
15d660b117 empty file to create folder 2016-12-15 18:30:22 +01:00
Thomas
544f7fb6d1 delete empty file 2016-12-15 18:28:02 +01:00
Thomas
c4eb198a8d Upload code files 2016-12-15 18:27:28 +01:00
Thomas
7067d1ae56 Create test 2016-12-15 18:24:03 +01:00
Thomas
d80edd1ed3 Create test 2016-12-15 18:08:12 +01:00
Thomas
aeefc11f25 Merge pull request from iluwatar/master
Update my local repository
2016-12-14 08:52:22 +01:00
Sia Wai Suan
8953bfc81b Merge pull request from iluwatar/master
Bringing fork up-to-date
2016-08-01 16:55:27 +01:00
1085 changed files with 23843 additions and 10438 deletions
.gitignore.travis.ymlCODE_COVERAGE.mdPULL_REQUEST_TEMPLATE.mdREADME.md
_scripts
abstract-document
abstract-factory
acyclic-visitor
adapter
aggregator-microservices
README.md
aggregator-service
pom.xml
src
main
java
com
iluwatar
aggregator
microservices
test
java
com
iluwatar
aggregator
microservices
etc
information-microservice
pom.xml
src
main
java
com
iluwatar
information
test
java
com
iluwatar
information
inventory-microservice
pom.xml
src
main
java
com
iluwatar
inventory
test
java
com
iluwatar
inventory
pom.xml
ambassador
api-gateway
README.md
api-gateway-service
pom.xml
src
main
test
java
com
iluwatar
etc
image-microservice
pom.xml
src
test
java
com
iluwatar
image
pom.xml
price-microservice
pom.xml
src
test
java
com
iluwatar
price
async-method-invocation
README.md
etc
pom.xml
src
main
java
com
iluwatar
test
java
com
iluwatar
balking
bridge
builder
business-delegate
caching
README.md
etc
pom.xml
src
main
java
com
iluwatar
test
java
callback
chain
checkstyle.xml
collection-pipeline
command
composite
converter
cqrs
dao
data-bus
data-mapper
data-transfer-object
decorator
delegation
README.md
etc
pom.xml
src
main
java
com
iluwatar
delegation
test
java
com
iluwatar
dependency-injection
dirty-flag
double-checked-locking
double-dispatch
eip-aggregator
eip-message-channel
.gitignoreREADME.md
etc
pom.xml
src
main
java
com
iluwatar
eip
message
channel
test
java
com
iluwatar
eip
message
eip-publish-subscribe
.gitignoreREADME.md
etc
pom.xml
src
main
java
com
iluwatar
eip
publish
subscribe
resources
test
java
com
iluwatar
eip
publish
subscribe
eip-splitter
README.md
etc
pom.xml
src
main
java
com
iluwatar
resources
test
java
com
iluwatar
resources
eip-wire-tap
README.md
etc
pom.xml
src
main
java
com
iluwatar
resources
test
java
com
iluwatar
resources
event-aggregator
event-asynchronous
event-driven-architecture
event-queue
event-sourcing
execute-around
extension-objects
facade
factory-kit
factory-method
feature-toggle
README.md
etc
pom.xml
src
main
java
com
iluwatar
test
java
com
iluwatar
fluentinterface
README.md
etc
pom.xml
src
main
java
com
iluwatar
fluentinterface
fluentiterable
test
java
com
iluwatar
fluentinterface
flux
flyweight
front-controller
guarded-suspension
README.md
etc
pom.xml
src
main
java
com
iluwatar
guarded
test
java
com
iluwatar
guarded
half-sync-half-async
README.md
etc
pom.xml
src
main
java
com
iluwatar
halfsynchalfasync
test
java
com
hexagonal
intercepting-filter
interpreter
iterator
layers
lazy-loading
marker
mediator
memento
message-channel/etc
model-view-controller
model-view-presenter
module
monad
README.md
etc
pom.xml
src
main
java
test
java
monostate
README.md
etc
pom.xml
src
main
java
com
iluwatar
test
java
multiton
mute-idiom
mutex
naked-objects
null-object
object-mother
object-pool
README.md
etc
pom.xml
src
main
java
com
iluwatar
object
test
java
observer
page-object
partial-response
poison-pill
pom.xml
private-class-data
producer-consumer
promise
property
README.md
etc
pom.xml
src
main
java
com
iluwatar
test
java
prototype
proxy
publish-subscribe/etc
queue-load-leveling
reactor
reader-writer-lock
repository
resource-acquisition-is-initialization
README.md
etc
pom.xml
src
main
java
com
iluwatar
resource
acquisition
is
initialization
test
java
com
iluwatar
resource
acquisition
retry
semaphore
servant
serverless
service-layer
service-locator
README.md
etc
pom.xml
src
main
java
com
iluwatar
servicelocator
test
java
com
singleton
specification
state
step-builder
README.md
etc
pom.xml
src
main
java
com
iluwatar
stepbuilder
test
strategy
template-method
thread-pool
README.md
etc
pom.xml
src
main
java
com
iluwatar
threadpool
test
throttling
tls
tolerant-reader
README.md
etc
pom.xml
src
main
java
com
iluwatar
test
java
trampoline
.gitignoreREADME.mdpom.xml
src
main
java
test
java
com
iluwatar
twin
unit-of-work
value-object
README.md
etc
pom.xml
src
main
java
com
iluwatar
value
test
java
com
visitor

1
.gitignore vendored

@@ -17,3 +17,4 @@ datanucleus.log
/bin/
*.log
data-mapper/src/main/resources/log4j.xml
event-sourcing/Journal.json

@@ -17,7 +17,7 @@ install:
- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -e
after_success:
- mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar -Dsonar.host.url=https://sonarqube.com -Dsonar.login=$SONAR_TOKEN
- mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN
- bash update-ghpages.sh
# use latest java version available instead of travis default
@@ -36,4 +36,4 @@ notifications:
on_failure: always # options: [always|never|change] default: always
on_start: never # options: [always|never|change] default: always
sudo: false # route the build to the container-based infrastructure for a faster build
sudo: required

@@ -1,7 +1,7 @@
# Code Coverage Report generation
To generate the code coverage report, execute the following command:
> mvn clean verify
> mvn clean verify jacoco:report
This will generate code coverage report in each of the modules. In order to view the same, open the following file in your browser.
> target/site/jacoco/index.html

15
PULL_REQUEST_TEMPLATE.md Normal file

@@ -0,0 +1,15 @@
Pull request title
- Clearly and concisely describes what it does
- Refer to the issue that it solves, if available
Pull request description
- Describes the main changes that come with the pull request
- Any relevant additional information is provided
> For detailed contributing instructions see https://github.com/iluwatar/java-design-patterns/wiki/01.-How-to-contribute

@@ -7,7 +7,8 @@
[![Build status](https://travis-ci.org/iluwatar/java-design-patterns.svg?branch=master)](https://travis-ci.org/iluwatar/java-design-patterns)
[![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/LICENSE.md)
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Quality Gate](https://sonarqube.com/api/badges/gate?key=com.iluwatar%3Ajava-design-patterns)](https://sonarqube.com/dashboard/index/com.iluwatar%3Ajava-design-patterns)
[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=com.iluwatar%3Ajava-design-patterns&metric=alert_status)](https://sonarcloud.io/dashboard/index/com.iluwatar%3Ajava-design-patterns)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1503/badge)](https://bestpractices.coreinfrastructure.org/projects/1503)
# Introduction

@@ -1,190 +0,0 @@
parent: half-sync-half-async; artifact: half-sync-half-async
Puml Server ID: RScv3SCm3030LU819FRPXg5fIm552tnYPFiyjRi3RkbAaYkdoQr5JBy369vrxz7oaSv6XmPhL3e6TCaJ0msU-CAoilTToyG8DdKOw5z0GzcAlvNAN_WZSD1brBHHPmxv0000
parent: abstract-document; artifact: abstract-document
Puml Server ID: PSjB3eCm34NHhPG599vtDyQn85L-ifzX-p3lxEf8Twj3MXGDQvyJMFubChxpKN767gucSq07iinEjSNDOACVNvoAUZr6MWoe3QVE_WRnxZ0Mf38b-hkIGlurX_MyehS7
parent: tolerant-reader; artifact: tolerant-reader
Puml Server ID: NSZ14SCm20NHLf829ExfXaYChGn26lZ4xSVdtFRjSrZJx9AkZnFOyI9olkenSEOxGxmjWnXgMvE6viLWfmz_kNI9SLZP38XRqEIuWx1Kd0t5XVjjGVj_DNtMdLD_
parent: event-driven-architecture; artifact: event-driven-architecture
Puml Server ID: TOhH3SCW30LNQGS0_tSRnrZ15H1adfFromBzkfFktZQaHT7mzgh0N1yYvoUVXXf7B7Mv1dGWozN9MZmCTlhopQdeidEaoO3wMDHvRI6zzvwAssPYbsfGGRYIGlxN7DxpZDv-
parent: publish-subscribe; artifact: publish-subscribe
Puml Server ID: PSZB3SCm203GLTe1RExT1XCKKs5YyMdMR--zFRsd66aTNAwFcRdZ1U1uzrDorgXWfykIBJjT2qJhnaI7Dtwm7HnoMjkOoMu12-C7s3LKOhQe4UGo63ZfVtlvwhkMVW40
parent: facade; artifact: facade
Puml Server ID: BSP15eCm20N0gxG7CEoz3ILKqvTW7dpq-hhehERTJ7fMJU-l7PYn4ZbVPMlOyvEXBeT13KMEGQtdnM2d7v-yL8sssJ8PKBUWmV64lYnSbHJoRqaVPUReDm00
parent: service-locator; artifact: service-locator
Puml Server ID: NSjB3iCm203HgxG7iDdtDeIWX0fZYqzo_MRTtUX9ynOZhPtBzNLchlW0EDxza3nhgs2dQScMdUO0qRenqU6B5xQTGmvh2pFPBM1WF07FSmbnqqcOqu6J_gsNZxvgw0y0
parent: dao; artifact: dao
Puml Server ID: 5SR14OKW30N0LhG0oVrt4o6ZE12Ov4NR_thQNQlc5aN2sd82qtz4naywAixOmyNoK8WYvT6fjdWOR7JnpLiHhuTkam4nTUhiRwZm847-J64zpUZj3m00
parent: model-view-presenter; artifact: model-view-presenter
Puml Server ID: ROlR3SGW3C1MkGu0-RzjKeXQJWcWFChwPO3xispvQBrmL0hbp-q-xGkWkFBL_8upZBICxjGzbo7GE1OwAlpmmLJ9sjNJH7VIRY1e6q169KvFevMcakrtI_BoD-HGoJE4Nm00
parent: observer; artifact: observer
Puml Server ID: FSkn4OGm30NHLg00hFow4KO3PcpP8tr1-pYwx6smQz5Suv2mkbp0y1-HyPlEWYlsSB7S5Q98kJSgDLu66ztyy7Q8brEtmO2OEZNs2Uhxl9u9GVv72cjfHAiV
parent: intercepting-filter; artifact: intercepting-filter
Puml Server ID: RSfB3i8m303Hgy014k-vZN5DQkIuaJ_q-fGzkz7JtCL8Q-DolUsPAnu0ZcSVadizAzZfi6JBJiS4qJenqU6D7smRXmnh2pFPBM1YN05o_KwyKcoqb-ZFEEcVz_BPLqtz0W00
parent: factory-method; artifact: factory-method
Puml Server ID: NSZB3G8n30N0Lg20n7UwCOxPP9MVx6TMT0zdRgEvjoazYeRrMmMsFuYChtmqr7Y6gycQq8aiQr3hSJ7OwEGtfwBUZfas0shJQR3_G2yMBFkaeQYha4B-AeUDl6FqBm00
parent: private-class-data; artifact: private-class-data
Puml Server ID: RShR3SCm243HLTe1RFwx3S4eeSB4uf6itmpGlwkZ-nOZhS7b-ZeoLtm07E--InwrLR3JQScMdSu9edLZeiCNBso3GtPh2pFPBM1YF07BvSBaHeeHRJm_SD8VxkMphvhw0m00
parent: async-method-invocation; artifact: async-method-invocation
Puml Server ID: TSdB3SCW303GLTe1mFTkunWhk0A3_4dKxTi5UdlIUuhIoCPfuz4Zjhy03EzwIlGyqjbeQR16fJL1HjuOQF362qjZbrFBnWWsTPZeFm3wHwbCZhvQ4RqMOSXIuA1_LzDctJd75m00
parent: execute-around; artifact: execute-around
Puml Server ID: NSZ14G8n20NGLhI0XBlT865suoGa0n_NylNixSsxTvEHJTF7xGHsF8YShtfqdFdCK9TbK4ELDQcFl1ZizE8tbwRH3okR0NKBcXm_a7vK4bhOLreZXVnLJPzrvnnV
parent: monostate; artifact: monostate
Puml Server ID: HSV14OGm20NGLjO23FVj1YEZsGaa0nzjVxrvUszfLdlkaju_9p3ZI-HybwFXp2r3l0w364eTIgtdpM2d7r-yxXBji7Ko86v1ol60TDW8C8G4zLr9rp9J-ny0
parent: thread-pool; artifact: thread-pool
Puml Server ID: JSV14SCW30J0Lk82GFzq8uF6a1624IUx_UIPt-xHhMXK2TTN0zP-4pa_-UfeSSOMBzCWXbpceAxnCDZfmpUdAhjVbXO3uhPfyFw1q5oufZMdag3yFuUFl6Be5m00
parent: delegation; artifact: delegation
Puml Server ID: JSV14GCX20NGLf82LkxfXbN69OFeu2VRVdBCxRsdUhLiac6F2rZxHHHybwwuyimjKQT37ANEGMfvCpZepHy-ccpjVYm697pJuFq3DJ7f39rEWlhNaZ7Aoc5V
parent: chain; artifact: chain
Puml Server ID: 9SR13SCm20NGLTe1OkxTXX0KKzd4Wa-pVYlrdTxJN4OTMZ4U7LZv8Wg-ssdejLTgoELGHvDhaesw6HpqvWzlXwQTlYq6D3nfSlv2qjcS5F9VgvXjrHnV
parent: resource-acquisition-is-initialization; artifact: resource-acquisition-is-initialization
Puml Server ID: ZShR3S8m343HLUW0YV_PnhXMQvGumOzMOdhA1lqxkhgBABLSEQqzzeZfJm33isuIUxxIsMXei4QbqK5QdXXeyCO3oyekcvQ94MpgqD4lWB6FDEA2z4bn2HbQn8leHMponNy13hgvrhHUP_Rs0m00
parent: fluentinterface; artifact: fluentinterface
Puml Server ID: NOj93eCm302_KXv0VEzlN6F0bMCYB_3zvjpRQ3IpY97MnkNwEZD7l04SdtP8dlMfOAVBaYqRNHr4wy54Xo_Uk6uSSjWwC9FT0Zh61DYrPY_pyXs9WPF-NIllRLJN7m00
parent: service-layer; artifact: service-layer
Puml Server ID: LOl93SCm3C1MQGUmzUysgY8aAcJ5q96WszVV_aW2V8gHriRb-ZWoPxm07E--Inxrhc2dqv8jEvq3HEl6H8SFNjWs3jcjJSnaju21iG3MSmbnK_mkuwJ_qij7dpNq1m00
parent: visitor; artifact: visitor
Puml Server ID: DSR14OGm20NGLhG0mtsxmSWeJa8oyD7sTo_xJczLgoqFIM_B1Spu43c_vLHSkMU8rs4GGwcZaxPy6UnqyyFR8Q6dRPC1SGlg7B_Gew4OJeBwVqdlPMPlNm00
parent: double-dispatch; artifact: double-dispatch
Puml Server ID: NSbB3iCW303HgpG70Ezx6yTOWSeOv4zp_MRTtUZDCPGa6wV9gqTiVmCOtlKQqVDCPwEbmHgLreGXUMEWmGU_M1hxkBHiZ61JXud-1BILft1fmvz37JZetshQh3kd_000
parent: monad; artifact: monad
Puml Server ID: 9SR13SCm20NGLPe1OkxTXjWeSMMm1Pza_LRgExsjMntP97syBc35cyZvAMV7bKU6U9q6CPGwbVh8Xy5E7xvvRnBzj7qn86v1ol4BwJHk9AZ_bNGjAtLy0G00
parent: front-controller; artifact: front-controller
Puml Server ID: PSlB3OGm303HLfO24j-t6nCC13bEvC_IFk6yjz6JPgbIE3OAvS_fFkmBe7Zde_ePQnXfwU8adajlK3bkT5Iuy8Tf8wk7f87kf6BGq6R0hlD8xwQTUG9v-SCSslA8nWy0
parent: strategy; artifact: strategy
Puml Server ID: FSV13OCm30NGLM00udktCS4AGOaJsTz5tRwSkBstLiqj3WbhombC_n0PtwbKdB67Y-MX44NAerDjSJFOwE8lRuTuBRfD1iJKgRC_88SnfFn8aD-ai9vczFO7
parent: command; artifact: command
Puml Server ID: DSgn4OCm30NGLM00h3xR25i7vYpXaxx2-g59zugtTgiZcwIFvGHcV8YSdt9qdBbdYDVR88PIRwK-yc6mqyLVtff4FsoR38XRa7Aye3SgMoD1_RkaQvcfumS0
parent: abstract-factory; artifact: abstract-factory
Puml Server ID: PSZB3OD034NHLa81Czwd6sCC39gVxEUWT1_ssLmTtQLqgR5fM7sTmFGtaV6TZu8prd0r6HtQaMKqAZLk1XjT_E6qgPUZfyc0MdTgx0-8LuUn8ErFXdr98NypXxKyezKV
parent: flux; artifact: flux
Puml Server ID: 7SP14eCm20NGg-W13FlU1YFLE0GpyAazVZk-rPkRLSrDqdKwW14l8kUxx0r7hXdYzJA8eTIhKzEy6UnqyeUNJQBjjWm6n2seS_n3Ryql2UgJajxBoAu_
parent: event-aggregator; artifact: event-aggregator
Puml Server ID: PSf13iCW30NHgxG70Ezx6uTOX0eCih-JwvTzTwEdUJSjFKu9wwyBMFuXCdvoRRZY21ShKo6ANEQWrkDXiD6NRqwdUAkQ5WDYwZJOTv3SUqzSgqbbp0qeVvZ3Hbun-Wy0
parent: singleton; artifact: singleton
Puml Server ID: HSV14SCm20J0Lk82BFxf1ikCh0n26ZZizfDVVhjRjwfvIhg-Bc35cyZvAQtZoYD3l4w364gTWxhcms2d3z-ydnAzsRuO4BUWmV43HRUcWcaagF-Lz55M3lq2
parent: null-object; artifact: null-object
Puml Server ID: JSV14SCm20J0Lk829Fxf1cF6bWSX3JhYzfDdVhjRSx4yDCDU5p3NcoZugMV3bNik3HaETLGPdPhbm-2WcpzS3btjz38PqF15dTSFv6bMndwhW1Jo_vhHwynkNm00
parent: multiton; artifact: multiton
Puml Server ID: FST14i8m20NGg-W16lRUXgPCYnD81Zxs-hfozzvJlOywf68yBc3bYoZuRgVYghrIea-7E5gVHZhgPd3Gcp-y7P9w-hOOaF0au_o1h0OKqqdG_saLrbRP-080
parent: composite; artifact: composite
Puml Server ID: HSf13eCm30NHgy01YFUzZGaM62LEP7-NwvTTT_EaMTLgoqFIst81Cpv4payv5LVk6U9r6CHGwkYaBHy6EztyvUsGqDEsoO2u1NMED-WTvmY5aA3-LT9xcTdR3m00
parent: api-gateway; artifact: image-microservice
Puml Server ID: 3Sp13SCm2030LTe1RFxTXX3aK1biOOZLxPlVlUujHZrFJk-lAsAk3u3ZhatYoYCNEmqBjgWq5AJdna27BzvOJbxIh4oCOBS5Yki1u9JIC7ZZ3pW8HB5nKI4VJtSBSKtNEbFx7m00
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'api-gateway/etc/image-microservice.urm.puml'
pumlid: 3Sp13SCm2030LTe1RFxTXX3aK1biOOZLxPlVlUujHZrFJk-lAsAk3u3ZhatYoYCNEmqBjgWq5AJdna27BzvOJbxIh4oCOBS5Yki1u9JIC7ZZ3pW8HB5nKI4VJtSBSKtNEbFx7m00
parent: api-gateway; artifact: api-gateway-service
Puml Server ID: JSox3SCm303HLP819FRUXg49cO542_nOyFPncUvUSszHwhbpMdyT4TCt0CDLcyIHdtGsEZLOez8vG7ek33JuueLbPvUcPM84cpeCz2S0fvI6mGjluA1_b-Tt2N5D6tNcw3y0
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'api-gateway/etc/api-gateway-service.urm.puml'
pumlid: JSox3SCm303HLP819FRUXg49cO542_nOyFPncUvUSszHwhbpMdyT4TCt0CDLcyIHdtGsEZLOez8vG7ek33JuueLbPvUcPM84cpeCz2S0fvI6mGjluA1_b-Tt2N5D6tNcw3y0
parent: api-gateway; artifact: price-microservice
Puml Server ID: 3Sn13iGW243HgqmFeEpdDfGIoqJK8DJqzkFklyq_f56DYyFgvtOVymjWk78Hl-ECoKQzEJVFr1Mana97Wny-c2wUKbeQwCxM9YZE7O13Ka7dXI-m4mmJugH2rlVksSXXcaTe_GC0
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'api-gateway/etc/price-microservice.urm.puml'
pumlid: 3Sn13iGW243HgqmFeEpdDfGIoqJK8DJqzkFklyq_f56DYyFgvtOVymjWk78Hl-ECoKQzEJVFr1Mana97Wny-c2wUKbeQwCxM9YZE7O13Ka7dXI-m4mmJugH2rlVksSXXcaTe_GC0
parent: object-pool; artifact: object-pool
Puml Server ID: JSV94SCm2030Lk829Fxf1cF6bWU1XYDkFtdcjxiD9Qc3o-LrPQvu0pW-_HnvrLx1JgR9cfrimf1wCD7XnW-sWsESsXPcicl0nFW1RB-PiYqp0KxwVo-VVTMKBm00
parent: adapter; artifact: adapter
Puml Server ID: DSR14S8m30J0Lg20M7-wEMnDOiPMFDA9j0yyUEtUkzMHJTF7xI1NF4GSLzaxZtncgDVJgCPIpobzv0N2vOKtjgRHTziMI7KBcOXl10thfxB-Nz9dMJd71m00
parent: hexagonal; artifact: hexagonal
Puml Server ID: HSTB4W8X30N0g-W1XkozpPD90LO8L3wEnzUTk-xxq2fvSfhSUiJs1v7XAcr4psSwMrqQh57gcZGaBmICNdZZEDb7qsCZWasT9lm7wln1MmeXZlfVIPjbvvGl
parent: value-object; artifact: value-object
Puml Server ID: LSZ13SCm20NGLTe1RExTXX2KECBOmfza_VRQszDxDnVBNJFiTG9pVOY2dteqdBdbqf3XK4ULqQbPFWmEklZcikjgXvV9W8Olwhn-e9ijjOpjKW4fv2zgHgypktq1
parent: twin; artifact: twin
Puml Server ID: 7SR13OCm30NGLUW0n7UsCS42eyH4zdUpFbNVwNtKQij3qjjo0ICs8kTPJiMLUuPuVGnYAFNff2qdWvrk_l9wIEXfws10t88wno-4gKQ2-az9xsLaRoy0
parent: semaphore; artifact: semaphore
Puml Server ID: HSV14SCm20J0Lk82BFxf1ikCfOn06ZZizfDVVhjRjphobFJnQi2ADv7pKwwEbaU6U9q6CPGwbVh8Xy5E7xvvFoNwPVjYGDo2bEC72b5URRgGeFvNqhMirF45
parent: message-channel; artifact: message-channel
Puml Server ID: NSZB3SCm203GLTe1RExTXX1akm9YyMdMRy-zFRtdCf8wkLmUCtF72y3nxcFbhAE2dIvBjknqAIof6nCTtlZ1TdAiOMrZ9hi5ACOFe1o1WnjDD6C1Jlg_NgvzbyeN
parent: poison-pill; artifact: poison-pill
Puml Server ID: JSZ14SCm20NHLf82BExfXiYCJGOX3NpYzkDZRllsgTwjTgcmnmciV145N-rGdFMkbEZJ8OxMvo2rkXWSzE4lRxka7huj1YGyQN3UGMjgpdkh6Gdwlrl5QAk6_G00
parent: aggregator-microservices; artifact: aggregator-service
Puml Server ID: JOov3SCm301NIGQGs7iRXYPa1g8ayB7NjuiKwGvtmBrbKC-Tq_hhY5Y-0HXUjKaS-Kbdepc2HrIQ2jBpma23BvvOTdPfeooCO1iEYlu0O6l63MDQKI6Rp-CKOWSE-ey_NzEqhjH-0m00
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'aggregator-microservices/etc/aggregator-service.urm.puml'
pumlid: JOov3SCm301NIGQGs7iRXYPa1g8ayB7NjuiKwGvtmBrbKC-Tq_hhY5Y-0HXUjKaS-Kbdepc2HrIQ2jBpma23BvvOTdPfeooCO1iEYlu0O6l63MDQKI6Rp-CKOWSE-ey_NzEqhjH-0m00
parent: aggregator-microservices; artifact: information-microservice
Puml Server ID: LSnB3i8m303Hgy016k-vZN5DQXGxaJ_jzUcMtKXFcgSOZTgvV3oEp1Kl0CUhTScZtXNiD2tPij5Ka54N9ZfyySHjvv1ksy9CTWjGZ3i0UtVkcDCt5V9vFquX3k0a4FjCLqoPzgUjNDig7Jy0
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'aggregator-microservices/etc/information-microservice.urm.puml'
pumlid: LSnB3i8m303Hgy016k-vZN5DQXGxaJ_jzUcMtKXFcgSOZTgvV3oEp1Kl0CUhTScZtXNiD2tPij5Ka54N9ZfyySHjvv1ksy9CTWjGZ3i0UtVkcDCt5V9vFquX3k0a4FjCLqoPzgUjNDig7Jy0
parent: aggregator-microservices; artifact: inventory-microservice
Puml Server ID: LSpB3G8n303HLg20ZUzqOxnMrYXn8d-oedjovJRIIEyfIYrFJckFAsBw2y3mBbNYodSw6mqDrYWqEaZB6mCDFhZmEDcbwZ4nWaqTEleEm5gDAyQmemlPsCOIOWSE0j6riM7VlrVIUfdPsmy0
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'aggregator-microservices/etc/inventory-microservice.urm.puml'
pumlid: LSpB3G8n303HLg20ZUzqOxnMrYXn8d-oedjovJRIIEyfIYrFJckFAsBw2y3mBbNYodSw6mqDrYWqEaZB6mCDFhZmEDcbwZ4nWaqTEleEm5gDAyQmemlPsCOIOWSE0j6riM7VlrVIUfdPsmy0
parent: bridge; artifact: bridge
Puml Server ID: BSR14SCm20J0Lf82BFxf1akCJ4R26ZZYzkE7zxLljJgoIVfu7S2A3v7pLRhYo3r3l9u6CPHwJjAH5uETllpZhKbejsqn86v1a-CExQwj2mdgqv8-oyev_W00
parent: servant; artifact: servant
Puml Server ID: DSkn4O0m20NGLNG0G-ys63cDbv0SV7HzRUnUy-QYkSOkONKwWU4haV6JZe8pjd2nt1MYIBatAZKU1XjTVFEoYvT3by60c3erzW_qdPiL9CY_KrXB8rfz0G00
parent: lazy-loading; artifact: lazy-loading
Puml Server ID: LSXB3W8X303Gg-W1e7jlqu66gIc5zED4JwzRTo_lpjeaEwN9xOpO_W0mlEhWEFD89sjBWpHgMnDOyi90WoU-i7Ho7besHf2fmqJ_0GG_xo8BE-i0YlONDMtMdLE-
parent: flyweight; artifact: flyweight
Puml Server ID: HSV94S8m3030Lg20M7-w4OvYAoCh7Xtnq3ty-Eq-MQlaJcdow17JNm26gpIEdkzqidffa4Qfrm2MN1XeSEADsqxEJRU94MJgCD1_W4C-YxZr08hwNqaRPUQGBm00
parent: mutex; artifact: mutex
Puml Server ID: 9SR13OCm30NGLSe0n7UsCS62LB69x6zWV2hrdTxKhFRS9Br_3c34GkHybxtXo3L3l9u6CPHwAhMUDuETldpnl4cqtUR1WBW5ASSlf0bvI53_A-bQHcf_0G00
parent: mediator; artifact: mediator
Puml Server ID: FSV14SCm20J0Lk82BFxf1akCJKOW3JhizfDNVhkRUktP9AE_Bc2kDr7mKqx5bKSkYJeSuYXr66dFXy517xvvRxBqz7qo8E6BZDSFPDAKCO84zP-IOMMczIy0
parent: page-object; artifact: page-object
Puml Server ID: JSV14OGW30NGLjO28FVj9iOCua1Wme-sxnxtzjvMJLeS6ju-9p3NbyZvoQNYZ3sMkWo36hACJhN5ms2dYszEXwvQB4q6r6rHv_K3JIwQndwfW1Jo_npUyupUNW00
parent: factory-kit; artifact: factory-kit
Puml Server ID: JST15i8m20N0g-W14lRU1YcsQ4BooCS-RwzBTpDNSscvQKQx7C1SDwBWi-w68--vD6Gur55bTBAM9uE3dlpcikcotSjaGCCNTLu_q8C58pxbPI25_Bzcz3gpjoy0
parent: property; artifact: property
Puml Server ID: FSV13OCm30NGLTe1YEziumOBKYMEPN-3s9wUUdlltRJst2Izlmx0OYLolihUSEGdGxnEXIXAdODQpul1Jby-UTaasgwBCI2kGOFZ1pAV9ewR1FMVaZwAvUWF
parent: dependency-injection; artifact: dependency-injection
Puml Server ID: RSdB3SCW303GLPe1mFTkunWhSGG6-PEesxS3zFQajubIpyPf_NL6B7y363xra3XpJsUZgS4QbUO0wVbWeC65DvR6BeUMXH5iwZ3GVu36YxMnqgU8NamXKu63_aPD6tNbw5y0
parent: layers; artifact: layers
Puml Server ID: BSR13OCm30NGLSe0n7UsCS62L8w9x6yGszD3t-bDpQhc9kdwEO0H2v7pNVQ68zSCyNeQn53gsQbftWns-lB5yoRHTfi70-8Mr3b-8UL7F4XG_otflOpi-W80
parent: producer-consumer; artifact: producer-consumer
Puml Server ID: PSjB3iCW303HgxG70Ezx6zTO2HKso9_a-c7VtUX9y-vA8nkdZTSPiVm3O7ZNeyUPttGscXgiKMaAz94t1XhyyCBIsFkXPM44cpe8-WvODbiIMzcdfspXe7-jQL9NodW0
parent: builder; artifact: builder
Puml Server ID: DSR94O0m2030LhG0mzzkC64KXs26GzlNZw_TcRLADagJwOWOlW8OFcNdE79B9wkN1ccKUdLWoGS33KwySMdalEioC89C7Jhw5zYIfNrIrFybhPUHNLu0
parent: specification; artifact: specification
Puml Server ID: LSX14i8m20NGg-W16lRU1YcsE0d9mCTUNxVkthoxkVJQjQBVJc3bWoZuQeVXh6UbXao7EfhCGTRhOd3Gcp-yxPfs-BOOqF2amVa3vLAnbmd3ffD2_gTLZBPgz2y0
parent: state; artifact: state
Puml Server ID: 9SRH3O0m20N0LNG0ox_RO2LQqz867hg-9jxNpKLpZLt2wdG2mrSYuoST1MTiuMAvAqIHSczKQZmCDhhuvcKNBuSkWm4nTMhiNyZ141BaVocifH6jlW00
parent: reader-writer-lock; artifact: reader-writer-lock
Puml Server ID: RSZB4S8m303HLg00MtUw4R8cCP5bZpwuVL80jttxx4gIZTFaSKOiVm4OxdhqEFETpaPJWpKgpG5TScEWmGU_M1fxFxGiZ61JXu5-1nXZOolR-gqYaoxWe3-xfeswSiWF
parent: interpreter; artifact: interpreter
Puml Server ID: JSf13eCm30NHgz034E-vZGaM62Kcih_BzQ6xxjv8yr6hBJT9RzC1Z5Y8dE-oAuvSCyJhPH13gLSdRNapsEdaBy-RXEus3mR4BQXpl21zVnykFmlgVvVqNaRszW00
parent: template-method; artifact: template-method
Puml Server ID: NSZ13SCW30NGLPe1mFTkuu0Lg6n0vZjPlpttzlIEFef6bN1zDM3jDv7paw-E5cTiyJ87P22NQTGr7WOxVVZcL6NtQwJ5WFZOPBn_88WjPKWoGPkL1EN_ShZb5QPV
parent: feature-toggle; artifact: feature-toggle
Puml Server ID: NSZ14G8X30NGLhG0oDrk8XjPd12OvCTjNy_UthpxiAPvIBhUJc37WyZvgdtWp6U6U5i6CTIs9WtDYy5ER_vmEIH6jx8P4BUWoV43lOIHBWMhTnKIjB-gwRFkdFe5
parent: business-delegate; artifact: business-delegate
Puml Server ID: POl13SCm3CHMQGU8zUysgYCuBcJ5a4x9-l6_Fu84tzsgvYxf-Zg06HyYvxkqZYE_6UBrD8YXr7DGrxmPxFJZYxTTeZVR9WFY5ZGu5j2wkad4wYgD8IIe_xQaZp9pw0C0
parent: naked-objects; artifact: naked-objects-integtests
Puml Server ID: LSmn4iCW30NHgoG70FMvZGmQ6ni48tt5ru_RT3kls7VJqgDAM7yTmF8FaV6TzuOZjd2nCXMYo6KEQZrk1XkT_ELKnTkkQJ4Wfaw3_GbIlgIckPrIu2Ge_vBQyziX3izX8wyO_GS0
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'naked-objects/etc/naked-objects-integtests.urm.puml'
pumlid: LSmn4iCW30NHgoG70FMvZGmQ6ni48tt5ru_RT3kls7VJqgDAM7yTmF8FaV6TzuOZjd2nCXMYo6KEQZrk1XkT_ELKnTkkQJ4Wfaw3_GbIlgIckPrIu2Ge_vBQyziX3izX8wyO_GS0
parent: naked-objects; artifact: naked-objects-dom
Puml Server ID: LSZ94SCW3030Lf82G7zt8mkDZOC4eyDkF_dcjxFlhZIoSTfudH7BDm33fnuzpjpJsMXgi4QbAT17FXXeSE6DfR7tGyl223Pr4FGVGF73hSpzOWe73lgVqgRKDAahPNm1
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'naked-objects/etc/naked-objects-dom.urm.puml'
pumlid: LSZ94SCW3030Lf82G7zt8mkDZOC4eyDkF_dcjxFlhZIoSTfudH7BDm33fnuzpjpJsMXgi4QbAT17FXXeSE6DfR7tGyl223Pr4FGVGF73hSpzOWe73lgVqgRKDAahPNm1
parent: naked-objects; artifact: naked-objects-fixture
Puml Server ID: LSX15i8W30N0g-W187jlaq9igH1uoO_r-BfrDs_kJKkFAc7zTW3B7qJ6LzuRZjZ2nSfKY2ANEQZrk1XiTFARKnLlkwR5W9Ww3VOVIFabDStjb08dGVcVz6mVX4aE6td5w5y0
I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file 'naked-objects/etc/naked-objects-fixture.urm.puml'
pumlid: LSX15i8W30N0g-W187jlaq9igH1uoO_r-BfrDs_kJKkFAc7zTW3B7qJ6LzuRZjZ2nSfKY2ANEQZrk1XiTFARKnLlkwR5W9Ww3VOVIFabDStjb08dGVcVz6mVX4aE6td5w5y0
parent: model-view-controller; artifact: model-view-controller
Puml Server ID: ROl13SCm201NQGUm-NSRQgE42h258Lw_wR-_qvtkoTOaEwNBuuoOwmNWkEl1SUOx5taR5cHHsr1WoOs13X-yi7HQV5YP645k2nJN3Q2ZavIBQPVVwqFajXJjVwdfMcUgV040
parent: proxy; artifact: proxy
Puml Server ID: 9SR13OCm30NGLM00udktCS62eCI9x6yesrEfx_Jcehd69c5rEe3X7oBZE-q5HwpXOhahH95oRrHgt0msEldYPHClkow30J5rQko_qB3-VKYG_qjXBOrezGK0
parent: memento; artifact: memento
Puml Server ID: DSgn4OCm30NGLM00h3xR2AC3SvRiaxx2-g59zugtDgiz3qdlomNC-10vF-Lik7BF4A_388PIXrBh-J3OwUOlRuT4EssR38XRa7Ay81Lz_o11_RkaQvcf_GS0
parent: decorator; artifact: decorator
Puml Server ID: HSV14SCm20J0Lk82BFxf1YF6LaP26ZZizfDVVhjRC-bPDRs_Bc35cyZvAMV3bKU6kao36ehCGQtdms2d3z-yLursshuOKBUWmV43LPNfZEcaaFzA-YWhH_y2
parent: data-mapper; artifact: data-mapper
Puml Server ID: JShB3OGm303HLg20nFVjnYGM1CN6ycTfVtFSsnjfzY5jPgUqkLqHwXy0mxUU8wuyqidQ8q4IjJqCO-QBWGOtVh5qyd5AKOmW4mT6Nu2-ZiAekapH_hkcSTNa-GC0
parent: caching; artifact: caching
Puml Server ID: DSRB4OKm2030LhG0m_rrWyWaE0bc-6ZxpujxsbMKUXwSrfSMCVq7OFYKAj5oJsUZIuCr2bq3fEU3WGOdthWTx59rcnZ1fWu3_GqGKXEjm47VIzeeCqV_0m00
parent: reactor; artifact: reactor
Puml Server ID: DSR14OGm20NGLjO23FVj1f7Hx2Ga0nzjVxtuJc-f9YrtJM-V4vZn9NA-or5nvfQXBiEWXYAZKsrvCzZfnnUlkqOzR9qCg5jGvtX2hYmOJWfvNz9xcTdR7m00
parent: iterator; artifact: iterator
Puml Server ID: FSV13OGm30NHLg00uljsOu85HeaJsTzB-yjfBwCtgrfjUKXwMovWneV8-IcduiezGxmEWnXA7PsqvSDWfvk_l1qIUjes6H2teCxnWlGDOpW9wdzAUYypU_i1
parent: callback; artifact: callback
Puml Server ID: FSVB4S8m30N0Lg20M7UwUL4qYOciUFGXxSE9s-wp6sjjKgwF8tF6YyXnjxtdKMk5E5-MOjdu6jIrRYIStlXWsIJwRij4fhW53SGFn51TmIT9yZ-jVBHPGxy0
parent: repository; artifact: repository
Puml Server ID: JSV13OCm30NGLM00udktCS42eyI9xE-YRjyUUtjlLQij3qblomNCU14vF-LKNBbdYDTX44EfevEsV1ZiTFERjqD2Jzic0-8Mr3b-89SvGZ7yGuBwrvBUoypUlW00
parent: mute-idiom; artifact: mute-idiom
Puml Server ID: JSf13iCm20NHgxG7iDdtDjH62PKX5luarq-MtSsJvgtUHdR96AyTcEj357pLJR7dDvT4EnpYgEqmqf4NWuD-V7BfidJpCXcGy4N6wmcoX1Jj-lo2ziUQONMcZHi0
parent: prototype; artifact: prototype
Puml Server ID: HSV13OCm30NGLM00udktCS62eCInxE-YRj_UUdjlRLfx7fBUbmkmU14vF-Lik7BF4AzJ8OfIvw3Mys6mqyrltWw9Tkfc38XhqE3uWSmd9Zuc9AZ_bVHHB4V_0W00
parent: step-builder; artifact: step-builder
Puml Server ID: LOZ93SCm3C1MQGQmzUysYYqaAcJ5q96i7t_x8KXkh4soKvfypeZfNm33fnuSP-xfPEtI88tQhW4i-M2WmGzlB9sS3oqJ8yZKOQ0lWOLPzcJfAoZQtwXfeyuSyW80
parent: double-checked-locking; artifact: double-checked-locking
Puml Server ID: TSdH4SCW203GLTe1bFzkGv1J6qGFeLc_MI1_x-wzkv94uJ1vDVUrFm26LwxTMnonsMYgitgcEQ1BNEXeyCKVfiAxLqqBtTbqmy1z0ygCGpXHOpgv99bqTgt0JW-LmqPUCUGF

@@ -1,67 +0,0 @@
#
# The MIT License
# Copyright (c) 2014-2016 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.
#
import requests, glob, re, os
# taken from here: http://stackoverflow.com/a/13641746
def replace(file, pattern, subst):
# Read contents from file as a single string
file_handle = open(file, 'r')
file_string = file_handle.read()
file_handle.close()
# Use RE package to allow for replacement (also allowing for (multiline) REGEX)
file_string = (re.sub(pattern, subst, file_string))
# Write contents to file.
# Using mode 'w' truncates the file.
file_handle = open(file, 'w')
file_handle.write(file_string)
file_handle.close()
# list of all puml files
fileList = glob.glob('*/etc/*.puml')
for puml in fileList:
pathSplit = puml.split("/")
# parent folder
parent = pathSplit[0]
# individual artifact/project name
artifact = pathSplit[2].replace(".urm.puml", "")
print "parent: " + parent + "; artifact: " + artifact
# do a POST to the official plantuml hosting site with a little trick "!includeurl" and raw github content
data = {
'text': "!includeurl https://raw.githubusercontent.com/iluwatar/java-design-patterns/master/" + puml
}
r = requests.post('http://plantuml.com/plantuml/uml', data=data)
pumlId = r.url.replace("http://plantuml.com/plantuml/uml/", "")
# the only thing needed to get a png/svg/ascii from the server back
print "Puml Server ID: " + pumlId
# add the id so jekyll/liquid can use it
if (parent == artifact):
replace("./" + parent + "/README.md", "categories:", "pumlid: {}\\ncategories:".format(pumlId))
else:
print "I dont want to program this, just add the following lines to the README.md file that corresponds to this puml file '" + puml + "'\npumlid: {}".format(pumlId)

@@ -3,7 +3,6 @@ layout: pattern
title: Abstract Document
folder: abstract-document
permalink: /patterns/abstract-document/
pumlid: PSjB3eCm34NHhPG599vtDyQn85L-ifzX-p3lxEf8Twj3MXGDQvyJMFubChxpKN767gucSq07iinEjSNDOACVNvoAUZr6MWoe3QVE_WRnxZ0Mf38b-hkIGlurX_MyehS7
categories: Structural
tags:
- Java
@@ -13,8 +12,6 @@ tags:
## Intent
Achieve flexibility of untyped languages and keep the type-safety
![alt text](./etc/abstract-document-base.png "Abstract Document Base")
![alt text](./etc/abstract-document.png "Abstract Document Traits and Domain")

Binary file not shown.

Before

(image error) Size: 15 KiB

Binary file not shown.

Before

(image error) Size: 16 KiB

After

(image error) Size: 94 KiB

@@ -1,91 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.1.9" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
realizations="true" associations="true" dependencies="false" nesting-relationships="true" router="FAN">
<interface id="1" language="java" name="com.iluwatar.abstractdocument.Document" project="design-patterns"
file="/design-patterns/src/com/iluwatar/abstractdocument/Document.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="341" y="376"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<interface id="2" language="java" name="com.iluwatar.abstractdocument.domain.HasModel" project="design-patterns"
file="/design-patterns/src/com/iluwatar/abstractdocument/domain/HasModel.java" binary="false" corner="BOTTOM_RIGHT">
<position height="81" width="173" x="41" y="194"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<interface id="3" language="java" name="com.iluwatar.abstractdocument.domain.HasPrice" project="design-patterns"
file="/design-patterns/src/com/iluwatar/abstractdocument/domain/HasPrice.java" binary="false" corner="BOTTOM_RIGHT">
<position height="81" width="175" x="254" y="194"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<interface id="4" language="java" name="com.iluwatar.abstractdocument.domain.HasParts" project="design-patterns"
file="/design-patterns/src/com/iluwatar/abstractdocument/domain/HasParts.java" binary="false" corner="BOTTOM_RIGHT">
<position height="81" width="173" x="469" y="194"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<class id="5" language="java" name="com.iluwatar.abstractdocument.domain.Car" project="design-patterns"
file="/design-patterns/src/com/iluwatar/abstractdocument/domain/Car.java" binary="false" corner="BOTTOM_RIGHT">
<position height="99" width="173" x="254" y="37"/>
<class-diagram version="1.2.2" icons="true" always-add-relationships="false" generalizations="true" realizations="true"
associations="true" dependencies="false" nesting-relationships="true" router="FAN">
<class id="1" language="java" name="com.iluwatar.abstractdocument.AbstractDocument" project="abstract-document"
file="/abstract-document/src/main/java/com/iluwatar/abstractdocument/AbstractDocument.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="659" y="286"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="6" language="java" name="com.iluwatar.abstractdocument.domain.Part" project="design-patterns"
file="/design-patterns/src/com/iluwatar/abstractdocument/domain/Part.java" binary="false" corner="BOTTOM_RIGHT">
<position height="99" width="173" x="41" y="37"/>
<interface id="2" language="java" name="com.iluwatar.abstractdocument.Document" project="abstract-document"
file="/abstract-document/src/main/java/com/iluwatar/abstractdocument/Document.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="562" y="27"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<class id="3" language="java" name="com.iluwatar.abstractdocument.domain.Car" project="abstract-document"
file="/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/Car.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="348" y="737"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<realization id="7">
<end type="SOURCE" refId="5"/>
<end type="TARGET" refId="2"/>
<class id="4" language="java" name="com.iluwatar.abstractdocument.domain.Part" project="abstract-document"
file="/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/Part.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="760" y="746"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<interface id="5" language="java" name="com.iluwatar.abstractdocument.domain.HasModel" project="abstract-document"
file="/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasModel.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="355" y="297"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<interface id="6" language="java" name="com.iluwatar.abstractdocument.domain.HasParts" project="abstract-document"
file="/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasParts.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="109" y="297"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<interface id="7" language="java" name="com.iluwatar.abstractdocument.domain.HasPrice" project="abstract-document"
file="/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasPrice.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="1008" y="283"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<interface id="8" language="java" name="com.iluwatar.abstractdocument.domain.HasType" project="abstract-document"
file="/abstract-document/src/main/java/com/iluwatar/abstractdocument/domain/HasType.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="1257" y="277"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<realization id="9">
<end type="SOURCE" refId="4"/>
<end type="TARGET" refId="8"/>
</realization>
<realization id="8">
<realization id="10">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="7"/>
</realization>
<generalization id="11">
<end type="SOURCE" refId="6"/>
<end type="TARGET" refId="2"/>
</realization>
<generalization id="9">
<end type="SOURCE" refId="2"/>
<end type="TARGET" refId="1"/>
</generalization>
<realization id="10">
<end type="SOURCE" refId="5"/>
<end type="TARGET" refId="3"/>
<realization id="12">
<end type="SOURCE" refId="4"/>
<end type="TARGET" refId="5"/>
</realization>
<realization id="11">
<end type="SOURCE" refId="5"/>
<end type="TARGET" refId="4"/>
<realization id="13">
<end type="SOURCE" refId="4"/>
<end type="TARGET" refId="7"/>
</realization>
<generalization id="12">
<generalization id="14">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="1"/>
</generalization>
<generalization id="13">
<realization id="15">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="6"/>
</realization>
<generalization id="16">
<end type="SOURCE" refId="8"/>
<end type="TARGET" refId="2"/>
</generalization>
<generalization id="17">
<end type="SOURCE" refId="7"/>
<end type="TARGET" refId="2"/>
</generalization>
<realization id="18">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="5"/>
</realization>
<generalization id="19">
<end type="SOURCE" refId="4"/>
<end type="TARGET" refId="1"/>
</generalization>
<realization id="14">
<end type="SOURCE" refId="6"/>
<end type="TARGET" refId="3"/>
<generalization id="20">
<end type="SOURCE" refId="5"/>
<end type="TARGET" refId="2"/>
</generalization>
<realization id="21">
<end type="SOURCE" refId="1"/>
<end type="TARGET" refId="2"/>
</realization>
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">

@@ -1,59 +0,0 @@
@startuml
package com.iluwatar.abstractdocument.domain {
class Car {
+ Car(properties : Map<String, Object>)
}
interface HasModel {
+ PROPERTY : String {static}
+ getModel() : Optional<String>
}
interface HasParts {
+ PROPERTY : String {static}
+ getParts() : Stream<Part>
}
interface HasPrice {
+ PROPERTY : String {static}
+ getPrice() : Optional<Number>
}
interface HasType {
+ PROPERTY : String {static}
+ 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

@@ -29,13 +29,18 @@
<parent>
<artifactId>java-design-patterns</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<artifactId>abstract-document</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

@@ -22,7 +22,7 @@
*/
package com.iluwatar.abstractdocument;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.HashMap;
@@ -30,8 +30,8 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* AbstractDocument test class

@@ -22,7 +22,7 @@
*/
package com.iluwatar.abstractdocument;
import org.junit.Test;
import org.junit.jupiter.api.Test;
/**
* Simple App test

@@ -28,13 +28,13 @@ import com.iluwatar.abstractdocument.domain.HasParts;
import com.iluwatar.abstractdocument.domain.HasPrice;
import com.iluwatar.abstractdocument.domain.HasType;
import com.iluwatar.abstractdocument.domain.Part;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import static junit.framework.TestCase.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test for Part and Car

@@ -3,7 +3,6 @@ layout: pattern
title: Abstract Factory
folder: abstract-factory
permalink: /patterns/abstract-factory/
pumlid: PSZB3OD034NHLa81Czwd6sCC39gVxEUWT1_ssLmTtQLqgR5fM7sTmFGtaV6TZu8prd0r6HtQaMKqAZLk1XjT_E6qgPUZfyc0MdTgx0-8LuUn8ErFXdr98NypXxKyezKV
categories: Creational
tags:
- Java
@@ -18,7 +17,146 @@ Kit
Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.
![alt text](./etc/abstract-factory_1.png "Abstract Factory")
## Explanation
Real world example
> To create a kingdom we need objects with common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom.
In plain words
> A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes.
Wikipedia says
> The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes
**Programmatic Example**
Translating the kingdom example above. First of all we have some interfaces and implementation for the objects in the kingdom
```java
public interface Castle {
String getDescription();
}
public interface King {
String getDescription();
}
public interface Army {
String getDescription();
}
// Elven implementations ->
public class ElfCastle implements Castle {
static final String DESCRIPTION = "This is the Elven castle!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfKing implements King {
static final String DESCRIPTION = "This is the Elven king!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfArmy implements Army {
static final String DESCRIPTION = "This is the Elven Army!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
// Orcish implementations similarly...
```
Then we have the abstraction and implementations for the kingdom factory
```java
public interface KingdomFactory {
Castle createCastle();
King createKing();
Army createArmy();
}
public class ElfKingdomFactory implements KingdomFactory {
public Castle createCastle() {
return new ElfCastle();
}
public King createKing() {
return new ElfKing();
}
public Army createArmy() {
return new ElfArmy();
}
}
public class OrcKingdomFactory implements KingdomFactory {
public Castle createCastle() {
return new OrcCastle();
}
public King createKing() {
return new OrcKing();
}
public Army createArmy() {
return new OrcArmy();
}
}
```
Now we have our abstract factory that lets us make family of related objects i.e. Elven kingdom factory creates Elven castle, king and army etc.
```java
KingdomFactory factory = new ElfKingdomFactory();
Castle castle = factory.createCastle();
King king = factory.createKing();
Army army = factory.createArmy();
castle.getDescription(); // Output: This is the Elven castle!
king.getDescription(); // Output: This is the Elven king!
army.getDescription(); // Output: This is the Elven Army!
```
Now, we can design a factory for our different kingdom factories. In this example, we created FactoryMaker, responsible for returning an instance of either ElfKingdomFactory or OrcKingdomFactory.
The client can use FactoryMaker to create the desired concrete factory which, in turn, will produce different concrete objects (Army, King, Castle).
In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for.
```java
public static class FactoryMaker {
public enum KingdomType {
ELF, ORC
}
public static KingdomFactory makeFactory(KingdomType type) {
switch (type) {
case ELF:
return new ElfKingdomFactory();
case ORC:
return new OrcKingdomFactory();
default:
throw new IllegalArgumentException("KingdomType not supported.");
}
}
}
public static void main(String[] args) {
App app = new App();
LOGGER.info("Elf Kingdom");
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
LOGGER.info("Orc Kingdom");
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
-- similar use of the orc factory
}
```
## Applicability
Use the Abstract Factory pattern when
@@ -27,6 +165,28 @@ Use the Abstract Factory pattern when
* a system should be configured with one of multiple families of products
* a family of related product objects is designed to be used together, and you need to enforce this constraint
* you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations
* the lifetime of the dependency is conceptually shorter than the lifetime of the consumer.
* you need a run-time value to construct a particular dependency
* you want to decide which product to call from a family at runtime.
* you need to supply one or more parameters only known at run-time before you can resolve a dependency.
## Use Cases:
* Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime.
* Unit test case writing becomes much easier
## Consequences:
* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time.
## Tutorial
* [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java)
## Presentations
* [Abstract Factory Pattern](etc/presentation.html)
## Real world examples

Binary file not shown.

Before

(image error) Size: 21 KiB

@@ -1,159 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
<interface id="1" language="java" name="com.iluwatar.abstractfactory.Army" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Army.java" binary="false" corner="BOTTOM_RIGHT">
<position height="70" width="161" x="1407" y="300"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<interface id="2" language="java" name="com.iluwatar.abstractfactory.KingdomFactory" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/KingdomFactory.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="124" width="161" x="1001" y="300"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<class id="3" language="java" name="com.iluwatar.abstractfactory.ElfCastle" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfCastle.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="106" width="161" x="96" y="118"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="4" language="java" name="com.iluwatar.abstractfactory.ElfKingdomFactory" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKingdomFactory.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="142" width="161" x="900" y="118"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="5" language="java" name="com.iluwatar.abstractfactory.ElfKing" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfKing.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="106" width="161" x="498" y="118"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<interface id="6" language="java" name="com.iluwatar.abstractfactory.King" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/King.java" binary="false" corner="BOTTOM_RIGHT">
<position height="70" width="161" x="599" y="300"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<class id="7" language="java" name="com.iluwatar.abstractfactory.OrcCastle" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcCastle.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="106" width="161" x="297" y="118"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="8" language="java" name="com.iluwatar.abstractfactory.OrcKing" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKing.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="106" width="161" x="699" y="118"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="9" language="java" name="com.iluwatar.abstractfactory.ElfArmy" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/ElfArmy.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="106" width="161" x="1306" y="118"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="10" language="java" name="com.iluwatar.abstractfactory.OrcArmy" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcArmy.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="106" width="161" x="1507" y="118"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<interface id="11" language="java" name="com.iluwatar.abstractfactory.Castle" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/Castle.java" binary="false" corner="BOTTOM_RIGHT">
<position height="70" width="161" x="197" y="300"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<class id="12" language="java" name="com.iluwatar.abstractfactory.OrcKingdomFactory" project="abstract-factory"
file="/abstract-factory/src/main/java/com/iluwatar/abstractfactory/OrcKingdomFactory.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="142" width="165" x="1101" y="118"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<realization id="13">
<end type="SOURCE" refId="4"/>
<end type="TARGET" refId="2"/>
</realization>
<realization id="14">
<end type="SOURCE" refId="7"/>
<end type="TARGET" refId="11"/>
</realization>
<realization id="15">
<end type="SOURCE" refId="8"/>
<end type="TARGET" refId="6"/>
</realization>
<realization id="16">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="11"/>
</realization>
<realization id="17">
<end type="SOURCE" refId="10"/>
<end type="TARGET" refId="1"/>
</realization>
<realization id="18">
<end type="SOURCE" refId="12"/>
<end type="TARGET" refId="2"/>
</realization>
<realization id="19">
<end type="SOURCE" refId="5"/>
<end type="TARGET" refId="6"/>
</realization>
<realization id="20">
<end type="SOURCE" refId="9"/>
<end type="TARGET" refId="1"/>
</realization>
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</classifier-display>
<association-display labels="true" multiplicity="true"/>
</class-diagram>

@@ -1,89 +0,0 @@
@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)
}
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
}
}
App --> "-castle" Castle
App --> "-king" King
App --> "-army" Army
ElfArmy ..|> Army
ElfCastle ..|> Castle
ElfKing ..|> King
ElfKingdomFactory ..|> KingdomFactory
OrcArmy ..|> Army
OrcCastle ..|> Castle
OrcKing ..|> King
OrcKingdomFactory ..|> KingdomFactory
@enduml

Binary file not shown.

Before

(image error) Size: 57 KiB

Binary file not shown.

After

(image error) Size: 57 KiB

Binary file not shown.

After

(image error) Size: 26 KiB

@@ -0,0 +1,190 @@
<!--
The MIT License
Copyright (c) 2017 Rodolfo Forte
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.
-->
<!DOCTYPE html>
<html>
<head>
<title>Design Patterns - Abstract Factory Presentation</title>
<meta charset="utf-8">
<style>
@import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
@import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
@import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
body { font-family: 'Droid Serif'; }
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: normal;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
blockquote {
border-left: 0.3em solid rgba(0,0,0,0.5);
padding: 0 15px;
font-style: italic;
}
img {
max-width:100%;
}
</style>
</head>
<body>
<textarea id="source">
class: center, middle
# Abstract Factory
---
# Also known as
* Kit
---
# Intent
* Provide an interface for creating families of related or dependent objects without specifying their concrete classes
---
# Explanation
* [Wikipedia](https://en.wikipedia.org/wiki/Abstract_factory_pattern) says:
> "The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes"
<br />
* In plain words:
* A factory that groups individual but related/dependent factories together without specifying their concrete classes;
* A factory of factories;
---
# Example
* In a factory that creates kingdoms, we need objects with common theme:
* Elven kingdom needs an Elven king, Elven castle and Elven army;
* Orcish kingdom needs an Orcish king, Orcish castle and Orcish army;
<br />
* There is a dependency between the objects in the kingdom;
---
# Diagram
* Based on the kingdom example, the diagram below showcases the different concrete factories and their concrete products:
.center[![Diagram](diagram1.png)]
---
# Diagram
* The class diagram below showcases the factory of factories;
* At runtime, we can define which Kingdom type is needed and pass it as a parameter to define which concrete KingdomFactory to instantiate;
* The concrete factory returned will then be able to produce the related objects of the specified type;
.center[![Diagram](diagram2.png)]
---
# Applicability
Use the Abstract Factory pattern when:
* A system should be independent of how its products are created, composed and represented;
* A system should be configured with one of multiple families of products;
* A family of related product objects is designed to be used together, and you need to enforce this constraint;
* You want to provide a class library of products, and you want to reveal just their interfaces, not their implementations;
---
# Applicability
Use the Abstract Factory pattern when:
* The lifetime of the dependency is conceptually shorter than the lifetime of the consumer;
* You need a run-time value to construct a particular dependency;
* You want to decide which product to call from a family at runtime;
* You need to supply one or more parameters only known at run-time before you can resolve a dependency;
---
#Use Cases
* Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime;
* Unit test case writing becomes much easier;
---
# Consequences
* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time
---
# Real world examples
[javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
[javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--)
[javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--)
---
# Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
---
# Tutorials
* Source code http://java-design-patterns.com/patterns/abstract-factory/
</textarea>
<script src="https://gnab.github.io/remark/downloads/remark-latest.min.js">
</script>
<script>
var slideshow = remark.create();
</script>
</body>
</html>

@@ -29,13 +29,18 @@
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<artifactId>abstract-factory</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

@@ -25,6 +25,8 @@ package com.iluwatar.abstractfactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType;
/**
*
* The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme
@@ -94,7 +96,34 @@ public class App {
}
/**
* Program entry point
* The factory of kingdom factories.
*/
public static class FactoryMaker {
/**
* Enumeration for the different types of Kingdoms.
*/
public enum KingdomType {
ELF, ORC
}
/**
* The factory method to create KingdomFactory concrete objects.
*/
public static KingdomFactory makeFactory(KingdomType type) {
switch (type) {
case ELF:
return new ElfKingdomFactory();
case ORC:
return new OrcKingdomFactory();
default:
throw new IllegalArgumentException("KingdomType not supported.");
}
}
}
/**
* Program entry point.
*
* @param args
* command line args
@@ -104,17 +133,15 @@ public class App {
App app = new App();
LOGGER.info("Elf Kingdom");
app.createKingdom(new ElfKingdomFactory());
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
LOGGER.info("Orc Kingdom");
app.createKingdom(new OrcKingdomFactory());
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
}
}

@@ -22,22 +22,28 @@
*/
package com.iluwatar.abstractfactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Before;
import org.junit.Test;
import com.iluwatar.abstractfactory.App.FactoryMaker;
import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test for abstract factory
*/
public class AbstractFactoryTest {
private App app = new App();
private KingdomFactory elfFactory;
private KingdomFactory orcFactory;
@Before
@BeforeEach
public void setUp() {
elfFactory = new ElfKingdomFactory();
orcFactory = new OrcKingdomFactory();
elfFactory = FactoryMaker.makeFactory(KingdomType.ELF);
orcFactory = FactoryMaker.makeFactory(KingdomType.ORC);
}
@Test

@@ -22,7 +22,7 @@
*/
package com.iluwatar.abstractfactory;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import java.io.IOException;

39
acyclic-visitor/README.md Normal file

@@ -0,0 +1,39 @@
---
layout: pattern
title: Acyclic Visitor
folder: acyclic-visitor
permalink: /patterns/acyclic-visitor/
categories: Behavioral
tags:
- Java
- Difficulty-Intermediate
---
![alt text](./etc/acyclic-visitor.png "Acyclic Visitor")
## 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.
## 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.
* When the visited class hierarchy will be frequently extended with new derivatives of the Element class.
* When the recompilation, relinking, retesting or redistribution of the derivatives of Element is very expensive.
## 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.
## Related patterns
* [Visitor Pattern](../visitor/README.md)
## Credits
* [Acyclic Visitor](http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf)

@@ -1,113 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
<class id="1" language="java" name="com.iluwatar.factory.method.OrcBlacksmith" project="factory-method"
file="/factory-method/src/main/java/com/iluwatar/factory/method/OrcBlacksmith.java" binary="false"
<class-diagram version="1.2.2" icons="true" always-add-relationships="false" generalizations="true" realizations="true"
associations="true" dependencies="false" nesting-relationships="true" router="FAN">
<interface id="1" language="java" name="com.iluwatar.acyclicvisitor.ModemVisitor" project="acyclic-visitor"
file="/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ModemVisitor.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="106" width="280" x="-46" y="239"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<interface id="2" language="java" name="com.iluwatar.factory.method.Blacksmith" project="factory-method"
file="/factory-method/src/main/java/com/iluwatar/factory/method/Blacksmith.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="88" width="280" x="114" y="385"/>
<position height="-1" width="-1" x="860" y="67"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<enumeration id="3" language="java" name="com.iluwatar.factory.method.WeaponType" project="factory-method"
file="/factory-method/src/main/java/com/iluwatar/factory/method/WeaponType.java" binary="false"
<class id="2" language="java" name="com.iluwatar.acyclicvisitor.Modem" project="acyclic-visitor"
file="/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/Modem.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="327" y="77"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="3" language="java" name="com.iluwatar.acyclicvisitor.ConfigureForUnixVisitor" project="acyclic-visitor"
file="/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForUnixVisitor.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="196" width="210" x="793" y="385"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</enumeration>
<class id="4" language="java" name="com.iluwatar.factory.method.OrcWeapon" project="factory-method"
file="/factory-method/src/main/java/com/iluwatar/factory/method/OrcWeapon.java" binary="false" corner="BOTTOM_RIGHT">
<position height="106" width="178" x="806" y="239"/>
<position height="124" width="196" x="647" y="225"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="5" language="java" name="com.iluwatar.factory.method.ElfWeapon" project="factory-method"
file="/factory-method/src/main/java/com/iluwatar/factory/method/ElfWeapon.java" binary="false" corner="BOTTOM_RIGHT">
<position height="106" width="172" x="594" y="239"/>
<class id="4" language="java" name="com.iluwatar.acyclicvisitor.Zoom" project="acyclic-visitor"
file="/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/Zoom.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="203" y="305"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<interface id="6" language="java" name="com.iluwatar.factory.method.Weapon" project="factory-method"
file="/factory-method/src/main/java/com/iluwatar/factory/method/Weapon.java" binary="false" corner="BOTTOM_RIGHT">
<position height="70" width="159" x="594" y="385"/>
<interface id="5" language="java" name="com.iluwatar.acyclicvisitor.HayesVisitor" project="acyclic-visitor"
file="/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/HayesVisitor.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="1019" y="468"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<class id="7" language="java" name="com.iluwatar.factory.method.ElfBlacksmith" project="factory-method"
file="/factory-method/src/main/java/com/iluwatar/factory/method/ElfBlacksmith.java" binary="false"
<interface id="6" language="java" name="com.iluwatar.acyclicvisitor.ZoomVisitor" project="acyclic-visitor"
file="/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ZoomVisitor.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="106" width="280" x="274" y="239"/>
<position height="-1" width="-1" x="758" y="467"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<class id="7" language="java" name="com.iluwatar.acyclicvisitor.Hayes" project="acyclic-visitor"
file="/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/Hayes.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="479" y="307"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<realization id="8">
<end type="SOURCE" refId="4"/>
<end type="TARGET" refId="6"/>
</realization>
<realization id="9">
<class id="8" language="java" name="com.iluwatar.acyclicvisitor.ConfigureForDosVisitor" project="acyclic-visitor"
file="/acyclic-visitor/src/main/java/com/iluwatar/acyclicvisitor/ConfigureForDosVisitor.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="142" width="192" x="883" y="225"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<generalization id="9">
<end type="SOURCE" refId="7"/>
<end type="TARGET" refId="2"/>
</realization>
</generalization>
<realization id="10">
<end type="SOURCE" refId="5"/>
<end type="SOURCE" refId="8"/>
<end type="TARGET" refId="6"/>
</realization>
<association id="11">
<end type="SOURCE" refId="4" navigable="false">
<attribute id="12" name="weaponType">
<position height="0" width="0" x="0" y="0"/>
</attribute>
<multiplicity id="13" minimum="0" maximum="1">
<position height="0" width="0" x="0" y="0"/>
</multiplicity>
</end>
<end type="TARGET" refId="3" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<realization id="14">
<end type="SOURCE" refId="1"/>
<end type="TARGET" refId="2"/>
<realization id="11">
<end type="SOURCE" refId="8"/>
<end type="TARGET" refId="5"/>
</realization>
<association id="15">
<end type="SOURCE" refId="5" navigable="false">
<attribute id="16" name="weaponType">
<position height="0" width="0" x="0" y="0"/>
</attribute>
<multiplicity id="17" minimum="0" maximum="1">
<position height="0" width="0" x="0" y="0"/>
</multiplicity>
</end>
<end type="TARGET" refId="3" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<realization id="12">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="6"/>
</realization>
<realization id="13">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="1"/>
</realization>
<realization id="14">
<end type="SOURCE" refId="8"/>
<end type="TARGET" refId="1"/>
</realization>
<generalization id="15">
<end type="SOURCE" refId="4"/>
<end type="TARGET" refId="2"/>
</generalization>
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>

Binary file not shown.

After

(image error) Size: 26 KiB

76
acyclic-visitor/pom.xml Normal file

@@ -0,0 +1,76 @@
<!--
The MIT License
Copyright (c) 2014 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.20.0-SNAPSHOT</version>
</parent>
<artifactId>acyclic-visitor</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.assertj/assertj-core -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.9.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/uk.org.lidalia/slf4j-test -->
<dependency>
<groupId>uk.org.lidalia</groupId>
<artifactId>slf4j-test</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</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>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@@ -20,19 +20,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.bridge;
package com.iluwatar.acyclicvisitor;
/**
*
* MagicWeaponImpl
*
* All ModemVisitor interface extends all visitor interfaces. This interface
* provides ease of use when a visitor needs to visit all modem types.
*/
public abstract class MagicWeaponImpl {
public abstract void wieldImp();
public abstract void swingImp();
public abstract void unwieldImp();
public interface AllModemVisitor extends ZoomVisitor, HayesVisitor{
}

@@ -0,0 +1,55 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
/**
* The Acyclic Visitor pattern allows new functions to be added to existing class
* hierarchies without affecting those hierarchies, and without creating the dependency
* cycles that are inherent to the GoF Visitor pattern, by making the Visitor base class
* degenerate
* <p>
* In this example the visitor base class is {@link ModemVisitor}. The base class of the
* visited hierarchy is {@link Modem} and has two children {@link Hayes} and {@link Zoom}
* each one having its own visitor interface {@link HayesVisitor} and {@link ZoomVisitor}
* respectively. {@link ConfigureForUnixVisitor} and {@link ConfigureForDosVisitor}
* implement each derivative's visit method only if it is required
*/
public class App {
/**
* Program's entry point
*/
public static void main(String[] args) {
ConfigureForUnixVisitor conUnix = new ConfigureForUnixVisitor();
ConfigureForDosVisitor conDos = new ConfigureForDosVisitor();
Zoom zoom = new Zoom();
Hayes hayes = new Hayes();
hayes.accept(conDos); // Hayes modem with Unix configurator
zoom.accept(conDos); // Zoom modem with Dos configurator
hayes.accept(conUnix); // Hayes modem with Unix configurator
zoom.accept(conUnix); // Zoom modem with Unix configurator
}
}

@@ -20,37 +20,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.bridge;
package com.iluwatar.acyclicvisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* Mjollnir
*
* ConfigureForDosVisitor class implements both zoom's and hayes' visit method
* for Dos manufacturer
*/
public class Mjollnir extends FlyingMagicWeaponImpl {
public class ConfigureForDosVisitor implements AllModemVisitor {
private static final Logger LOGGER = LoggerFactory.getLogger(Mjollnir.class);
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForDosVisitor.class);
@Override
public void wieldImp() {
LOGGER.info("wielding Mjollnir");
public void visit(Hayes hayes) {
LOGGER.info(hayes + " used with Dos configurator.");
}
@Override
public void swingImp() {
LOGGER.info("swinging Mjollnir");
}
@Override
public void unwieldImp() {
LOGGER.info("unwielding Mjollnir");
}
@Override
public void flyImp() {
LOGGER.info("Mjollnir hits the enemy in the air and returns back to the owner's hand");
public void visit(Zoom zoom) {
LOGGER.info(zoom + " used with Dos configurator.");
}
}

@@ -0,0 +1,40 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* ConfigureForUnixVisitor class implements zoom's visit method for Unix
* manufacturer, unlike traditional visitor pattern, this class may selectively implement
* visit for other modems.
*/
public class ConfigureForUnixVisitor implements ZoomVisitor {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForUnixVisitor.class);
public void visit(Zoom zoom) {
LOGGER.info(zoom + " used with Unix configurator.");
}
}

@@ -0,0 +1,56 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Hayes class implements its accept method
*/
public class Hayes extends Modem {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForDosVisitor.class);
/**
* Accepts all visitors but honors only HayesVisitor
*/
@Override
public void accept(ModemVisitor modemVisitor) {
if (modemVisitor instanceof HayesVisitor) {
((HayesVisitor) modemVisitor).visit(this);
} else {
LOGGER.info("Only HayesVisitor is allowed to visit Hayes modem");
}
}
/**
* Hayes' modem's toString
* method
*/
@Override
public String toString() {
return "Hayes modem";
}
}

@@ -0,0 +1,30 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
/**
* HayesVisitor interface
*/
public interface HayesVisitor extends ModemVisitor {
void visit(Hayes hayes);
}

@@ -0,0 +1,30 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
/**
* Modem abstract class
*/
public abstract class Modem {
public abstract void accept(ModemVisitor modemVisitor);
}

@@ -0,0 +1,32 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
/**
* ModemVisitor interface does not contain any visit methods so that it does not
* depend on the visited hierarchy. Each derivative's visit method is declared in
* its own visitor interface
*/
public interface ModemVisitor {
// Visitor is a degenerate base class for all visitors.
}

@@ -0,0 +1,55 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Zoom class implements its accept method
*/
public class Zoom extends Modem {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigureForDosVisitor.class);
/**
* Accepts all visitors but honors only ZoomVisitor
*/
@Override
public void accept(ModemVisitor modemVisitor) {
if (modemVisitor instanceof ZoomVisitor) {
((ZoomVisitor) modemVisitor).visit(this);
} else {
LOGGER.info("Only ZoomVisitor is allowed to visit Zoom modem");
}
}
/**
* Zoom modem's toString
* method
*/
@Override
public String toString() {
return "Zoom modem";
}
}

@@ -20,16 +20,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.iterator;
package com.iluwatar.acyclicvisitor;
/**
*
* ItemIterator interface.
*
* ZoomVisitor interface
*/
public interface ItemIterator {
boolean hasNext();
Item next();
public interface ZoomVisitor extends ModemVisitor {
void visit(Zoom zoom);
}

@@ -0,0 +1,39 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
import org.junit.jupiter.api.Test;
import com.iluwatar.acyclicvisitor.App;
/**
* Tests that the Acyclic Visitor example runs without errors.
*/
public class AppTest {
@Test
public void test() {
String[] args = {};
App.main(args);
}
}

@@ -0,0 +1,75 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
import static org.mockito.Mockito.mock;
import static uk.org.lidalia.slf4jext.Level.INFO;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import com.iluwatar.acyclicvisitor.ConfigureForDosVisitor;
import com.iluwatar.acyclicvisitor.Hayes;
import com.iluwatar.acyclicvisitor.HayesVisitor;
import com.iluwatar.acyclicvisitor.Zoom;
import com.iluwatar.acyclicvisitor.ZoomVisitor;
import uk.org.lidalia.slf4jtest.TestLogger;
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
/**
* ConfigureForDosVisitor test class
*/
public class ConfigureForDosVisitorTest {
TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForDosVisitor.class);
@Test
public void testVisitForZoom() {
ConfigureForDosVisitor conDos = new ConfigureForDosVisitor();
Zoom zoom = new Zoom();
conDos.visit(zoom);
assertThat(logger.getLoggingEvents()).extracting("level", "message").contains(
tuple(INFO, zoom + " used with Dos configurator."));
}
@Test
public void testVisitForHayes() {
ConfigureForDosVisitor conDos = new ConfigureForDosVisitor();
Hayes hayes = new Hayes();
conDos.visit(hayes);
assertThat(logger.getLoggingEvents()).extracting("level", "message").contains(
tuple(INFO, hayes + " used with Dos configurator."));
}
@AfterEach
public void clearLoggers() {
TestLoggerFactory.clear();
}
}

@@ -0,0 +1,65 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.acyclicvisitor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
import static uk.org.lidalia.slf4jext.Level.INFO;
import static org.mockito.Mockito.mock;
import uk.org.lidalia.slf4jtest.TestLogger;
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
import org.junit.jupiter.api.Test;
import com.iluwatar.acyclicvisitor.ConfigureForUnixVisitor;
import com.iluwatar.acyclicvisitor.Hayes;
import com.iluwatar.acyclicvisitor.HayesVisitor;
import com.iluwatar.acyclicvisitor.Zoom;
import com.iluwatar.acyclicvisitor.ZoomVisitor;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
/**
* ConfigureForUnixVisitor test class
*/
public class ConfigureForUnixVisitorTest {
TestLogger logger = TestLoggerFactory.getTestLogger(ConfigureForUnixVisitor.class);
@AfterEach
public void clearLoggers() {
TestLoggerFactory.clear();
}
@Test
public void testVisitForZoom() {
ConfigureForUnixVisitor conUnix = new ConfigureForUnixVisitor();
Zoom zoom = new Zoom();
conUnix.visit(zoom);
assertThat(logger.getLoggingEvents()).extracting("level", "message").contains(
tuple(INFO, zoom + " used with Unix configurator."));
}
}

@@ -20,36 +20,41 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.bridge;
package com.iluwatar.acyclicvisitor;
import org.junit.Test;
import static org.mockito.Mockito.spy;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static org.mockito.Mockito.verifyZeroInteractions;
import org.junit.jupiter.api.Test;
import com.iluwatar.acyclicvisitor.ConfigureForDosVisitor;
import com.iluwatar.acyclicvisitor.ConfigureForUnixVisitor;
import com.iluwatar.acyclicvisitor.Hayes;
import com.iluwatar.acyclicvisitor.HayesVisitor;
/**
* Date: 12/6/15 - 11:26 PM
*
* @author Jeroen Meulemeester
* Hayes test class
*/
public class FlyingMagicWeaponTest extends MagicWeaponTest {
public class HayesTest {
/**
* Invoke all possible actions on the weapon and check if the actions are executed on the actual
* underlying weapon implementation.
*/
@Test
public void testMjollnir() throws Exception {
final Mjollnir mjollnir = spy(new Mjollnir());
final FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(mjollnir);
public void testAcceptForDos() {
Hayes hayes = new Hayes();
ConfigureForDosVisitor mockVisitor = mock(ConfigureForDosVisitor.class);
testBasicWeaponActions(flyingMagicWeapon, mjollnir);
flyingMagicWeapon.fly();
verify(mjollnir, times(1)).flyImp();
verifyNoMoreInteractions(mjollnir);
hayes.accept(mockVisitor);
verify((HayesVisitor)mockVisitor).visit(eq(hayes));
}
@Test
public void testAcceptForUnix() {
Hayes hayes = new Hayes();
ConfigureForUnixVisitor mockVisitor = mock(ConfigureForUnixVisitor.class);
hayes.accept(mockVisitor);
verifyZeroInteractions(mockVisitor);
}
}

@@ -20,36 +20,40 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.bridge;
package com.iluwatar.acyclicvisitor;
import org.junit.Test;
import static org.mockito.Mockito.spy;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.internal.verification.VerificationModeFactory.times;
import static org.mockito.Mockito.mock;
import org.junit.jupiter.api.Test;
import com.iluwatar.acyclicvisitor.ConfigureForDosVisitor;
import com.iluwatar.acyclicvisitor.ConfigureForUnixVisitor;
import com.iluwatar.acyclicvisitor.Zoom;
import com.iluwatar.acyclicvisitor.ZoomVisitor;
/**
* Date: 12/6/15 - 11:15 PM
*
* @author Jeroen Meulemeester
* Zoom test class
*/
public class BlindingMagicWeaponTest extends MagicWeaponTest {
public class ZoomTest {
/**
* Invoke all possible actions on the weapon and check if the actions are executed on the actual
* underlying weapon implementation.
*/
@Test
public void testExcalibur() throws Exception {
final Excalibur excalibur = spy(new Excalibur());
final BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(excalibur);
public void testAcceptForDos() {
Zoom zoom = new Zoom();
ConfigureForDosVisitor mockVisitor = mock(ConfigureForDosVisitor.class);
testBasicWeaponActions(blindingMagicWeapon, excalibur);
blindingMagicWeapon.blind();
verify(excalibur, times(1)).blindImp();
verifyNoMoreInteractions(excalibur);
zoom.accept(mockVisitor);
verify((ZoomVisitor)mockVisitor).visit(eq(zoom));
}
@Test
public void testAcceptForUnix() {
Zoom zoom = new Zoom();
ConfigureForUnixVisitor mockVisitor = mock(ConfigureForUnixVisitor.class);
zoom.accept(mockVisitor);
verify((ZoomVisitor)mockVisitor).visit(eq(zoom));
}
}

@@ -3,7 +3,6 @@ layout: pattern
title: Adapter
folder: adapter
permalink: /patterns/adapter/
pumlid: DSR14S8m30J0Lg20M7-wEMnDOiPMFDA9j0yyUEtUkzMHJTF7xI1NF4GSLzaxZtncgDVJgCPIpobzv0N2vOKtjgRHTziMI7KBcOXl10thfxB-Nz9dMJd71m00
categories: Structural
tags:
- Java
@@ -19,7 +18,85 @@ Convert the interface of a class into another interface the clients
expect. Adapter lets classes work together that couldn't otherwise because of
incompatible interfaces.
![alt text](./etc/adapter.png "Adapter")
## Explanation
Real world example
> Consider that you have some pictures in your memory card and you need to transfer them to your computer. In order to transfer them you need some kind of adapter that is compatible with your computer ports so that you can attach memory card to your computer. In this case card reader is an adapter.
> Another example would be the famous power adapter; a three legged plug can't be connected to a two pronged outlet, it needs to use a power adapter that makes it compatible with the two pronged outlet.
> Yet another example would be a translator translating words spoken by one person to another
In plain words
> Adapter pattern lets you wrap an otherwise incompatible object in an adapter to make it compatible with another class.
Wikipedia says
> In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.
**Programmatic Example**
Consider a captain that can only use rowing boats and cannot sail at all.
First we have interfaces `RowingBoat` and `FishingBoat`
```java
public interface RowingBoat {
void row();
}
public class FishingBoat {
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
public void sail() {
LOGGER.info("The fishing boat is sailing");
}
}
```
And captain expects an implementation of `RowingBoat` interface to be able to move
```java
public class Captain implements RowingBoat {
private RowingBoat rowingBoat;
public Captain(RowingBoat rowingBoat) {
this.rowingBoat = rowingBoat;
}
@Override
public void row() {
rowingBoat.row();
}
}
```
Now let's say the pirates are coming and our captain needs to escape but there is only fishing boat available. We need to create an adapter that allows the captain to operate the fishing boat with his rowing boat skills.
```java
public class FishingBoatAdapter implements RowingBoat {
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoatAdapter.class);
private FishingBoat boat;
public FishingBoatAdapter() {
boat = new FishingBoat();
}
@Override
public void row() {
boat.sail();
}
}
```
And now the `Captain` can use the `FishingBoat` to escape the pirates.
```java
Captain captain = new Captain(new FishingBoatAdapter());
captain.row();
```
## Applicability
Use the Adapter pattern when
@@ -27,6 +104,20 @@ Use the Adapter pattern when
* you want to use an existing class, and its interface does not match the one you need
* you want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces
* you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class.
* most of the applications using third party libraries use adapters as a middle layer between the application and the 3rd party library to decouple the application from the library. If another library has to be used only an adapter for the new library is required without having to change the application code.
## Consequences:
Class and object adapters have different trade-offs. A class adapter
* adapts Adaptee to Target by committing to a concrete Adaptee class. As a consequence, a class adapter wont work when we want to adapt a class and all its subclasses.
* lets Adapter override some of Adaptees behavior, since Adapter is a subclass of Adaptee.
* introduces only one object, and no additional pointer indirection is needed to get to the adaptee.
An object adapter
* lets a single Adapter work with many Adaptees—that is, the Adaptee itself and all of its subclasses (if any). The Adapter can also add functionality to all Adaptees at once.
* makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making Adapter refer to the subclass rather than the Adaptee itself.
## Real world examples

Binary file not shown.

Before

(image error) Size: 12 KiB

@@ -1,37 +0,0 @@
@startuml
package com.iluwatar.adapter {
class App {
+ App()
+ main(args : String[]) {static}
}
class BattleFishingBoat {
- LOGGER : Logger {static}
- boat : FishingBoat
+ BattleFishingBoat()
+ fire()
+ move()
}
interface BattleShip {
+ fire() {abstract}
+ move() {abstract}
}
class Captain {
- battleship : BattleShip
+ Captain()
+ Captain(battleship : BattleShip)
+ fire()
+ move()
+ setBattleship(battleship : BattleShip)
}
class FishingBoat {
- LOGGER : Logger {static}
+ FishingBoat()
+ fish()
+ sail()
}
}
BattleFishingBoat --> "-boat" FishingBoat
Captain --> "-battleship" BattleShip
BattleFishingBoat ..|> BattleShip
Captain ..|> BattleShip
@enduml

@@ -29,13 +29,18 @@
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<artifactId>adapter</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@@ -34,14 +34,14 @@ package com.iluwatar.adapter;
* object. This example uses the object adapter approach.
*
* <p>
* The Adapter ({@link BattleFishingBoat}) converts the interface of the adaptee class (
* {@link FishingBoat}) into a suitable one expected by the client ( {@link BattleShip} ).
* The Adapter ({@link FishingBoatAdapter}) converts the interface of the adaptee class (
* {@link FishingBoat}) into a suitable one expected by the client ( {@link RowingBoat} ).
*
* <p>
* The story of this implementation is this. <br>
* Pirates are coming! we need a {@link BattleShip} to fight! We have a {@link FishingBoat} and our
* Pirates are coming! we need a {@link RowingBoat} to flee! We have a {@link FishingBoat} and our
* captain. We have no time to make up a new ship! we need to reuse this {@link FishingBoat}. The
* captain needs a battleship which can fire and move. The spec is in {@link BattleShip}. We will
* captain needs a rowing boat which he can operate. The spec is in {@link RowingBoat}. We will
* use the Adapter pattern to reuse {@link FishingBoat}.
*
*/
@@ -53,8 +53,8 @@ public class App {
* @param args command line args
*/
public static void main(String[] args) {
Captain captain = new Captain(new BattleFishingBoat());
captain.move();
captain.fire();
// The captain can only operate rowing boats but with adapter he is able to use fishing boats as well
Captain captain = new Captain(new FishingBoatAdapter());
captain.row();
}
}

@@ -23,33 +23,25 @@
package com.iluwatar.adapter;
/**
* The Captain uses {@link BattleShip} to fight. <br>
* The Captain uses {@link RowingBoat} to sail. <br>
* This is the client in the pattern.
*/
public class Captain implements BattleShip {
public class Captain {
private BattleShip battleship;
private RowingBoat rowingBoat;
public Captain() {
public Captain() {}
public Captain(RowingBoat rowingBoat) {
this.rowingBoat = rowingBoat;
}
public Captain(BattleShip battleship) {
this.battleship = battleship;
public void setRowingBoat(RowingBoat rowingBoat) {
this.rowingBoat = rowingBoat;
}
public void setBattleship(BattleShip battleship) {
this.battleship = battleship;
}
@Override
public void fire() {
battleship.fire();
}
@Override
public void move() {
battleship.move();
public void row() {
rowingBoat.row();
}
}

@@ -27,7 +27,8 @@ import org.slf4j.LoggerFactory;
/**
*
* Device class (adaptee in the pattern). We want to reuse this class
* Device class (adaptee in the pattern). We want to reuse this class.
* Fishing boat moves by sailing.
*
*/
public class FishingBoat {
@@ -35,11 +36,7 @@ public class FishingBoat {
private static final Logger LOGGER = LoggerFactory.getLogger(FishingBoat.class);
public void sail() {
LOGGER.info("The Boat is moving to that place");
}
public void fish() {
LOGGER.info("fishing ...");
LOGGER.info("The fishing boat is sailing");
}
}

@@ -20,28 +20,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.bridge;
package com.iluwatar.adapter;
/**
*
* MagicWeapon
* Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link RowingBoat}
* interface expected by the client ({@link Captain}).
*
*/
public abstract class MagicWeapon {
public class FishingBoatAdapter implements RowingBoat {
protected MagicWeaponImpl imp;
private FishingBoat boat;
public MagicWeapon(MagicWeaponImpl imp) {
this.imp = imp;
public FishingBoatAdapter() {
boat = new FishingBoat();
}
public abstract void wield();
public abstract void swing();
public abstract void unwield();
public MagicWeaponImpl getImp() {
return imp;
@Override
public void row() {
boat.sail();
}
}

@@ -24,13 +24,11 @@ package com.iluwatar.adapter;
/**
* The interface expected by the client.<br>
* A Battleship can fire and move.
* A rowing boat is rowed to move.
*
*/
public interface BattleShip {
public interface RowingBoat {
void fire();
void move();
void row();
}

@@ -22,8 +22,8 @@
*/
package com.iluwatar.adapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.Map;
@@ -39,45 +39,40 @@ public class AdapterPatternTest {
private Map<String, Object> beans;
private static final String BATTLESHIP_BEAN = "engineer";
private static final String FISHING_BEAN = "fisher";
private static final String CAPTAIN_BEAN = "captain";
private static final String ROWING_BEAN = "captain";
/**
* This method runs before the test execution and sets the bean objects in the beans Map.
*/
@Before
@BeforeEach
public void setup() {
beans = new HashMap<>();
BattleFishingBoat battleFishingBoat = spy(new BattleFishingBoat());
beans.put(BATTLESHIP_BEAN, battleFishingBoat);
FishingBoatAdapter fishingBoatAdapter = spy(new FishingBoatAdapter());
beans.put(FISHING_BEAN, fishingBoatAdapter);
Captain captain = new Captain();
captain.setBattleship((BattleFishingBoat) beans.get(BATTLESHIP_BEAN));
beans.put(CAPTAIN_BEAN, captain);
captain.setRowingBoat((FishingBoatAdapter) beans.get(FISHING_BEAN));
beans.put(ROWING_BEAN, captain);
}
/**
* This test asserts that when we use the move() method on a captain bean(client), it is
* internally calling move method on the battleship object. The Adapter ({@link BattleFishingBoat}
* This test asserts that when we use the row() method on a captain bean(client), it is
* internally calling sail method on the fishing boat object. The Adapter ({@link FishingBoatAdapter}
* ) converts the interface of the target class ( {@link FishingBoat}) into a suitable one
* expected by the client ({@link Captain} ).
*/
@Test
public void testAdapter() {
BattleShip captain = (BattleShip) beans.get(CAPTAIN_BEAN);
Captain captain = (Captain) beans.get(ROWING_BEAN);
// when captain moves
captain.move();
captain.row();
// the captain internally calls the battleship object to move
BattleShip battleship = (BattleShip) beans.get(BATTLESHIP_BEAN);
verify(battleship).move();
// same with above with firing
captain.fire();
verify(battleship).fire();
RowingBoat adapter = (RowingBoat) beans.get(FISHING_BEAN);
verify(adapter).row();
}
}

@@ -22,7 +22,7 @@
*/
package com.iluwatar.adapter;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import java.io.IOException;

@@ -3,7 +3,6 @@ layout: pattern
title: Aggregator Microservices
folder: aggregator-microservices
permalink: /patterns/aggregator-microservices/
pumlid: JOov3SCm301NIGQGs7iRXYPa1g8ayB7NjuiKwGvtmBrbKC-Tq_hhY5Y-0HXUjKaS-Kbdepc2HrIQ2jBpma23BvvOTdPfeooCO1iEYlu0O6l63MDQKI6Rp-CKOWSE-ey_NzEqhjH-0m00
categories: Architectural
tags:
- Java

@@ -29,7 +29,7 @@
<parent>
<artifactId>aggregator-microservices</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -54,8 +54,13 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@@ -25,6 +25,9 @@ package com.iluwatar.aggregator.microservices;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Spring Boot EntryPoint Class
*/
@SpringBootApplication
public class App {

@@ -22,15 +22,18 @@
*/
package com.iluwatar.aggregator.microservices;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
/**
* Test Aggregation of domain objects
*/
public class AggregatorTest {
@InjectMocks
@@ -42,7 +45,7 @@ public class AggregatorTest {
@Mock
private ProductInventoryClient inventoryClient;
@Before
@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}

@@ -1,43 +0,0 @@
@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() : int {abstract}
}
class ProductInventoryClientImpl {
- LOGGER : Logger {static}
+ ProductInventoryClientImpl()
+ getProductInventories() : int
}
}
Aggregator --> "-informationClient" ProductInformationClient
Aggregator --> "-inventoryClient" ProductInventoryClient
ProductInformationClientImpl ..|> ProductInformationClient
ProductInventoryClientImpl ..|> ProductInventoryClient
@enduml

@@ -1,12 +0,0 @@
@startuml
package com.iluwatar.information.microservice {
class InformationApplication {
+ InformationApplication()
+ main(args : String[]) {static}
}
class InformationController {
+ InformationController()
+ getProductTitle() : String
}
}
@enduml

@@ -1,12 +0,0 @@
@startuml
package com.iluwatar.inventory.microservice {
class InventoryApplication {
+ InventoryApplication()
+ main(args : String[]) {static}
}
class InventoryController {
+ InventoryController()
+ getProductInventories() : int
}
}
@enduml

@@ -29,7 +29,7 @@
<parent>
<artifactId>aggregator-microservices</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -54,8 +54,13 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

@@ -26,6 +26,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* Controller providing endpoints to retrieve information about products
*/
@RestController
public class InformationController {

@@ -22,9 +22,13 @@
*/
package com.iluwatar.information.microservice;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test for Information Rest Controller
*/
public class InformationControllerTest {
@Test
@@ -33,7 +37,7 @@ public class InformationControllerTest {
String title = infoController.getProductTitle();
Assert.assertEquals("The Product Title.", title);
assertEquals("The Product Title.", title);
}
}

@@ -29,7 +29,7 @@
<parent>
<artifactId>aggregator-microservices</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -54,8 +54,13 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

@@ -26,6 +26,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* Controller providing endpoints to retrieve product inventories
*/
@RestController
public class InventoryController {

@@ -22,17 +22,20 @@
*/
package com.iluwatar.inventory.microservice;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test Inventory Rest Controller
*/
public class InventoryControllerTest {
@Test
public void testGetProductInventories() throws Exception {
InventoryController inventoryController = new InventoryController();
int numberOfInventories = inventoryController.getProductInventories();
Assert.assertEquals(5, numberOfInventories);
assertEquals(5, numberOfInventories);
}
}

@@ -29,32 +29,11 @@
<parent>
<artifactId>java-design-patterns</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>aggregator-microservices</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>com.github.markusmo3.urm</groupId>
<artifactId>urm-maven-plugin</artifactId>
<version>${urm.version}</version>
<configuration combine.self="override">
<outputDirectory>${project.basedir}/../etc</outputDirectory>
<packages>
<param>com.iluwatar</param>
</packages>
<skipForProjects>
<!-- skip for parent project -->
<param>aggregator-microservices</param>
</skipForProjects>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>information-microservice</module>
<module>aggregator-service</module>

178
ambassador/README.md Normal file

@@ -0,0 +1,178 @@
---
layout: pattern
title: Ambassador
folder: ambassador
permalink: /patterns/ambassador/
categories: Structural
tags:
- Java
- Difficulty-Intermediate
---
## Intent
Provide a helper service instance on a client and offload common functionality away from a shared resource.
## Explanation
Real world example
> A remote service has many clients accessing a function it provides. The service is a legacy application and is impossible to update. Large numbers of requests from users are causing connectivity issues. New rules for request frequency should be implemented along with latency checks and client-side logging.
In plain words
> Using the ambassador pattern, we can implement less-frequent polling from clients along with latency checks and logging.
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.
**Programmatic Example**
With the above example in mind we will imitate the functionality in a simple manner. We have an interface implemented by the remote service as well as the ambassador service:
```java
interface RemoteServiceInterface {
long doRemoteFunction(int value) throws Exception;
}
```
A remote services represented as a singleton.
```java
public class RemoteService implements RemoteServiceInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class);
private static RemoteService service = null;2
static synchronized RemoteService getRemoteService() {
if (service == null) {
service = new RemoteService();
}
return service;
}
private RemoteService() {}
@Override
public long doRemoteFunction(int value) {
long waitTime = (long) Math.floor(Math.random() * 1000);
try {
sleep(waitTime);
} catch (InterruptedException e) {
LOGGER.error("Thread sleep interrupted", e)
}
return waitTime >= 200 ? value * 10 : -1;
}
}
```
A service ambassador adding additional features such as logging, latency checks
```java
public class ServiceAmbassador implements RemoteServiceInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceAmbassador.class);
private static final int RETRIES = 3;
private static final int DELAY_MS = 3000;
ServiceAmbassador() {}
@Override
public long doRemoteFunction(int value) {
return safeCall(value);
}
private long checkLatency(int value) {
RemoteService service = RemoteService.getRemoteService();
long startTime = System.currentTimeMillis();
long result = service.doRemoteFunction(value);
long timeTaken = System.currentTimeMillis() - startTime;
LOGGER.info("Time taken (ms): " + timeTaken);
return result;
}
private long safeCall(int value) {
int retries = 0;
long result = -1;
for (int i = 0; i < RETRIES; i++) {
if (retries >= RETRIES) {
return -1;
}
if ((result = checkLatency(value)) == -1) {
LOGGER.info("Failed to reach remote: (" + (i + 1) + ")");
retries++;
try {
sleep(DELAY_MS);
} catch (InterruptedException e) {
LOGGER.error("Thread sleep state interrupted", e);
}
} else {
break;
}
}
return result;
}
}
```
A client has a local service ambassador used to interact with the remote service:
```java
public class Client {
private ServiceAmbassador serviceAmbassador;
Client() {
serviceAmbassador = new ServiceAmbassador();
}
long useService(int value) {
long result = serviceAmbassador.doRemoteFunction(value);
LOGGER.info("Service result: " + result)
return result;
}
}
```
And here are two clients using the service.
```java
Client host1 = new Client();
Client host2 = new Client();
host1.useService(12);
host2.useService(73);
```
## 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
be implemented on the client avoiding the need for changes on the remote service.
* Ambassador provides a local interface for a remote service.
* Ambassador provides logging, circuit breaking, retries and security on the client.
## Typical Use Case
* Control access to another object
* Implement logging
* Implement circuit breaking
* Offload remote service tasks
* Facilitate network connection
## Real world examples
* [Kubernetes-native API gateway for microservices](https://github.com/datawire/ambassador)
## Credits
* [Ambassador pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/ambassador)
* [Designing Distributed Systems: Patterns and Paradigms for Scalable, Reliable Services](https://books.google.co.uk/books?id=6BJNDwAAQBAJ&pg=PT35&lpg=PT35&dq=ambassador+pattern+in+real+world&source=bl&ots=d2e7GhYdHi&sig=Lfl_MDnCgn6lUcjzOg4GXrN13bQ&hl=en&sa=X&ved=0ahUKEwjk9L_18rrbAhVpKcAKHX_KA7EQ6AEIWTAI#v=onepage&q=ambassador%20pattern%20in%20real%20world&f=false)

48
ambassador/pom.xml Normal file

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
The MIT License
Copyright (c) 2014-2016 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.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ambassador</artifactId>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@@ -0,0 +1,53 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.ambassador;
/**
*
* The ambassador pattern creates a helper service that sends network requests on behalf of a
* client. It is often used in cloud-based applications to offload features of a remote service.
*
* An ambassador service can be thought of as an out-of-process proxy that is co-located with
* the client. Similar to the proxy design pattern, the ambassador service provides an interface
* for another remote service. In addition to the interface, the ambassador provides extra
* functionality and features, specifically offloaded common connectivity tasks. This usually
* consists of monitoring, logging, routing, security etc. This is extremely useful in
* legacy applications where the codebase is difficult to modify and allows for improvements
* in the application's networking capabilities.
*
* In this example, we will the ({@link ServiceAmbassador}) class represents the ambassador while the
* ({@link RemoteService}) class represents a remote application.
*
*/
public class App {
/**
* Entry point
*/
public static void main(String[] args) {
Client host1 = new Client();
Client host2 = new Client();
host1.useService(12);
host2.useService(73);
}
}

@@ -0,0 +1,42 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.ambassador;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
/**
* A simple Client
*/
public class Client {
private static final Logger LOGGER = LoggerFactory.getLogger(Client.class);
private final ServiceAmbassador serviceAmbassador = new ServiceAmbassador();
long useService(int value) {
long result = serviceAmbassador.doRemoteFunction(value);
LOGGER.info("Service result: " + result);
return result;
}
}

@@ -0,0 +1,65 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.ambassador;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.lang.Thread.sleep;
/**
* A remote legacy application represented by a Singleton implementation.
*/
public class RemoteService implements RemoteServiceInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(RemoteService.class);
private static RemoteService service = null;
static synchronized RemoteService getRemoteService() {
if (service == null) {
service = new RemoteService();
}
return service;
}
private RemoteService() {}
/**
* Remote function takes a value and multiplies it by 10 taking a random amount of time.
* Will sometimes return -1. This imitates connectivity issues a client might have to account for.
* @param value integer value to be multiplied.
* @return if waitTime is more than 200ms, it returns value * 10, otherwise -1.
*/
@Override
public long doRemoteFunction(int value) {
long waitTime = (long) Math.floor(Math.random() * 1000);
try {
sleep(waitTime);
} catch (InterruptedException e) {
LOGGER.error("Thread sleep state interrupted", e);
}
return waitTime >= 200 ? value * 10 : -1;
}
}

@@ -0,0 +1,31 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.ambassador;
/**
* Interface shared by ({@link RemoteService}) and ({@link ServiceAmbassador}).
*/
interface RemoteServiceInterface {
long doRemoteFunction(int value) throws Exception;
}

@@ -0,0 +1,84 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.ambassador;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.lang.Thread.sleep;
/**
*
* ServiceAmbassador provides an interface for a ({@link Client}) to access ({@link RemoteService}).
* The interface adds logging, latency testing and usage of the service in a safe way that will not
* add stress to the remote service when connectivity issues occur.
*
*/
public class ServiceAmbassador implements RemoteServiceInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceAmbassador.class);
private static final int RETRIES = 3;
private static final int DELAY_MS = 3000;
ServiceAmbassador() {}
@Override
public long doRemoteFunction(int value) {
return safeCall(value);
}
private long checkLatency(int value) {
long startTime = System.currentTimeMillis();
long result = RemoteService.getRemoteService().doRemoteFunction(value);
long timeTaken = System.currentTimeMillis() - startTime;
LOGGER.info("Time taken (ms): " + timeTaken);
return result;
}
private long safeCall(int value) {
int retries = 0;
long result = -1;
for (int i = 0; i < RETRIES; i++) {
if (retries >= RETRIES) {
return -1;
}
if ((result = checkLatency(value)) == -1) {
LOGGER.info("Failed to reach remote: (" + (i + 1) + ")");
retries++;
try {
sleep(DELAY_MS);
} catch (InterruptedException e) {
LOGGER.error("Thread sleep state interrupted", e);
}
} else {
break;
}
}
return result;
}
}

@@ -20,15 +20,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.bridge;
package com.iluwatar.ambassador;
import org.junit.jupiter.api.Test;
/**
*
* SoulEatingMagicWeaponImpl
*
* Application test
*/
public abstract class SoulEatingMagicWeaponImpl extends MagicWeaponImpl {
public abstract void eatSoulImp();
public class AppTest {
@Test
public void test() {
App.main(new String[]{});
}
}

@@ -0,0 +1,40 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.ambassador;
import org.junit.jupiter.api.Test;
/**
* Test for {@link Client}
*/
public class ClientTest {
@Test
public void test() {
Client client = new Client();
long result = client.useService(10);
assert result == 100 || result == -1;
}
}

@@ -0,0 +1,37 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.ambassador;
import org.junit.jupiter.api.Test;
/**
* Test for {@link RemoteService}
*/
public class RemoteServiceTest {
@Test
public void test() {
long result = RemoteService.getRemoteService().doRemoteFunction(10);
assert result == 100 || result == -1;
}
}

@@ -0,0 +1,37 @@
/**
* The MIT License
* Copyright (c) 2014-2016 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.ambassador;
import org.junit.jupiter.api.Test;
/**
* Test for {@link ServiceAmbassador}
*/
public class ServiceAmbassadorTest {
@Test
public void test() {
long result = new ServiceAmbassador().doRemoteFunction(10);
assert result == 100 || result == -1;
}
}

@@ -3,7 +3,6 @@ layout: pattern
title: API Gateway
folder: api-gateway
permalink: /patterns/api-gateway/
pumlid: JSox3SCm303HLP819FRUXg49cO542_nOyFPncUvUSszHwhbpMdyT4TCt0CDLcyIHdtGsEZLOez8vG7ek33JuueLbPvUcPM84cpeCz2S0fvI6mGjluA1_b-Tt2N5D6tNcw3y0
categories: Architectural
tags:
- Java

@@ -29,7 +29,7 @@
<parent>
<artifactId>api-gateway</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api-gateway-service</artifactId>
@@ -53,8 +53,13 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@@ -35,7 +35,7 @@ import java.io.IOException;
* An adapter to communicate with the Image microservice
*/
@Component
public class ImageClientImpl implements ImageClient{
public class ImageClientImpl implements ImageClient {
/**
* Makes a simple HTTP Get request to the Image microservice
* @return The path to the image

@@ -35,7 +35,7 @@ import java.io.IOException;
* An adapter to communicate with the Price microservice
*/
@Component
public class PriceClientImpl implements PriceClient{
public class PriceClientImpl implements PriceClient {
/**
* Makes a simple HTTP Get request to the Price microservice
* @return The price of the product

@@ -22,15 +22,18 @@
*/
package com.iluwatar.api.gateway;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
/**
* Test API Gateway Pattern
*/
public class ApiGatewayTest {
@InjectMocks
@@ -42,7 +45,7 @@ public class ApiGatewayTest {
@Mock
private PriceClient priceClient;
@Before
@BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}

@@ -1,48 +0,0 @@
@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

@@ -1,12 +0,0 @@
@startuml
package com.iluwatar.image.microservice {
class ImageApplication {
+ ImageApplication()
+ main(args : String[]) {static}
}
class ImageController {
+ ImageController()
+ getImagePath() : String
}
}
@enduml

@@ -1,12 +0,0 @@
@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.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -54,8 +54,13 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

@@ -22,9 +22,13 @@
*/
package com.iluwatar.image.microservice;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test for Image Rest Controller
*/
public class ImageControllerTest {
@Test
public void testGetImagePath() {
@@ -32,6 +36,6 @@ public class ImageControllerTest {
String imagePath = imageController.getImagePath();
Assert.assertEquals("/product-image.png", imagePath);
assertEquals("/product-image.png", imagePath);
}
}

@@ -29,32 +29,11 @@
<parent>
<artifactId>java-design-patterns</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api-gateway</artifactId>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>com.github.markusmo3.urm</groupId>
<artifactId>urm-maven-plugin</artifactId>
<version>${urm.version}</version>
<configuration combine.self="override">
<outputDirectory>${project.basedir}/../etc</outputDirectory>
<packages>
<param>com.iluwatar</param>
</packages>
<skipForProjects>
<!-- skip for parent project -->
<param>api-gateway</param>
</skipForProjects>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>image-microservice</module>
<module>price-microservice</module>

@@ -29,7 +29,7 @@
<parent>
<artifactId>api-gateway</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -54,8 +54,13 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

@@ -22,9 +22,13 @@
*/
package com.iluwatar.price.microservice;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test for Price Rest Controller
*/
public class PriceControllerTest {
@Test
public void testgetPrice() {
@@ -32,6 +36,6 @@ public class PriceControllerTest {
String price = priceController.getPrice();
Assert.assertEquals("20", price);
assertEquals("20", price);
}
}

@@ -3,7 +3,6 @@ layout: pattern
title: Async Method Invocation
folder: async-method-invocation
permalink: /patterns/async-method-invocation/
pumlid: TSdB3SCW303GLTe1mFTkunWhk0A3_4dKxTi5UdlIUuhIoCPfuz4Zjhy03EzwIlGyqjbeQR16fJL1HjuOQF362qjZbrFBnWWsTPZeFm3wHwbCZhvQ4RqMOSXIuA1_LzDctJd75m00
categories: Concurrency
tags:
- Java

@@ -1,51 +0,0 @@
@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

@@ -29,13 +29,18 @@
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.14.0-SNAPSHOT</version>
<version>1.20.0-SNAPSHOT</version>
</parent>
<artifactId>async-method-invocation</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>

@@ -25,8 +25,8 @@ package com.iluwatar.async.method.invocation;
import java.util.concurrent.ExecutionException;
/**
*
* AsyncResult interface
* @param <T> parameter returned when getValue is invoked
*/
public interface AsyncResult<T> {

Some files were not shown because too many files have changed in this diff Show More