From 5ad99be224166a664706058f2845fa2a48cca6b5 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Mon, 25 Jan 2016 21:10:58 +0000 Subject: [PATCH 01/22] #354 Add maven model for feature toggle design pattern --- feature-toggle/pom.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 feature-toggle/pom.xml diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml new file mode 100644 index 000000000..71aa837de --- /dev/null +++ b/feature-toggle/pom.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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.10.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>feature-toggle</artifactId> + + +</project> \ No newline at end of file From cf10bd1d05da1254ccbf36a4d4673f8fe585f1e0 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Mon, 25 Jan 2016 21:11:26 +0000 Subject: [PATCH 02/22] #354 Add maven model for feature toggle design pattern --- feature-toggle/pom.xml | 24 ++++++++++++++++++++++++ pom.xml | 1 + 2 files changed, 25 insertions(+) diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index 71aa837de..98c140f37 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -1,4 +1,28 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ The MIT License (MIT) + ~ + ~ Copyright (c) 2016 Orange Foundry + ~ + ~ 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"> diff --git a/pom.xml b/pom.xml index c929f2945..68208288d 100644 --- a/pom.xml +++ b/pom.xml @@ -91,6 +91,7 @@ <module>publish-subscribe</module> <module>delegation</module> <module>event-driven-architecture</module> + <module>feature-toggle</module> </modules> <dependencyManagement> From d7526fc7c0ecff5dc2d56768ecde3f878f935fa5 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Mon, 25 Jan 2016 21:14:24 +0000 Subject: [PATCH 03/22] #354 Add maven model for feature toggle design pattern --- abstract-factory/index.md | 13 +- adapter/index.md | 13 +- async-method-invocation/index.md | 8 +- bridge/index.md | 12 +- builder/index.md | 10 +- business-delegate/index.md | 6 +- caching/index.md | 8 +- callback/index.md | 8 +- chain/index.md | 10 +- command/index.md | 15 +- composite/index.md | 10 +- dao/index.md | 8 +- decorator/etc/decorator.png | Bin 8109 -> 29945 bytes decorator/etc/decorator.ucls | 45 ++-- decorator/etc/decorator_1.png | Bin 24245 -> 0 bytes decorator/index.md | 13 +- .../main/java/com/iluwatar/decorator/App.java | 4 +- .../{SmartTroll.java => SmartHostile.java} | 12 +- ...rtTrollTest.java => SmartHostileTest.java} | 6 +- delegation/index.md | 13 +- dependency-injection/index.md | 6 +- double-checked-locking/index.md | 6 +- double-dispatch/index.md | 8 +- event-aggregator/index.md | 8 +- event-driven-architecture/index.md | 11 +- execute-around/index.md | 6 +- facade/index.md | 8 +- factory-method/index.md | 11 +- fluentinterface/index.md | 13 +- flux/index.md | 8 +- flyweight/index.md | 10 +- front-controller/index.md | 10 +- half-sync-half-async/index.md | 10 +- intercepting-filter/index.md | 10 +- interpreter/index.md | 8 +- iterator/index.md | 13 +- layers/index.md | 9 +- lazy-loading/index.md | 8 +- mediator/index.md | 8 +- memento/index.md | 13 +- message-channel/index.md | 12 +- model-view-controller/index.md | 8 +- model-view-presenter/index.md | 8 +- monostate/index.md | 10 +- multiton/index.md | 6 +- naked-objects/index.md | 10 +- null-object/index.md | 6 +- object-pool/index.md | 6 +- observer/index.md | 15 +- poison-pill/index.md | 8 +- pom.xml | 16 +- private-class-data/index.md | 6 +- producer-consumer/index.md | 6 +- property/index.md | 8 +- prototype/index.md | 10 +- proxy/index.md | 15 +- publish-subscribe/index.md | 10 +- reactor/index.md | 10 +- reader-writer-lock/etc/reader-writer-lock.png | Bin 0 -> 39623 bytes .../etc/reader-writer-lock.ucls | 86 +++++++ reader-writer-lock/index.md | 29 +++ reader-writer-lock/pom.xml | 24 ++ .../com/iluwatar/reader/writer/lock/App.java | 56 +++++ .../iluwatar/reader/writer/lock/Reader.java | 40 ++++ .../reader/writer/lock/ReaderWriterLock.java | 211 ++++++++++++++++++ .../iluwatar/reader/writer/lock/Writer.java | 40 ++++ .../iluwatar/reader/writer/lock/AppTest.java | 16 ++ .../writer/lock/ReaderAndWriterTest.java | 81 +++++++ .../reader/writer/lock/ReaderTest.java | 50 +++++ .../reader/writer/lock/StdOutTest.java | 53 +++++ .../reader/writer/lock/WriterTest.java | 50 +++++ repository/index.md | 11 +- .../index.md | 6 +- servant/index.md | 6 +- service-layer/index.md | 8 +- service-locator/index.md | 10 +- singleton/index.md | 12 +- specification/index.md | 8 +- state/index.md | 11 +- step-builder/index.md | 8 +- strategy/index.md | 11 +- template-method/index.md | 8 +- thread-pool/index.md | 6 +- tolerant-reader/index.md | 8 +- twin/index.md | 8 +- visitor/index.md | 10 +- 86 files changed, 1165 insertions(+), 270 deletions(-) delete mode 100644 decorator/etc/decorator_1.png rename decorator/src/main/java/com/iluwatar/decorator/{SmartTroll.java => SmartHostile.java} (56%) rename decorator/src/test/java/com/iluwatar/decorator/{SmartTrollTest.java => SmartHostileTest.java} (85%) create mode 100644 reader-writer-lock/etc/reader-writer-lock.png create mode 100644 reader-writer-lock/etc/reader-writer-lock.ucls create mode 100644 reader-writer-lock/index.md create mode 100644 reader-writer-lock/pom.xml create mode 100644 reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java create mode 100644 reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java create mode 100644 reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java create mode 100644 reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java create mode 100644 reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/AppTest.java create mode 100644 reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/ReaderAndWriterTest.java create mode 100644 reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/ReaderTest.java create mode 100644 reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/StdOutTest.java create mode 100644 reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/WriterTest.java diff --git a/abstract-factory/index.md b/abstract-factory/index.md index f31ed2d01..485599b98 100644 --- a/abstract-factory/index.md +++ b/abstract-factory/index.md @@ -10,24 +10,27 @@ tags: - Difficulty-Intermediate --- -**Also known as:** Kit +## Also known as +Kit -**Intent:** Provide an interface for creating families of related or dependent +## Intent +Provide an interface for creating families of related or dependent objects without specifying their concrete classes.  -**Applicability:** Use the Abstract Factory pattern when +## 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 -**Real world examples:** +## Real world examples * [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/adapter/index.md b/adapter/index.md index f77018e45..4263eb322 100644 --- a/adapter/index.md +++ b/adapter/index.md @@ -10,24 +10,27 @@ tags: - Difficulty-Beginner --- -**Also known as:** Wrapper +## Also known as +Wrapper -**Intent:** Convert the interface of a class into another interface the clients +## Intent +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.  -**Applicability:** Use the Adapter pattern when +## Applicability +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. -**Real world examples:** +## Real world examples * [java.util.Arrays#asList()](http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/async-method-invocation/index.md b/async-method-invocation/index.md index b9fadb886..93c0249d9 100644 --- a/async-method-invocation/index.md +++ b/async-method-invocation/index.md @@ -10,21 +10,23 @@ tags: - Functional --- -**Intent:** Asynchronous method invocation is pattern where the calling thread +## Intent +Asynchronous method invocation is pattern where the calling thread is not blocked while waiting results of tasks. The pattern provides parallel processing of multiple independent tasks and retrieving the results via callbacks or waiting until everything is done.  -**Applicability:** Use async method invocation pattern when +## Applicability +Use async method invocation pattern when * you have multiple independent tasks that can run in parallel * you need to improve the performance of a group of sequential tasks * you have limited amount of processing capacity or long running tasks and the caller should not wait the tasks to be ready -**Real world examples:** +## Real world examples * [FutureTask](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/FutureTask.html), [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html) and [ExecutorService](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html) (Java) * [Task-based Asynchronous Pattern](https://msdn.microsoft.com/en-us/library/hh873175.aspx) (.NET) diff --git a/bridge/index.md b/bridge/index.md index 008325ce5..49dad14e4 100644 --- a/bridge/index.md +++ b/bridge/index.md @@ -10,15 +10,17 @@ tags: - Difficulty-Intermediate --- -**Also known as:** Handle/Body +## Also known as +Handle/Body -**Intent:** Decouple an abstraction from its implementation so that the two can +## Intent +Decouple an abstraction from its implementation so that the two can vary independently. -  -**Applicability:** Use the Bridge pattern when +## Applicability +Use the Bridge pattern when * you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time. * both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently @@ -26,6 +28,6 @@ vary independently. * you have a proliferation of classes. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" to refer to such class hierarchies * you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class, in which multiple objects can share the same string representation. -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/builder/index.md b/builder/index.md index 8f299d116..05056e7c9 100644 --- a/builder/index.md +++ b/builder/index.md @@ -10,22 +10,24 @@ tags: - Difficulty-Intermediate --- -**Intent:** Separate the construction of a complex object from its +## Intent +Separate the construction of a complex object from its representation so that the same construction process can create different representations.  -**Applicability:** Use the Builder pattern when +## Applicability +Use the Builder pattern when * the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled * the construction process must allow different representations for the object that's constructed -**Real world examples:** +## Real world examples * [java.lang.StringBuilder](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html) * [Apache Camel builders](https://github.com/apache/camel/tree/0e195428ee04531be27a0b659005e3aa8d159d23/camel-core/src/main/java/org/apache/camel/builder) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/business-delegate/index.md b/business-delegate/index.md index 0b28a5a2f..7d548da11 100644 --- a/business-delegate/index.md +++ b/business-delegate/index.md @@ -9,14 +9,16 @@ tags: - Difficulty-Intermediate --- -**Intent:** The Business Delegate pattern adds an abstraction layer between +## Intent +The Business Delegate pattern adds an abstraction layer between presentation and business tiers. By using the pattern we gain loose coupling between the tiers and encapsulate knowledge about how to locate, connect to, and interact with the business objects that make up the application.  -**Applicability:** Use the Business Delegate pattern when +## Applicability +Use the Business Delegate pattern when * you want loose coupling between presentation and business tiers * you want to orchestrate calls to multiple business services diff --git a/caching/index.md b/caching/index.md index d15fbb7d9..2b89d0559 100644 --- a/caching/index.md +++ b/caching/index.md @@ -10,17 +10,19 @@ tags: - Performance --- -**Intent:** To avoid expensive re-acquisition of resources by not releasing +## Intent +To avoid expensive re-acquisition of resources by not releasing the resources immediately after their use. The resources retain their identity, are kept in some fast-access storage, and are re-used to avoid having to acquire them again.  -**Applicability:** Use the Caching pattern(s) when +## Applicability +Use the Caching pattern(s) when * Repetitious acquisition, initialization, and release of the same resource causes unnecessary performance overhead. -**Credits** +## Credits * [Write-through, write-around, write-back: Cache explained](http://www.computerweekly.com/feature/Write-through-write-around-write-back-Cache-explained) * [Read-Through, Write-Through, Write-Behind, and Refresh-Ahead Caching](https://docs.oracle.com/cd/E15357_01/coh.360/e15723/cache_rtwtwbra.htm#COHDG5177) diff --git a/callback/index.md b/callback/index.md index a70da1ff4..be73dc78f 100644 --- a/callback/index.md +++ b/callback/index.md @@ -11,16 +11,18 @@ tags: - Idiom --- -**Intent:** Callback is a piece of executable code that is passed as an +## Intent +Callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time.  -**Applicability:** Use the Callback pattern when +## Applicability +Use the Callback pattern when * when some arbitrary synchronous or asynchronous action must be performed after execution of some defined activity. -**Real world examples:** +## Real world examples * [CyclicBarrier] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html#CyclicBarrier%28int,%20java.lang.Runnable%29) constructor can accept callback that will be triggered every time when barrier is tripped. diff --git a/chain/index.md b/chain/index.md index 5432b51b6..ef18f6f64 100644 --- a/chain/index.md +++ b/chain/index.md @@ -10,23 +10,25 @@ tags: - Difficulty-Intermediate --- -**Intent:** Avoid coupling the sender of a request to its receiver by giving +## Intent +Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.  -**Applicability:** Use Chain of Responsibility when +## Applicability +Use Chain of Responsibility when * more than one object may handle a request, and the handler isn't known a priori. The handler should be ascertained automatically * you want to issue a request to one of several objects without specifying the receiver explicitly * the set of objects that can handle a request should be specified dynamically -**Real world examples:** +## Real world examples * [java.util.logging.Logger#log()](http://docs.oracle.com/javase/8/docs/api/java/util/logging/Logger.html#log%28java.util.logging.Level,%20java.lang.String%29) * [Apache Commons Chain](https://commons.apache.org/proper/commons-chain/index.html) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/command/index.md b/command/index.md index 4052a8ae7..2b9311537 100644 --- a/command/index.md +++ b/command/index.md @@ -10,15 +10,18 @@ tags: - Difficulty-Intermediate --- -**Also known as:** Action, Transaction +## Also known as +Action, Transaction -**Intent:** Encapsulate a request as an object, thereby letting you +## Intent +Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.  -**Applicability:** Use the Command pattern when you want to +## Applicability +Use the Command pattern when you want to * parameterize objects by an action to perform. You can express such parameterization in a procedural language with a callback function, that is, a function that's registered somewhere to be called at a later point. Commands are an object-oriented replacement for callbacks. * specify, queue, and execute requests at different times. A Command object can have a lifetime independent of the original request. If the receiver of a request can be represented in an address space-independent way, then you can transfer a command object for the request to a different process and fulfill the request there @@ -26,16 +29,16 @@ support undoable operations. * support logging changes so that they can be reapplied in case of a system crash. By augmenting the Command interface with load and store operations, you can keep a persistent log of changes. Recovering from a crash involves reloading logged commands from disk and re-executing them with the execute operation * structure a system around high-level operations build on primitive operations. Such a structure is common in information systems that support transactions. A transaction encapsulates a set of changes to data. The Command pattern offers a way to model transactions. Commands have a common interface, letting you invoke all transactions the same way. The pattern also makes it easy to extend the system with new transactions -**Typical Use Case:** +## Typical Use Case * to keep a history of requests * implement callback functionality * implement the undo functionality -**Real world examples:** +## Real world examples * [java.lang.Runnable](http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/composite/index.md b/composite/index.md index bf5a920ac..8b980292d 100644 --- a/composite/index.md +++ b/composite/index.md @@ -10,22 +10,24 @@ tags: - Difficulty-Intermediate --- -**Intent:** Compose objects into tree structures to represent part-whole +## Intent +Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.  -**Applicability:** Use the Composite pattern when +## Applicability +Use the Composite pattern when * you want to represent part-whole hierarchies of objects * you want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly -**Real world examples:** +## Real world examples * [java.awt.Container](http://docs.oracle.com/javase/8/docs/api/java/awt/Container.html) and [java.awt.Component](http://docs.oracle.com/javase/8/docs/api/java/awt/Component.html) * [Apache Wicket](https://github.com/apache/wicket) component tree, see [Component](https://github.com/apache/wicket/blob/91e154702ab1ff3481ef6cbb04c6044814b7e130/wicket-core/src/main/java/org/apache/wicket/Component.java) and [MarkupContainer](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/dao/index.md b/dao/index.md index 91f6dc776..785a1c362 100644 --- a/dao/index.md +++ b/dao/index.md @@ -9,16 +9,18 @@ tags: - Difficulty-Beginner --- -**Intent:** Object provides an abstract interface to some type of database or +## Intent +Object provides an abstract interface to some type of database or other persistence mechanism.  -**Applicability:** Use the Data Access Object in any of the following situations +## Applicability +Use the Data Access Object in any of the following situations * when you want to consolidate how the data layer is accessed * when you want to avoid writing multiple data retrieval/persistence layers -**Credits:** +## Credits * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) diff --git a/decorator/etc/decorator.png b/decorator/etc/decorator.png index 1e4bfdac2b201b9d0a7277f4ebc531102a411327..47a87b20b33dd4964ad94d7309bd63eb7b828d70 100644 GIT binary patch literal 29945 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 literal 8109 zcmaiZXIN9)wl+=apa>!;Mg&2m+2}$5QBb5vFVaLnsY)>-Wg&=&C`F|RYUsW99;72+ zB3-43^cqS+30aw6+}nNcbM8I&d_VGMWzM<An4`S!cvrZ-t|mJRKMM^F4f{1M4Feh) zT4U;un~9G4gxmRiF%1pE`<jND(WCb(R&FnkwY@to_TuSD!4>4rp-CmdR<zLJ(Kdw- z3?`n8AqSnh86)jV%)LY&JQo_WV@py#<|lCIsCscrxRuh4V!<ZQrh;<^Tp70JpBJlz z-w8gc5Juy1a<w{Qb^1O;_FDZ=xUiZVm`AeD%&Mzh@+I6Iw6wAs>nExZ2aP>sYH4Vy zUtImhNkgN0FNi|hWc5-XXvbR*(d5%Qbj)w?$LR}p#+_A%`#;o<p;Wc!9W)h!PMKZ# z#+3}2GQlCiI84M-ikjN|#1(are1d>KnF8q-H<E1LyUVsK?Pe{c$tX1+<w;oDM;~X) zlL7{oU&=Kza8@M+wwqoWX5BCG>5PdkXc!(_OlQI>TyV5x|41p_x*aHYGS698I+GJC z_SYf{?c!UYVSD_5w4zS+d%gxbOXmWy-RUH4VGf9xng6Qh=0*L-T5h%&<1Y6*ELfp` zHW>qWBEQ$PKtSVsNKbQAzu&O8gz-V{0@KV5d5K}2D;}e-%xsYd-F_x-Dc>sOWitz| zh_lV0=(y#!R>rBQ10U(i_;7=F9EmF}-{rq~StT*KNIleflF4oGjPq}w3Qn2jfYr5( zMn#LG-h+>8wAwI`Le!xy;>7}$fRm}^TNc4~x-RrHhS|W5IU8JPh`77|QOBpX8%R%3 z-ET3p`n+DQJ$&>^?{TE?!d2!>A;wg|seKyDB{7V#C1-mi$Td9t(0OyA;-SUsu}4!< zun1Z#vei1+u6lb=wEPI(!tG?K7{kHxCr3coskhF|u{emU<*N~qwIIyV&*VJ+`IuJu z%+`uB6}Iqn1X1!u1r8}8=%k$;O8La?tqyEi)PWQiiE&>F#LN7Dg!2Fi6@x>bHoFF6 z_QrF3^jvEuzlLKdles*5L;dGM-%`$qYs}jmcxI#w<NarDelF0_n+TX_etSZ|regCd z%WylMp)4;%!CJ^k9u5)gKgM}3MaIlvsMF<_C;{CT?TYQKmq?)_W!2YscKBQ<a`jti z;2kFwdu>eF^i5pOIzF-fIZ_+nkjP70x}#~ufNLPv+^)1_`>(y99>Rt{Ua~CXB}Y-e zLgY>^V0Q6Epg-o`nfk%4q*DFXq{^|*fc+J&Cu?g`Tc$4(kX(*(!g*d7q_vB!K$VJ0 z%_L5a^CKxoYxC8F0NfQGX5$M^DN^8?wy}=m$z@<?AYl2`(xU&lg<6HNRk;I?6~0QJ zxWm`oU!RsIA75e7ebG30JoIvOe~imusTipo2ecB#qVvB{{i51tQ-^{VzY+D``@iNQ zuSFqrF0HeF!e3I_?af*}Iqqpo-xebs^8;L;$!GeJZ0Ep?GP}{qT6v{VZst)Ap-8w> zNsRKEYaS9l))ejf=Sagm*M;q(F~3w(SFn+WDjL~BK@Y$L*TT=-cT1Rhm$pGa6Kff- zkjKX9o0$^3Z1I-+vtBOc%@i_tn527vG8dsnak6@cHVX;C%y?ed@6S~j34`9%*lo$> zOa^d&6<O$epEy`&dJz2>H5uApl<x-3)i$^g+bRv-XeXL3`Wm)(I@ISwzRRL{ly4h) zUD)(&)k|-JDVoin*t<TD_H=W(4kLZK3dhTw1NI8BUjQOwcNRZR+9DH#I{Y$r&|jd+ z!hqq$Z{fYz-Xn(5-HwF-he$)8V_t#gF&C*t5bfIY_Z|LDJZcJ%GHci;EE9HrMj`fv zgE=QaTuTD=TTNFL^VoiTJ{dJ_!U9L!d>`1a+kaKR5q|D^Tmz5}r;Xx*C|-_^mrIr8 zHcJ_PP($JCJHfMU<F_JYgO(>0?AeSHn@YkKqy-?jsa+b_p87C26ZZngV{``2J6i!V zZlb-X0Lg{kmh92mb63k`&e1wfpB9dIzt>mkVu~Fvnaw&nd~8GuT1Zf5^UaI|`+nW% zr^Ii(wxCUwkKXS&P=nz2FuW(38G(l!&ZY@|OG@%JSC=775WjoKtzcYsLtHSVG|L6N zo7-Hb+Z?sCv>b;~c3M1xNO@suL;X{MOmLmnJc9cv#Y&jK`JW2cR+3P(T=#zBeQt`u zg%w?;M1+dQpYEn_4$r;Oi=2J@iQ2}Ae%*ag@p;i-M%o{_b)?<R>y(dwNn6$G_>L%& zr0jJV$ZE)1IgJO_-=#Fu!sgQH3ggaK9Utsrnw3tuN%zL@Pk%%oW7&$d`!)0Imh_Qg z1{cYcvoONsp~m*{+Ww8r^PT(G^IE@)t%tPO6P?mO6UTGe9<bg!rFTH9=!SI}pF|%M z$A~#T=HyK6hB&!Q%@*GXXV@-`2YE*9h~B6l)rDKQBubyA5{mBSJ=K$jFBJ{gymbz` zvb9$>U2DqnVtdJ0q=7B^%?zgyl1C|NO+45?7A-qdK{?faRRC(f5pS6WnFZ^_=_gZ! zBBo>KSUpeTZ{acgcn_q0m+8HkN)eA=SWlO&D*ER;C)PHFdXL&xomIJ9+wC@hl=#H2 zo$Uupd!{Onv3=eP{5F9-nxl8*nlL4Q%d|5?#g7>BmK3h{oP>xw`}Wk^uV5S9gIhX! zaX3TX8i57t)=n?C;e^<14@pXX>yEWe`sF0@ezwZIfM-v;SAHKaqFwAsMv4sEv+gx9 zYL_XG{le#=&rNDG2UI?#ue@zm!K>*tH1g|(a4K9vy^=(?b-jc~HL;|yQ)YLV2LXjM zGfjuY*e(1w=KiM?VeJDWBcbd~{Q3`HN)_2L^8~w6p~%XPo`{?;d9sBG`QHeB0=6IM zIAcrZJkYd*j&Mz;Fe=O9D5z*E4*bc&a(yr+EnvOw)DP{>O@KT(%Jxd1jlQJ$L2A%g zDj38G7;=TBMj#%B1r<-j`vzafQlTfsR=ZdW^kvLo(nuxhRA0CqnPrzIwljrssKEqr zWyAv8sA&0?`YS|dBXU=Gu9#jqt7|2lzn2_$CI@_Vz@6^NIazK5VoYqXKOQ7p>vKQQ z;`JzCvA28qX8;ZCB7N<82TJKf^wK_|uq~*Ok9#lGS&wQ8alR3Yy#=+|AM(Zxz9c1# z)pKCK&Lc<cGBsdrUB@ZU23s~KW}(jH5nf}zxFT>A3dF8ptE>Zn)1KaH8a>IhR<|`g zXH9v#%MIh8_26*E)CrW3Kv<it(#3@v9k$jHnFYh;d#d5Arw|qEq`4e1&SUabvB&$& zl9)TUZ_i{(4YRi2k2@R8_9EbBg;N)4V&i+%aF1T&eNqq>CP?oqP3RjJyRP<=hkc_m zETzROCe2`I%bVxS^(p+=9qZ3SE`9E9BIy3dq20Dg*Pcpc4>CqR0EK2=)!`qEV);-X zEA&B*q#*vE<H2a;?3XDe)Q6ElCnsK5`^l{67Asw2K<c_#qbv@pCDj}~^ljPSdP@}X zrcqYrTX03xTif32#)sYa*?l1f$Ap}kPEsq8&fStQ2R8nXdIhk0?h2ko9R-AVN=DPu zIgYYRp_Ewu1h<jb*Fj(Ax%!8LiKYi6MFQNM$57Mlk#>gsg%Drt0JLAbQ!eDTjnRsE zDMe1|(*0h_kL`Muvbm9-kPgTBpNTchEJmp%eHI4VuPHO1)#?N+MBuD^YlBRW!m2dn zrOR+pu{uf5fjR9@X!4<7!{3ukF9ptxt}81+B_BBEZ4PU$PH&$kdcGk@#|n(c<ygQS zfwyd1T)*vs%#F6U{6FHa|7aZ~g25lgIRO2I>uU7huGxUrx~NOSjU?O?vB>ht2Q4_) zq2pnP!V*`$-3=)|diD8H;FP8#_AI{tm2@T_h`MyAc?Zh1b5kOs`?x&6{FN&fDS&iy zxBk{)@f{fRo~?Nsijk?n66tb&EH{{$1W;`3_@3@UaQ=f6!x8pfIzi+4N9;fBhfy=T zpwNV3H9w*A-@N(X)^Ke;G?ia;>{848-1PVJSO#j%+}F;2OPQJ*;fP&I+dJ=S{||8u z2k6&c0dFs~xb_f(X|;=oxR%#JOX?N>9W8O|%X7%j&75MMcln$zDhxMh*Z0UiezqWe zuwSY;{GFE+QqN_y`A-l3WC4&O2$hmNm6^_s(zA_B!Y|_-9TI9QvrI)>3l-jc*@~0= z9{(4mFF0k?2J~LYkYhSY?Up~4&X#UT**QFt-mL$uF*li{{L$0psAa%!@=qno%RuxE zC*rU<@kQ3OVknAyYx(MhYv`pwJA4(VeZZIOs>*Z!5cff#N44O4=edkP&EA*ZAMF$i z99AMR?&-fW0)Hcy3v(q2oFlEpl)c#Pi4oHD3+O>55B0lm3rxkQ+<&X3Qy<*W`1c*; z6G7VMWZKTk*JF7xZ>|QkNbZ06(Qe?Ejny~;xwwROtIU#=ApRajEVQ!+$mp1_`><z+ z7AMZsIx^!hwy<)GDkx@fXU0M3ifuM}YImzXr3wlU{Abc!%ukA!1)r;HE#J`=>h^TL z*KIBkpBB%orN-~&7q0w4jC<yG6aHpdQn6s5YzLR|29KdR_3XuLz)&RJ?q<pOnYa@# zf49)I+w^4xb<^9s%qAoduJ~wDY5eoMPjnR-jrHvpRO>Iio9`>^ED)a+Z~qOKpDP$F zVQ}|4eBbR^dA<d2_5!ghufjm-O*qD9(7(+r8!}U0h_lTDh>uI_tOc*0s5z5QWt!h` zZ~PyB2NZTQS-+Ew-X>ktR_l)=eXld>HGLWS+Y)zX**y?0Ml>&fs#^2Bclw4%OM&Dz zk9`Wojyc0JxPSuP_6uNsB7tnClX-LDohzzj?7w#Y4%=3B`onlJ{R@j}FB@5emEK&d z_G$BP8_A)XRugBtLPoO`TQuIzAB5P=th9qDVRo_pZGU0_^z);Oj?5$Cnj~pSsL=n0 zBPuDnV@^W)ZAnl^%ERfPq=YpMVH32W`t4k8z3k*@jhDT>z0FSZJ_qpl#8X%1j0$Gf zrq)&ssRh@GM&)?#QHDX_fTXk4a3exHYm>%#CNr;%(&|5Y`J9uJt9rQdy%bHSrRpY` z)T(zyRq9#_1<T^R1<i=tsP%dv7ju9f5+?kLke1pLyVbh8Ifs3(V7O&SbMK}e?6Dnf z@9cZZ*h9Yp<G;Jn)zwvsV9<(qyof#nInzzY@{_>AgSDTZN)fc3LHrgEBZVNkY;foS ziLfwMhl+=}RUHTPfkGsi_MU2Qp!0nJ<;UgAjI`&|+)0SGPQ)TO@*W8_F7ePhAeqiG zEoK6LO$q}J$k};%o-ev)qAHf1<S?hSAsR%oi70czzTUaHY06*G2dxT0L5Gc+A1Z#J zy4Fcs(FdMirRan16YJ9Er40D=<5~llx#s&N&o#T~dJSK>e?gGI!Q_o1_WZ9Pb?&l^ zn`^Hj-&M-t0J)-^Lr!|ZwYs)}fq~A>xyxBJ8yW$GB7xnda#AxVhe7)LjN<$Iov<G> z9Kk|=R(Ifm6M9Do6YBx*t1MpkHRE&-T*$VW!CmR9BBdhwTq_dUuSNDbBx-nX_aTir zpT!_^60~kMKF?Y^eu#((9!2KR#Hr?i;!=XJpfEQ}HfkU~)~MjwTt?GRoVHe9rF6G7 z1K#YbQ*%Rl*5YO4MppW}(P;B!?*YUjMks6#%wf@4sE8=CPw1CYo{SxEw<3M;t!!qx zJ={B;_Zpu;wm-Jpoehl{D_7qFXeCr6iG2GtLLW&WB4nE^1&nh`RU8O(#8i`~vk_t^ z&zzDepiJR2MqA|Pq($L6=EXJp_n56C`IO;yf?Ymv@a?u|StmlvhQ4N{cf!X9*%pDC zV4{&(kEI`59~edvFB>P3zy|K4w{^doR<&t5Kq@HIpzzi$oLy%r!wz!1_sc+3N+7Ro zu`6cZxNDWq6fn4w7)Z7e7~j-Gkq<>s9_Dpz8=!NMLOMS*dnquMNP^tmIS{*JYC6uc zn>{wYs8-zw6jE4z6lA^T4pjP}u0zm!HJG6tKl_@SIXUKO{i*|JHt}f`nIlz%Br0Lk zcqx8;F+4nc=Rr}LW|VAF@1%#(S*^*;nc8M6xkQ*FRfU9gS(oNHY4o;L!>sP%3Ykn^ zlRI<7Z+kUk`?BI3{i$@Qh31UD*MKHqaE_Zh@9aiSp5Lp@8}&c(*p_s2pgHQIweAPS z&?tYYG!s(RbqU_N&2ze~v$M0ZZr?AGC0U-49kteOtKi>VaQa!*|6t%cP?O|+$|n23 zD&MF7W9rt0!FTj3HrJAQJ$Gl~yOlw5P)h=ODm#`^m%n)Y(PHGoi!o<zaP=ienedly zrVZtrhr}WE<zUTOI`({!93x>*O;pdiTdg-Don@2ml9eKB7chAyDEcKd!v$H{!!f<5 z-?K*X&vt!nn9v&I>)G_-llclVb&`S)`uR%X&KhnD9iq+M`G$O8F;L?*cbZOwtPqhn zkA6J6(Sfm5TsupOy1|hB%L!<Nb*B3}pBV5^6pH4O`3eoATSa=5qgSJ~w}ZoJjLFLg z!`*()luULRr+G$Q9i0>k>M)VI3}qrCCpS!-qhrqjKV8&$kb5p++teGo0`s5go|oPa zf-Dwnf}UP?vp6U4NDGb#r@8$;-vSK_m8C3%Esr-O1+u~ia(7Ga@t)AX45Jzr+~p?x zH&4aiI$yuUv8d_#qq4vg4PV)$4udLcN{Hub%ESqxY+f~?PdjWFxiA;ZDwRFt1m%*Y z>y}H!i|RL0Bc#-+>pn3NG2ROf;j9Z!n*Zvp`_H^MxQO|h=QlwsY1eX1`kCsbzobF> zV>pcXQwlA|`~;6WpkXB7SyG^&w8THsph@P?w%qu8YYEFW95R||9w}Dgx}E4I6Ia38 zZK_1zOn+ibLN2e=$DACsfai#|A07m-Hgj{p^z@&&VC>@pM{6(sW`}n%!gS@1#`{S7 zG=(Ftm5-~{HQdl}t>p9*r1%Kz#xPN=PV0KrXRMmJ*5`<*StZ)tFiA{kPJvD+eI9}) z5-V7S<CqS@+AAv`$LGzQB?xb?Rh)`Clm_W-!3lOL2PE}t@e&5-1aoiWbJrr<8JCvc zw+&<{-0xz7>CN?XDLMr+ttRCv>NcLrJibIp0YY2PuLL3<ZG3c}KyLt?UT%8NBiF6L zrT=0^wCphwqe03d5!09I&JeuZ^>WeJJkI%88s*)<tL@kBS&}D4bbJQu1a+=VW`id; zQ(WP!D$g|eki6#4#eeC922Dqt^kEmJ>4oDGHI%s-IudANvJ0o|o9X~9U%bp>_BRkH zVW^t!-p3m;@_YoutyB)F)>|2vd+9)$&gb53GU7CY$pSKb@_Fs~6QVd*?DaNAG0Ahf zitt{1**au}MqBYT+-u$eOmiHnfJQTez{#ODkN6oxu@WS3-v68P$p5F{QV9yNOK*1T zJ$bb?ri&=;Rs)|>%#7{}bz=S<dleG2QDXCExyntY64hZD?0rL!yRdzrSLV34LBW$> zhd-$|9W#7Jd2;FIA^1%vzJ9^x__uWr>@oR<wH}XsRBh$-ElIko89-P3ye5@?xoQd! zz~npdt=N<DY2l04%Jwv){ALo!j7GRE;mluLxK1s1rfzBu`rTxN4Uy1~*)-(chHL)6 zL@`__Xs`FmLG{tyvEd(n6TRu+$^@%^b)=U5)?!O0$*&}|<Dfk(os};xoeU+*52%4{ zSNV+sOY3^SvEbzDy(Q^@6BKxBCqm;z+M*4sZ`((f$tLky6Ps-15Q^{Tp3BSxPVO+p zc@Sy5S!D&?9eW|_QM1aNTD{lYk2weob_#|CMvFJTm6M{XkFU!hY6<=MO@oC8?~r(} zg~s!Km!WF$k&5%^#jWsIY+>DGmt_)T_^(w~Y`tEGI;bj;Z(W4E_H3Tt@;r3r%*t~m z+_TqOim-S9<3}dyi(gT9lD1Hk7B5u(W5?SwhD(5Q?ZLLtCMLt4MbQ10G8k}OW42|2 zQNFw<2$ScsDXjea{(d9iM1Y0aqT}^`a5HDtcr@bY$`rz|GcH`nTef8f(+C&kWL&8^ zF(8f*EeG19!!$7cF&`Xq{bw4+qUzT|jz>KS2aDcuZ(M16m4{9%Gnk%Uho*MWnRJ|& zI7qa79f0MB7#oRE-Z>Sz$&inkTqrndGhVy?92+mD!2_LvQT>774cAToH*EpH@I??^ z6*Dz}k)(OdQZIm9w|^vc0H514WdszsoOKo;NQ}4j#o>^1|Etr`|3wd*XyH2b|0{=M z2Qd%(zZ`ob@H7*S(A;cEfo$&@nSkBXhe?d@uf~w(>TWR#Zdi|Xe_vU@|0_UKap?02 z_wCh|#r7YR05P3&>ngQJtMFZ#&=Bjr$f`tkA9geluQzl}x^LB!Aa|hV3i*(THMM1x zoW22Ga|i7DSTyF+tFi3GeQ*oy$W_bggFN`6szc4NLdTmph1WYH{6l6GKhY{JDI26e zGYt$aKPF%AF%hd;E0;WalEQpQI*js!fja}z$&)F!@4_{ZklwjM!*BfCtV<~kB>mI9 zE+&NZ)1uvotAS@8%1)Xxu*CmS!)BF#t6`Tx(Efdk$kHL>k^$8>zDpQsuHQ=7&FXS~ z)3m;wvie(_RW#45j}T(t&9WC;9zhF^&ESv+LTZPB`kR#nNBzxhOWJ_g>uK~c8o#h2 zL*T~KkOA<Q26lwSfdB%I$`AnKAcnhRX=U&HTJ4NKcTg;EZs0F$F45}-K%Os;p-NyG z30r(zQdC!j%@inzG%(_fy#Kx5Rj;brlf*Tsu*)2_+D79CEuVcnG_n=R2jU|NsOoDD z`s}*rJmR?~5d%UNsQvff!ppw~{YZ+=%U4z-|9r~IKCKVxn)fe4L4S`9|06eS$ygq$ z;Pq1##<LvF2DJPC1-Sn8<UcL3Iun{YtPJbW9uCdIJ>eSO8^8ULH3e$oH@Xf)CK43p zZN3=^4J+3tLrvCiGeLpoc0k}PN&I+Ha!4N$;d*Gme!hg4#ONI9Nr0xX_!@Y3C=U-@ zL05pcDsWESRRTm+H&0*Ddf6ZEq`4F%ga+=$=v0#eKM5((g}zu(8gU#C46tdU^N)~P z@U@u2A#EkE<3QYSV7+7DMrc2y|7sQ_hBI^9DsLUdYi@Vh##AIZF)XsDt!FZL2xS-U z`4!NMtv6*=yW<aFpU4q7&0cU3K#f4}hYr-LVo4tMixerIuD3Gp$Eb)q`jT{MBOhL@ zMskG-_sX3G7rQ;U#^*Z4$8o5Axgl+of91EA$v|4Ael~JWwCY&R@RSKj8yMJL%p7>E zmkVTK{9ee+qnni`E9(<q2QN(&ZNVRdJ;O(Z*5o*zP@bGgW`I3zJ^GmlSK)mF9I++u z7^8Y|pJcoaad)<QjFYpvqs*rhNSL(G230eTM&LH%WF#g`bP-BEeA<bOcUkEbKaTNQ z-TC+dGos5#@VFQ`AhIpn#LgfRVN#Z7dPLzn;N0SkC9RN@H`ykbG6ERt<^g?$>b(iD zs<IKiL(yccWujz0R_^Mpj4i;w>~Nk=UxywTLpHYNYp!G@+whjW_X-opuR27<L$epx zdjTJx<}N&O_%D7VEnm9}RZ?+DJ{hRAaQgY=lT#p7*8hJNjpRWdB52iiAIfJ78lM-s zv))|pR)R%pIAoJu0ma9Q!f3*6IqCEg-P@)WTfbio(1cM(Y`T@1RPacFJr_9pvIkRn zmN*PFtl&=Zl}AxQ`<#~`-wKbQM^)-yuLQ<en)bLHphEb_BG5DhVR_!^`?hLTb%2d^ zRs8n?eR4tGtPB&?a91K|AtEr-<42C9x6iz7F9_NlGT!88pjI1oZvVQ3W?wi;?+a|o zPRqN&MGe}6e_PW_9rzca!;*sfg{~KBcs}2E>2CPP%-ef_`N@rUc7uss1^ShBBdh<s z$bQ)`FJ$h!YVQvEJO@6CNu-A7I#mbw`^1V(=uFcezviJMCS8A-uL>@gs9T35LqY$x z8eif>+S{e>^shbX`@>9G2AFAnN+m-y_jz$hn(7F^SY+K$vVW8NBK0#o&9y7K8ine% G!T%5UTm=aL diff --git a/decorator/etc/decorator.ucls b/decorator/etc/decorator.ucls index 7adb8c3a6..a5353d4ec 100644 --- a/decorator/etc/decorator.ucls +++ b/decorator/etc/decorator.ucls @@ -1,18 +1,18 @@ <?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-diagram version="1.1.9" 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.decorator.Hostile" project="decorator" file="/decorator/src/main/java/com/iluwatar/decorator/Hostile.java" binary="false" corner="BOTTOM_RIGHT"> - <position height="106" width="134" x="116" y="408"/> + <position height="-1" width="-1" x="554" y="188"/> <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="2" language="java" name="com.iluwatar.decorator.SmartTroll" project="decorator" - file="/decorator/src/main/java/com/iluwatar/decorator/SmartTroll.java" binary="false" corner="BOTTOM_RIGHT"> - <position height="124" width="134" x="116" y="244"/> + <class id="2" language="java" name="com.iluwatar.decorator.App" project="decorator" + file="/decorator/src/main/java/com/iluwatar/decorator/App.java" binary="false" corner="BOTTOM_RIGHT"> + <position height="-1" width="-1" x="117" y="202"/> <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"/> @@ -21,29 +21,46 @@ </class> <class id="3" language="java" name="com.iluwatar.decorator.Troll" project="decorator" file="/decorator/src/main/java/com/iluwatar/decorator/Troll.java" binary="false" corner="BOTTOM_RIGHT"> - <position height="124" width="134" x="290" y="244"/> + <position height="-1" width="-1" x="315" y="100"/> <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="4"> + <class id="4" language="java" name="com.iluwatar.decorator.SmartHostile" project="decorator" + file="/decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java" binary="false" corner="BOTTOM_RIGHT"> + <position height="-1" width="-1" x="318" y="315"/> + <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> + <dependency id="5"> <end type="SOURCE" refId="2"/> + <end type="TARGET" refId="4"/> + </dependency> + <realization id="6"> + <end type="SOURCE" refId="3"/> <end type="TARGET" refId="1"/> </realization> - <association id="5"> - <end type="SOURCE" refId="2" navigable="false"> - <attribute id="6" name="decorated"/> - <multiplicity id="7" minimum="0" maximum="1"/> + <association id="7"> + <end type="SOURCE" refId="4" navigable="false"> + <attribute id="8" name="decorated"/> + <multiplicity id="9" minimum="0" maximum="1"/> </end> <end type="TARGET" refId="1" navigable="true"/> <display labels="true" multiplicity="true"/> </association> - <realization id="8"> - <end type="SOURCE" refId="3"/> + <realization id="10"> + <end type="SOURCE" refId="4"/> <end type="TARGET" refId="1"/> </realization> + <dependency id="11"> + <end type="SOURCE" refId="2"/> + <end type="TARGET" refId="3"/> + </dependency> <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"/> diff --git a/decorator/etc/decorator_1.png b/decorator/etc/decorator_1.png deleted file mode 100644 index 5a7afe2d1a2ccdc7c23f748e35df829385a13ce8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24245 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 diff --git a/decorator/index.md b/decorator/index.md index ca6c7bb50..5494ca944 100644 --- a/decorator/index.md +++ b/decorator/index.md @@ -10,20 +10,23 @@ tags: - Difficulty-Beginner --- -**Also known as:** Wrapper +## Also known as +Wrapper -**Intent:** Attach additional responsibilities to an object dynamically. +## Intent +Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. - + -**Applicability:** Use Decorator +## Applicability +Use Decorator * to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects * for responsibilities that can be withdrawn * when extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/decorator/src/main/java/com/iluwatar/decorator/App.java b/decorator/src/main/java/com/iluwatar/decorator/App.java index d58d3b61a..242e72d11 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/App.java +++ b/decorator/src/main/java/com/iluwatar/decorator/App.java @@ -8,7 +8,7 @@ package com.iluwatar.decorator; * runtime. * <p> * In this example we show how the simple {@link Troll} first attacks and then flees the battle. - * Then we decorate the {@link Troll} with a {@link SmartTroll} and perform the attack again. You + * Then we decorate the {@link Troll} with a {@link SmartHostile} and perform the attack again. You * can see how the behavior changes after the decoration. * */ @@ -30,7 +30,7 @@ public class App { // change the behavior of the simple troll by adding a decorator System.out.println("\nA smart looking troll surprises you."); - Hostile smart = new SmartTroll(troll); + Hostile smart = new SmartHostile(troll); smart.attack(); smart.fleeBattle(); System.out.printf("Smart troll power %d.\n", smart.getAttackPower()); diff --git a/decorator/src/main/java/com/iluwatar/decorator/SmartTroll.java b/decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java similarity index 56% rename from decorator/src/main/java/com/iluwatar/decorator/SmartTroll.java rename to decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java index 93927237d..93f494688 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/SmartTroll.java +++ b/decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java @@ -1,34 +1,34 @@ package com.iluwatar.decorator; /** - * SmartTroll is a decorator for {@link Hostile} objects. The calls to the {@link Hostile} interface + * SmartHostile is a decorator for {@link Hostile} objects. The calls to the {@link Hostile} interface * are intercepted and decorated. Finally the calls are delegated to the decorated {@link Hostile} * object. * */ -public class SmartTroll implements Hostile { +public class SmartHostile implements Hostile { private Hostile decorated; - public SmartTroll(Hostile decorated) { + public SmartHostile(Hostile decorated) { this.decorated = decorated; } @Override public void attack() { - System.out.println("The troll throws a rock at you!"); + System.out.println("It throws a rock at you!"); decorated.attack(); } @Override public int getAttackPower() { - // decorated troll power + 20 because it is smart + // decorated hostile's power + 20 because it is smart return decorated.getAttackPower() + 20; } @Override public void fleeBattle() { - System.out.println("The troll calls for help!"); + System.out.println("It calls for help!"); decorated.fleeBattle(); } } diff --git a/decorator/src/test/java/com/iluwatar/decorator/SmartTrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java similarity index 85% rename from decorator/src/test/java/com/iluwatar/decorator/SmartTrollTest.java rename to decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java index faafc4a82..e5be32eae 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/SmartTrollTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java @@ -11,15 +11,15 @@ import static org.mockito.internal.verification.VerificationModeFactory.times; * * @author Jeroen Meulemeester */ -public class SmartTrollTest { +public class SmartHostileTest { @Test - public void testSmartTroll() throws Exception { + public void testSmartHostile() throws Exception { // Create a normal troll first, but make sure we can spy on it later on. final Hostile simpleTroll = spy(new Troll()); // Now we want to decorate the troll to make it smarter ... - final Hostile smartTroll = new SmartTroll(simpleTroll); + final Hostile smartTroll = new SmartHostile(simpleTroll); assertEquals(30, smartTroll.getAttackPower()); verify(simpleTroll, times(1)).getAttackPower(); diff --git a/delegation/index.md b/delegation/index.md index 2064a5bf7..e5c0c6376 100644 --- a/delegation/index.md +++ b/delegation/index.md @@ -9,19 +9,22 @@ tags: - Difficulty-Beginner --- -**Also known as:** Proxy Pattern +## Also known as +Proxy Pattern -**Intent:** It is a technique where an object expresses certain behavior to the outside but in +## Intent +It is a technique where an object expresses certain behavior to the outside but in reality delegates responsibility for implementing that behaviour to an associated object.  -**Applicability:** Use the Delegate pattern in order to achieve the following +## Applicability +Use the Delegate pattern in order to achieve the following * Reduce the coupling of methods to their class * Components that behave identically, but realize that this situation can change in the future. -**Credits** +## Credits * [Delegate Pattern: Wikipedia ](https://en.wikipedia.org/wiki/Delegation_pattern) -* [Proxy Pattern: Wikipedia ](https://en.wikipedia.org/wiki/Proxy_pattern) \ No newline at end of file +* [Proxy Pattern: Wikipedia ](https://en.wikipedia.org/wiki/Proxy_pattern) diff --git a/dependency-injection/index.md b/dependency-injection/index.md index 4caa30c94..735f589b1 100644 --- a/dependency-injection/index.md +++ b/dependency-injection/index.md @@ -9,7 +9,8 @@ tags: - Difficulty-Beginner --- -**Intent:** Dependency Injection is a software design pattern in which one or +## Intent +Dependency Injection is a software design pattern in which one or more dependencies (or services) are injected, or passed by reference, into a dependent object (or client) and are made part of the client's state. The pattern separates the creation of a client's dependencies from its own @@ -18,7 +19,8 @@ inversion of control and single responsibility principles.  -**Applicability:** Use the Dependency Injection pattern when +## Applicability +Use the Dependency Injection pattern when * when you need to remove knowledge of concrete implementation from object * to enable unit testing of classes in isolation using mock objects or stubs diff --git a/double-checked-locking/index.md b/double-checked-locking/index.md index 05ec2006f..da1fdd1a2 100644 --- a/double-checked-locking/index.md +++ b/double-checked-locking/index.md @@ -10,14 +10,16 @@ tags: - Idiom --- -**Intent:** Reduce the overhead of acquiring a lock by first testing the +## Intent +Reduce the overhead of acquiring a lock by first testing the locking criterion (the "lock hint") without actually acquiring the lock. Only if the locking criterion check indicates that locking is required does the actual locking logic proceed.  -**Applicability:** Use the Double Checked Locking pattern when +## Applicability +Use the Double Checked Locking pattern when * there is a concurrent access in object creation, e.g. singleton, where you want to create single instance of the same class and checking if it's null or not maybe not be enough when there are two or more threads that checks if instance is null or not. * there is a concurrent access on a method where method's behaviour changes according to the some constraints and these constraint change within this method. diff --git a/double-dispatch/index.md b/double-dispatch/index.md index a660e0f88..ae87208a2 100644 --- a/double-dispatch/index.md +++ b/double-dispatch/index.md @@ -10,15 +10,17 @@ tags: - Idiom --- -**Intent:** Double Dispatch pattern is a way to create maintainable dynamic +## Intent +Double Dispatch pattern is a way to create maintainable dynamic behavior based on receiver and parameter types.  -**Applicability:** Use the Double Dispatch pattern when +## Applicability +Use the Double Dispatch pattern when * the dynamic behavior is not defined only based on receiving object's type but also on the receiving method's parameter type. -**Real world examples:** +## Real world examples * [ObjectOutputStream](https://docs.oracle.com/javase/8/docs/api/java/io/ObjectOutputStream.html) diff --git a/event-aggregator/index.md b/event-aggregator/index.md index 05e94e0de..5462a2a5d 100644 --- a/event-aggregator/index.md +++ b/event-aggregator/index.md @@ -9,7 +9,8 @@ tags: - Difficulty-Beginner --- -**Intent:** A system with lots of objects can lead to complexities when a +## Intent +A system with lots of objects can lead to complexities when a client wants to subscribe to events. The client has to find and register for each object individually, if each object has multiple events then each event requires a separate subscription. An Event Aggregator acts as a single source @@ -18,7 +19,8 @@ allowing clients to register with just the aggregator.  -**Applicability:** Use the Event Aggregator pattern when +## Applicability +Use the Event Aggregator pattern when * Event Aggregator is a good choice when you have lots of objects that are potential event sources. Rather than have the observer deal with registering @@ -26,6 +28,6 @@ allowing clients to register with just the aggregator. Aggregator. As well as simplifying registration, a Event Aggregator also simplifies the memory management issues in using observers. -**Credits:** +## Credits * [Martin Fowler - Event Aggregator](http://martinfowler.com/eaaDev/EventAggregator.html) diff --git a/event-driven-architecture/index.md b/event-driven-architecture/index.md index 6c2ae99c6..7c786b76c 100644 --- a/event-driven-architecture/index.md +++ b/event-driven-architecture/index.md @@ -3,25 +3,26 @@ title: Event Driven Architecture folder: event-driven-architecture permalink: /patterns/event-driven-architecture - -**Intent:** Send and notify state changes of your objects to other applications using an Event-driven Architecture. +## Intent +Send and notify state changes of your objects to other applications using an Event-driven Architecture.  -**Applicability:** Use an Event-driven architecture when +## Applicability +Use an Event-driven architecture when * you want to create a loosely coupled system * you want to build a more responsive system * you want a system that is easier to extend -**Real world examples:** +## Real world examples * SendGrid, an email API, sends events whenever an email is processed, delivered, opened etc... (https://sendgrid.com/docs/API_Reference/Webhooks/event.html) * Chargify, a billing API, exposes payment activity through various events (https://docs.chargify.com/api-events) * Amazon's AWS Lambda, lets you execute code in response to events such as changes to Amazon S3 buckets, updates to an Amazon DynamoDB table, or custom events generated by your applications or devices. (https://aws.amazon.com/lambda) * MySQL runs triggers based on events such as inserts and update events happening on database tables. -**Credits:** +## Credits * [Event-driven architecture - Wikipedia](http://www.computerweekly.com/feature/Write-through-write-around-write-back-Cache-explained) * [Fundamental Components of an Event-Driven Architecture](http://giocc.com/fundamental-components-of-an-event-driven-architecture.html) diff --git a/execute-around/index.md b/execute-around/index.md index 8e62d5a8c..ec543bdc7 100644 --- a/execute-around/index.md +++ b/execute-around/index.md @@ -10,13 +10,15 @@ tags: - Idiom --- -**Intent:** Execute Around idiom frees the user from certain actions that +## Intent +Execute Around idiom frees the user from certain actions that should always be executed before and after the business method. A good example of this is resource allocation and deallocation leaving the user to specify only what to do with the resource.  -**Applicability:** Use the Execute Around idiom when +## Applicability +Use the Execute Around idiom when * you use an API that requires methods to be called in pairs such as open/close or allocate/deallocate. diff --git a/facade/index.md b/facade/index.md index 9ad9cb985..c416552c7 100644 --- a/facade/index.md +++ b/facade/index.md @@ -10,17 +10,19 @@ tags: - Difficulty-Beginner --- -**Intent:** Provide a unified interface to a set of interfaces in a subsystem. +## Intent +Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.  -**Applicability:** Use the Facade pattern when +## Applicability +Use the Facade pattern when * you want to provide a simple interface to a complex subsystem. Subsystems often get more complex as they evolve. Most patterns, when applied, result in more and smaller classes. This makes the subsystem more reusable and easier to customize, but it also becomes harder to use for clients that don't need to customize it. A facade can provide a simple default view of the subsystem that is good enough for most clients. Only clients needing more customizability will need to look beyond the facade. * there are many dependencies between clients and the implementation classes of an abstraction. Introduce a facade to decouple the subsystem from clients and other subsystems, thereby promoting subsystem independence and portability. * you want to layer your subsystems. Use a facade to define an entry point to each subsystem level. If subsystems are dependent, the you can simplify the dependencies between them by making them communicate with each other solely through their facades -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/factory-method/index.md b/factory-method/index.md index 3568a1109..42237883d 100644 --- a/factory-method/index.md +++ b/factory-method/index.md @@ -10,20 +10,23 @@ tags: - Gang Of Four --- -**Also known as:** Virtual Constructor +## Also known as +Virtual Constructor -**Intent:** Define an interface for creating an object, but let subclasses +## Intent +Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.  -**Applicability:** Use the Factory Method pattern when +## Applicability +Use the Factory Method pattern when * a class can't anticipate the class of objects it must create * a class wants its subclasses to specify the objects it creates * classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/fluentinterface/index.md b/fluentinterface/index.md index 0cabed598..767792da7 100644 --- a/fluentinterface/index.md +++ b/fluentinterface/index.md @@ -10,9 +10,10 @@ tags: - Functional --- -**Intent:** A fluent interface provides an easy-readable, flowing interface, that often mimics a domain specific language. Using this pattern results in code that can be read nearly as human language. +## Intent +A fluent interface provides an easy-readable, flowing interface, that often mimics a domain specific language. Using this pattern results in code that can be read nearly as human language. -**Implementation:** +## Implementation A fluent interface can be implemented using any of @@ -22,13 +23,13 @@ A fluent interface can be implemented using any of  - -**Applicability:** Use the Fluent Interface pattern when +## Applicability +Use the Fluent Interface pattern when * you provide an API that would benefit from a DSL-like usage * you have objects that are difficult to configure or use -**Real world examples:** +## Real world examples * [Java 8 Stream API](http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html) * [Google Guava FluentInterable](https://github.com/google/guava/wiki/FunctionalExplained) @@ -36,7 +37,7 @@ A fluent interface can be implemented using any of * [Mockito](http://mockito.org/) * [Java Hamcrest](http://code.google.com/p/hamcrest/wiki/Tutorial) -**Credits** +## Credits * [Fluent Interface - Martin Fowler](http://www.martinfowler.com/bliki/FluentInterface.html) * [Evolutionary architecture and emergent design: Fluent interfaces - Neal Ford](http://www.ibm.com/developerworks/library/j-eaed14/) diff --git a/flux/index.md b/flux/index.md index c1ef0b4f9..7ac312c44 100644 --- a/flux/index.md +++ b/flux/index.md @@ -9,17 +9,19 @@ tags: - Difficulty-Intermediate --- -**Intent:** Flux eschews MVC in favor of a unidirectional data flow. When a +## Intent +Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with a view, the view propagates an action through a central dispatcher, to the various stores that hold the application's data and business logic, which updates all of the views that are affected.  -**Applicability:** Use the Flux pattern when +## Applicability +Use the Flux pattern when * you want to focus on creating explicit and understandable update paths for your application's data, which makes tracing changes during development simpler and makes bugs easier to track down and fix. -**Credits:** +## Credits * [Flux - Application architecture for building user interfaces](http://facebook.github.io/flux/) diff --git a/flyweight/index.md b/flyweight/index.md index 41a45f555..a98dced8e 100644 --- a/flyweight/index.md +++ b/flyweight/index.md @@ -11,12 +11,14 @@ tags: - Performance --- -**Intent:** Use sharing to support large numbers of fine-grained objects +## Intent +Use sharing to support large numbers of fine-grained objects efficiently.  -**Applicability:** The Flyweight pattern's effectiveness depends heavily on how +## Applicability +The Flyweight pattern's effectiveness depends heavily on how and where it's used. Apply the Flyweight pattern when all of the following are true @@ -26,10 +28,10 @@ true * many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed * the application doesn't depend on object identity. Since flyweight objects may be shared, identity tests will return true for conceptually distinct objects. -**Real world examples:** +## Real world examples * [java.lang.Integer#valueOf(int)](http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#valueOf%28int%29) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/front-controller/index.md b/front-controller/index.md index 603bfef2b..a462a08e0 100644 --- a/front-controller/index.md +++ b/front-controller/index.md @@ -9,23 +9,25 @@ tags: - Difficulty-Intermediate --- -**Intent:** Introduce a common handler for all requests for a web site. This +## Intent +Introduce a common handler for all requests for a web site. This way we can encapsulate common functionality such as security, internationalization, routing and logging in a single place.  -**Applicability:** Use the Front Controller pattern when +## Applicability +Use the Front Controller pattern when * you want to encapsulate common request handling functionality in single place * you want to implements dynamic request handling i.e. change routing without modifying code * make web server configuration portable, you only need to register the handler web server specific way -**Real world examples:** +## Real world examples * [Apache Struts](https://struts.apache.org/) -**Credits:** +## Credits * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) * [Presentation Tier Patterns](http://www.javagyan.com/tutorials/corej2eepatterns/presentation-tier-patterns) diff --git a/half-sync-half-async/index.md b/half-sync-half-async/index.md index 5eb93c058..8a091f813 100644 --- a/half-sync-half-async/index.md +++ b/half-sync-half-async/index.md @@ -9,13 +9,15 @@ tags: - Difficulty-Intermediate --- -**Intent:** The Half-Sync/Half-Async pattern decouples synchronous I/O from +## Intent +The Half-Sync/Half-Async pattern decouples synchronous I/O from asynchronous I/O in a system to simplify concurrent programming effort without degrading execution efficiency.  -**Applicability:** Use Half-Sync/Half-Async pattern when +## Applicability +Use Half-Sync/Half-Async pattern when * a system possesses following characteristics: * the system must perform tasks in response to external events that occur asynchronously, like hardware interrupts in OS @@ -23,13 +25,13 @@ degrading execution efficiency. * the higher level tasks in the system can be simplified significantly if I/O is performed synchronously. * one or more tasks in a system must run in a single thread of control, while other tasks may benefit from multi-threading. -**Real world examples:** +## Real world examples * [BSD Unix networking subsystem](http://www.cs.wustl.edu/~schmidt/PDF/PLoP-95.pdf) * [Real Time CORBA](http://www.omg.org/news/meetings/workshops/presentations/realtime2001/4-3_Pyarali_thread-pool.pdf) * [Android AsyncTask framework](http://developer.android.com/reference/android/os/AsyncTask.html) -**Credits:** +## Credits * [Douglas C. Schmidt and Charles D. Cranor - Half Sync/Half Async](http://www.cs.wustl.edu/~schmidt/PDF/PLoP-95.pdf) * [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697) diff --git a/intercepting-filter/index.md b/intercepting-filter/index.md index 3aa70ba02..327f091b1 100644 --- a/intercepting-filter/index.md +++ b/intercepting-filter/index.md @@ -9,22 +9,24 @@ tags: - Difficulty-Intermediate --- -**Intent:** Provide pluggable filters to conduct necessary pre-processing and +## Intent +Provide pluggable filters to conduct necessary pre-processing and post-processing to requests from a client to a target  -**Applicability:** Use the Intercepting Filter pattern when +## Applicability +Use the Intercepting Filter pattern when * a system uses pre-processing or post-processing requests * a system should do the authentication/ authorization/ logging or tracking of request and then pass the requests to corresponding handlers * you want a modular approach to configuring pre-processing and post-processing schemes -**Real world examples:** +## Real world examples * [Struts 2 - Interceptors](https://struts.apache.org/docs/interceptors.html) -**Credits:** +## Credits * [TutorialsPoint - Intercepting Filter](http://www.tutorialspoint.com/design_pattern/intercepting_filter_pattern.htm) * [Presentation Tier Patterns](http://www.javagyan.com/tutorials/corej2eepatterns/presentation-tier-patterns) diff --git a/interpreter/index.md b/interpreter/index.md index dd6a7eda2..87c1c47f7 100644 --- a/interpreter/index.md +++ b/interpreter/index.md @@ -10,19 +10,21 @@ tags: - Difficulty-Intermediate --- -**Intent:** Given a language, define a representation for its grammar along +## Intent +Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.  -**Applicability:** Use the Interpreter pattern when there is a language to +## Applicability +Use the Interpreter pattern when there is a language to interpret, and you can represent statements in the language as abstract syntax trees. The Interpreter pattern works best when * the grammar is simple. For complex grammars, the class hierarchy for the grammar becomes large and unmanageable. Tools such as parser generators are a better alternative in such cases. They can interpret expressions without building abstract syntax trees, which can save space and possibly time * efficiency is not a critical concern. The most efficient interpreters are usually not implemented by interpreting parse trees directly but by first translating them into another form. For example, regular expressions are often transformed into state machines. But even then, the translator can be implemented by the Interpreter pattern, so the pattern is still applicable -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/iterator/index.md b/iterator/index.md index fe6c1fe35..d6be7758d 100644 --- a/iterator/index.md +++ b/iterator/index.md @@ -10,23 +10,26 @@ tags: - Gang Of Four --- -**Also known as:** Cursor +## Also known as +Cursor -**Intent:** Provide a way to access the elements of an aggregate object +## Intent +Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.  -**Applicability:** Use the Iterator pattern +## Applicability +Use the Iterator pattern * to access an aggregate object's contents without exposing its internal representation * to support multiple traversals of aggregate objects * to provide a uniform interface for traversing different aggregate structures -**Real world examples:** +## Real world examples * [java.util.Iterator](http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/layers/index.md b/layers/index.md index 5f746d4d2..8e8eda366 100644 --- a/layers/index.md +++ b/layers/index.md @@ -10,18 +10,19 @@ tags: - Spring --- -**Intent:** Layers is an architectural style where software responsibilities are +## Intent +Layers is an architectural style where software responsibilities are divided among the different layers of the application.  -**Applicability:** Use the Layers architecture when +## Applicability +Use the Layers architecture when * you want clearly divide software responsibilities into differents parts of the program * you want to prevent a change from propagating throughout the application * you want to make your application more maintainable and testable -**Credits:** +## Credits * [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697) - diff --git a/lazy-loading/index.md b/lazy-loading/index.md index 6f2501b7e..8a06700d3 100644 --- a/lazy-loading/index.md +++ b/lazy-loading/index.md @@ -11,17 +11,19 @@ tags: - Performance --- -**Intent:** Lazy loading is a design pattern commonly used to defer +## Intent +Lazy loading is a design pattern commonly used to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used.  -**Applicability:** Use the Lazy Loading idiom when +## Applicability +Use the Lazy Loading idiom when * eager loading is expensive or the object to be loaded might not be needed at all -**Real world examples:** +## Real world examples * JPA annotations @OneToOne, @OneToMany, @ManyToOne, @ManyToMany and fetch = FetchType.LAZY diff --git a/mediator/index.md b/mediator/index.md index cb4ce7fb1..c7a0478c8 100644 --- a/mediator/index.md +++ b/mediator/index.md @@ -10,18 +10,20 @@ tags: - Difficulty-Intermediate --- -**Intent:** Define an object that encapsulates how a set of objects interact. +## Intent +Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.  -**Applicability:** Use the Mediator pattern when +## Applicability +Use the Mediator pattern when * a set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructured and difficult to understand * reusing an object is difficult because it refers to and communicates with many other objects * a behavior that's distributed between several classes should be customizable without a lot of subclassing -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/memento/index.md b/memento/index.md index 7322aef50..463b5fec0 100644 --- a/memento/index.md +++ b/memento/index.md @@ -10,22 +10,25 @@ tags: - Difficulty-Intermediate --- -**Also known as:** Token +## Also known as +Token -**Intent:** Without violating encapsulation, capture and externalize an +## Intent +Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.  -**Applicability:** Use the Memento pattern when +## Applicability +Use the Memento pattern when * a snapshot of an object's state must be saved so that it can be restored to that state later, and * a direct interface to obtaining the state would expose implementation details and break the object's encapsulation -**Real world examples:** +## Real world examples * [java.util.Date](http://docs.oracle.com/javase/8/docs/api/java/util/Date.html) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/message-channel/index.md b/message-channel/index.md index 3b742a983..8aebd0157 100644 --- a/message-channel/index.md +++ b/message-channel/index.md @@ -7,18 +7,20 @@ categories: Integration tags: - Java - EIP - - Camel + - Apache Camelâ„¢ --- -**Intent:** When two applications communicate using a messaging system they do it by using logical addresses +## Intent +When two applications communicate using a messaging system they do it by using logical addresses of the system, so called Message Channels.  -**Applicability:** Use the Message Channel pattern when +## Applicability +Use the Message Channel pattern when * two or more applications need to communicate using a messaging system -**Real world examples:** +## Real world examples -* [akka-camel](http://doc.akka.io/docs/akka/snapshot/scala/camel.html) +* [akka-camel](http://doc.akka.io/docs/akka/snapshot/scala/camel.html) \ No newline at end of file diff --git a/model-view-controller/index.md b/model-view-controller/index.md index 3d1d3e929..bc96f7ab1 100644 --- a/model-view-controller/index.md +++ b/model-view-controller/index.md @@ -9,18 +9,20 @@ tags: - Difficulty-Intermediate --- -**Intent:** Separate the user interface into three interconnected components: +## Intent +Separate the user interface into three interconnected components: the model, the view and the controller. Let the model manage the data, the view display the data and the controller mediate updating the data and redrawing the display.  -**Applicability:** Use the Model-View-Controller pattern when +## Applicability +Use the Model-View-Controller pattern when * you want to clearly separate the domain data from its user interface representation -**Credits:** +## Credits * [Trygve Reenskaug - Model-view-controller](http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) diff --git a/model-view-presenter/index.md b/model-view-presenter/index.md index a65a9a651..a3b921ce4 100644 --- a/model-view-presenter/index.md +++ b/model-view-presenter/index.md @@ -9,17 +9,19 @@ tags: - Difficulty-Intermediate --- -**Intent:** Apply a "Separation of Concerns" principle in a way that allows +## Intent +Apply a "Separation of Concerns" principle in a way that allows developers to build and test user interfaces.  -**Applicability:** Use the Model-View-Presenter in any of the following +## Applicability +Use the Model-View-Presenter in any of the following situations * when you want to improve the "Separation of Concerns" principle in presentation logic * when a user interface development and testing is necessary. -**Real world examples:** +## Real world examples * [MVP4J](https://github.com/amineoualialami/mvp4j) diff --git a/monostate/index.md b/monostate/index.md index 4176af3ce..415d13f0e 100644 --- a/monostate/index.md +++ b/monostate/index.md @@ -9,22 +9,24 @@ tags: - Difficulty-Beginner --- -**Intent:** Enforces a behaviour like sharing the same state amongst all instances. +## Intent +Enforces a behaviour like sharing the same state amongst all instances.  -**Applicability:** Use the Monostate pattern when +## Applicability +Use the Monostate pattern when * The same state must be shared across all instances of a class. * Typically this pattern might be used everywhere a Singleton might be used. Singleton usage however is not transparent, Monostate usage is. * Monostate has one major advantage over singleton. The subclasses might decorate the shared state as they wish and hence can provide dynamically different behaviour than the base class. -**Typical Use Case:** +## Typical Use Case * the logging class * managing a connection to a database * file manager -**Real world examples:** +## Real world examples Yet to see this. diff --git a/multiton/index.md b/multiton/index.md index 6491de442..68fb6bbc6 100644 --- a/multiton/index.md +++ b/multiton/index.md @@ -9,11 +9,13 @@ tags: - Difficulty-Beginner --- -**Intent:** Ensure a class only has limited number of instances, and provide a +## Intent +Ensure a class only has limited number of instances, and provide a global point of access to them.  -**Applicability:** Use the Multiton pattern when +## Applicability +Use the Multiton pattern when * there must be specific number of instances of a class, and they must be accessible to clients from a well-known access point diff --git a/naked-objects/index.md b/naked-objects/index.md index e3dd09a81..eb1c083b1 100644 --- a/naked-objects/index.md +++ b/naked-objects/index.md @@ -9,22 +9,24 @@ tags: - Difficulty-Expert --- -**Intent:** The Naked Objects architectural pattern is well suited for rapid +## Intent +The Naked Objects architectural pattern is well suited for rapid prototyping. Using the pattern, you only need to write the domain objects, everything else is autogenerated by the framework.  -**Applicability:** Use the Naked Objects pattern when +## Applicability +Use the Naked Objects pattern when * you are prototyping and need fast development cycle * an autogenerated user interface is good enough * you want to automatically publish the domain as REST services -**Real world examples:** +## Real world examples * [Apache Isis](https://isis.apache.org/) -**Credits:** +## Credits * [Richard Pawson - Naked Objects](http://downloads.nakedobjects.net/resources/Pawson%20thesis.pdf) diff --git a/null-object/index.md b/null-object/index.md index 6b659b5cc..b5fb279db 100644 --- a/null-object/index.md +++ b/null-object/index.md @@ -9,7 +9,8 @@ tags: - Difficulty-Beginner --- -**Intent:** In most object-oriented languages, such as Java or C#, references +## Intent +In most object-oriented languages, such as Java or C#, references may be null. These references need to be checked to ensure they are not null before invoking any methods, because methods typically cannot be invoked on null references. Instead of using a null reference to convey absence of an @@ -20,6 +21,7 @@ Object is very predictable and has no side effects: it does nothing.  -**Applicability:** Use the Null Object pattern when +## Applicability +Use the Null Object pattern when * you want to avoid explicit null checks and keep the algorithm elegant and easy to read. diff --git a/object-pool/index.md b/object-pool/index.md index 0d37041c3..cf36d9880 100644 --- a/object-pool/index.md +++ b/object-pool/index.md @@ -10,14 +10,16 @@ tags: - Performance --- -**Intent:** When objects are expensive to create and they are needed only for +## Intent +When objects are expensive to create and they are needed only for short periods of time it is advantageous to utilize the Object Pool pattern. The Object Pool provides a cache for instantiated objects tracking which ones are in use and which are available.  -**Applicability:** Use the Object Pool pattern when +## Applicability +Use the Object Pool pattern when * the objects are expensive to create (allocation cost) * you need a large number of short-lived objects (memory fragmentation) diff --git a/observer/index.md b/observer/index.md index ea1667ef5..7e83e899d 100644 --- a/observer/index.md +++ b/observer/index.md @@ -10,28 +10,31 @@ tags: - Gang Of Four --- -**Also known as:** Dependents, Publish-Subscribe +## Also known as +Dependents, Publish-Subscribe -**Intent:** Define a one-to-many dependency between objects so that when one +## Intent +Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.  -**Applicability:** Use the Observer pattern in any of the following situations +## Applicability +Use the Observer pattern in any of the following situations * when an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently * when a change to one object requires changing others, and you don't know how many objects need to be changed * when an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don't want these objects tightly coupled -**Typical Use Case:** +## Typical Use Case * changing in one object leads to a change in other objects -**Real world examples:** +## Real world examples * [java.util.Observer](http://docs.oracle.com/javase/8/docs/api/java/util/Observer.html) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/poison-pill/index.md b/poison-pill/index.md index 90dff3c36..eb37c5ada 100644 --- a/poison-pill/index.md +++ b/poison-pill/index.md @@ -9,15 +9,17 @@ tags: - Difficulty-Intermediate --- -**Intent:** Poison Pill is known predefined data item that allows to provide +## Intent +Poison Pill is known predefined data item that allows to provide graceful shutdown for separate distributed consumption process.  -**Applicability:** Use the Poison Pill idiom when +## Applicability +Use the Poison Pill idiom when * need to send signal from one thread/process to another to terminate -**Real world examples:** +## Real world examples * [akka.actor.PoisonPill](http://doc.akka.io/docs/akka/2.1.4/java/untyped-actors.html) diff --git a/pom.xml b/pom.xml index 68208288d..772ef721c 100644 --- a/pom.xml +++ b/pom.xml @@ -11,18 +11,19 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <hibernate.version>5.0.1.Final</hibernate.version> - <spring.version>4.1.7.RELEASE</spring.version> - <spring-data.version>1.9.0.RELEASE</spring-data.version> - <h2.version>1.4.188</h2.version> + <spring.version>4.2.4.RELEASE</spring.version> + <spring-data.version>1.9.2.RELEASE</spring-data.version> + <h2.version>1.4.190</h2.version> <junit.version>4.12</junit.version> <compiler.version>3.0</compiler.version> <coveralls.version>4.0.0</coveralls.version> <jacoco.version>0.7.2.201409121644</jacoco.version> <commons-dbcp.version>1.4</commons-dbcp.version> - <camel.version>2.15.3</camel.version> + <camel.version>2.16.1</camel.version> <log4j.version>1.2.17</log4j.version> - <guava.version>18.0</guava.version> - <systemrules.version>1.14.0</systemrules.version> + <guava.version>19.0</guava.version> + <systemrules.version>1.15.1</systemrules.version> + <mockito.version>1.10.19</mockito.version> </properties> <modules> <module>abstract-factory</module> @@ -61,6 +62,7 @@ <module>intercepting-filter</module> <module>producer-consumer</module> <module>poison-pill</module> + <module>reader-writer-lock</module> <module>lazy-loading</module> <module>service-layer</module> <module>specification</module> @@ -145,7 +147,7 @@ <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>1.10.19</version> + <version>${mockito.version}</version> <scope>test</scope> </dependency> <dependency> diff --git a/private-class-data/index.md b/private-class-data/index.md index 4c09df0d0..981208fa3 100644 --- a/private-class-data/index.md +++ b/private-class-data/index.md @@ -10,12 +10,14 @@ tags: - Idiom --- -**Intent:** Private Class Data design pattern seeks to reduce exposure of +## Intent +Private Class Data design pattern seeks to reduce exposure of attributes by limiting their visibility. It reduces the number of class attributes by encapsulating them in single Data object.  -**Applicability:** Use the Private Class Data pattern when +## Applicability +Use the Private Class Data pattern when * you want to prevent write access to class data members diff --git a/producer-consumer/index.md b/producer-consumer/index.md index 124c98a2a..c666ab12e 100644 --- a/producer-consumer/index.md +++ b/producer-consumer/index.md @@ -10,13 +10,15 @@ tags: - I/O --- -**Intent:** Producer Consumer Design pattern is a classic concurrency pattern which reduces +## Intent +Producer Consumer Design pattern is a classic concurrency pattern which reduces coupling between Producer and Consumer by separating Identification of work with Execution of Work.  -**Applicability:** Use the Producer Consumer idiom when +## Applicability +Use the Producer Consumer idiom when * decouple system by separate work in two process produce and consume. * addresses the issue of different timing require to produce work or consuming work diff --git a/property/index.md b/property/index.md index 9949239c1..0ac5c7a6c 100644 --- a/property/index.md +++ b/property/index.md @@ -9,15 +9,17 @@ tags: - Difficulty-Beginner --- -**Intent:** Create hierarchy of objects and new objects using already existing +## Intent +Create hierarchy of objects and new objects using already existing objects as parents.  -**Applicability:** Use the Property pattern when +## Applicability +Use the Property pattern when * when you like to have objects with dynamic set of fields and prototype inheritance -**Real world examples:** +## Real world examples * [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) prototype inheritance diff --git a/prototype/index.md b/prototype/index.md index 457c2f46a..632daca93 100644 --- a/prototype/index.md +++ b/prototype/index.md @@ -10,21 +10,23 @@ tags: - Difficulty-Beginner --- -**Intent:** Specify the kinds of objects to create using a prototypical +## Intent +Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.  -**Applicability:** Use the Prototype pattern when a system should be independent of how its products are created, composed and represented; and +## Applicability +Use the Prototype pattern when a system should be independent of how its products are created, composed and represented; and * when the classes to instantiate are specified at run-time, for example, by dynamic loading; or * to avoid building a class hierarchy of factories that parallels the class hierarchy of products; or * when instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state -**Real world examples:** +## Real world examples * [java.lang.Object#clone()](http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#clone%28%29) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/proxy/index.md b/proxy/index.md index 2f16527a8..a3e03708e 100644 --- a/proxy/index.md +++ b/proxy/index.md @@ -10,14 +10,17 @@ tags: - Difficulty-Beginner --- -**Also known as:** Surrogate +## Also known as +Surrogate -**Intent:** Provide a surrogate or placeholder for another object to control +## Intent +Provide a surrogate or placeholder for another object to control access to it.  -**Applicability:** Proxy is applicable whenever there is a need for a more +## Applicability +Proxy is applicable whenever there is a need for a more versatile or sophisticated reference to an object than a simple pointer. Here are several common situations in which the Proxy pattern is applicable @@ -25,7 +28,7 @@ are several common situations in which the Proxy pattern is applicable * a virtual proxy creates expensive objects on demand. * a protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights. -**Typical Use Case:** +## Typical Use Case * control access to another object * lazy initialization @@ -33,11 +36,11 @@ are several common situations in which the Proxy pattern is applicable * facilitate network connection * to count references to an object -**Real world examples:** +## Real world examples * [java.lang.reflect.Proxy](http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html) * [Apache Commons Proxy](https://commons.apache.org/proper/commons-proxy/) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/publish-subscribe/index.md b/publish-subscribe/index.md index cd1ad3971..bd83e37fb 100644 --- a/publish-subscribe/index.md +++ b/publish-subscribe/index.md @@ -7,13 +7,15 @@ categories: Integration tags: - Java - EIP - - Camel + - Apache Camelâ„¢ --- -**Intent:** Broadcast messages from sender to all the interested receivers. +## Intent +Broadcast messages from sender to all the interested receivers.  -**Applicability:** Use the Publish Subscribe Channel pattern when +## Applicability +Use the Publish Subscribe Channel pattern when -* two or more applications need to communicate using a messaging system for broadcasts. +* two or more applications need to communicate using a messaging system for broadcasts. \ No newline at end of file diff --git a/reactor/index.md b/reactor/index.md index 9071413d8..b9ba98948 100644 --- a/reactor/index.md +++ b/reactor/index.md @@ -10,21 +10,23 @@ tags: - I/O --- -**Intent:** The Reactor design pattern handles service requests that are delivered concurrently to an application by one or more clients. The application can register specific handlers for processing which are called by reactor on specific events. Dispatching of event handlers is performed by an initiation dispatcher, which manages the registered event handlers. Demultiplexing of service requests is performed by a synchronous event demultiplexer. +## Intent +The Reactor design pattern handles service requests that are delivered concurrently to an application by one or more clients. The application can register specific handlers for processing which are called by reactor on specific events. Dispatching of event handlers is performed by an initiation dispatcher, which manages the registered event handlers. Demultiplexing of service requests is performed by a synchronous event demultiplexer.  -**Applicability:** Use Reactor pattern when +## Applicability +Use Reactor pattern when * a server application needs to handle concurrent service requests from multiple clients. * a server application needs to be available for receiving requests from new clients even when handling older client requests. * a server must maximize throughput, minimize latency and use CPU efficiently without blocking. -**Real world examples:** +## Real world examples * [Spring Reactor](http://projectreactor.io/) -**Credits** +## Credits * [Douglas C. Schmidt - Reactor](https://www.dre.vanderbilt.edu/~schmidt/PDF/Reactor.pdf) * [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697) diff --git a/reader-writer-lock/etc/reader-writer-lock.png b/reader-writer-lock/etc/reader-writer-lock.png new file mode 100644 index 0000000000000000000000000000000000000000..f7b6005309263d2dc8baf7505fd68091a580011b GIT binary patch literal 39623 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 literal 0 HcmV?d00001 diff --git a/reader-writer-lock/etc/reader-writer-lock.ucls b/reader-writer-lock/etc/reader-writer-lock.ucls new file mode 100644 index 000000000..920904e76 --- /dev/null +++ b/reader-writer-lock/etc/reader-writer-lock.ucls @@ -0,0 +1,86 @@ +<?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.reader.writer.lock.Writer" project="reader-writer-lock" + file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java" binary="false" + corner="BOTTOM_RIGHT"> + <position height="-1" width="-1" x="487" y="105"/> + <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="2" language="java" name="com.iluwatar.reader.writer.lock.ReaderWriterLock.WriteLock" + project="reader-writer-lock" + file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java" binary="false" + corner="BOTTOM_RIGHT"> + <position height="191" width="197" x="488" y="313"/> + <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.reader.writer.lock.ReaderWriterLock" project="reader-writer-lock" + file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java" binary="false" + corner="BOTTOM_RIGHT"> + <position height="245" width="224" x="606" y="28"/> + <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.reader.writer.lock.Reader" project="reader-writer-lock" + file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java" binary="false" + corner="BOTTOM_RIGHT"> + <position height="-1" width="-1" x="944" y="109"/> + <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.reader.writer.lock.ReaderWriterLock.ReadLock" + project="reader-writer-lock" + file="/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java" binary="false" + corner="BOTTOM_RIGHT"> + <position height="191" width="197" x="725" y="313"/> + <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> + <nesting id="6"> + <end type="SOURCE" refId="3"/> + <end type="TARGET" refId="2"/> + </nesting> + <association id="7"> + <end type="SOURCE" refId="3" navigable="false"> + <attribute id="8" name="writerLock"/> + <multiplicity id="9" minimum="0" maximum="1"/> + </end> + <end type="TARGET" refId="2" navigable="true"/> + <display labels="true" multiplicity="true"/> + </association> + <association id="10"> + <end type="SOURCE" refId="3" navigable="false"> + <attribute id="11" name="readerLock"/> + <multiplicity id="12" minimum="0" maximum="1"/> + </end> + <end type="TARGET" refId="5" navigable="true"/> + <display labels="true" multiplicity="true"/> + </association> + <nesting id="13"> + <end type="SOURCE" refId="3"/> + <end type="TARGET" refId="5"/> + </nesting> + <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> \ No newline at end of file diff --git a/reader-writer-lock/index.md b/reader-writer-lock/index.md new file mode 100644 index 000000000..91d16892c --- /dev/null +++ b/reader-writer-lock/index.md @@ -0,0 +1,29 @@ +--- +layout: pattern +title: Reader Writer Lock +folder: reader-writer-lock +permalink: /patterns/reader-writer-lock/ +categories: Concurrent +tags: +- Java +--- + +**Intent:** + +Suppose we have a shared memory area with the basic constraints detailed above. It is possible to protect the shared data behind a mutual exclusion mutex, in which case no two threads can access the data at the same time. However, this solution is suboptimal, because it is possible that a reader R1 might have the lock, and then another reader R2 requests access. It would be foolish for R2 to wait until R1 was done before starting its own read operation; instead, R2 should start right away. This is the motivation for the Reader Writer Lock pattern. + + + +**Applicability:** + +Application need to increase the performance of resource synchronize for multiple thread, in particularly there are mixed read/write operations. + +**Real world examples:** + +* [Java Reader Writer Lock](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html) + +**Credits** + +* [Readers–writer lock](https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock) + +* [Readers–writers_problem](https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem) \ No newline at end of file diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml new file mode 100644 index 000000000..14b17011d --- /dev/null +++ b/reader-writer-lock/pom.xml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.iluwatar</groupId> + <artifactId>java-design-patterns</artifactId> + <version>1.10.0-SNAPSHOT</version> + </parent> + <artifactId>reader-writer-lock</artifactId> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + + </dependencies> +</project> diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java new file mode 100644 index 000000000..b11b11be7 --- /dev/null +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/App.java @@ -0,0 +1,56 @@ +package com.iluwatar.reader.writer.lock; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; + +/** + * + * In a multiple thread applications, the threads may try to synchronize the shared resources + * regardless of read or write operation. It leads to a low performance especially in a "read more + * write less" system as indeed the read operations are thread-safe to another read operation. + * <p> + * Reader writer lock is a synchronization primitive that try to resolve this problem. This pattern + * allows concurrent access for read-only operations, while write operations require exclusive + * access. This means that multiple threads can read the data in parallel but an exclusive lock is + * needed for writing or modifying data. When a writer is writing the data, all other writers or + * readers will be blocked until the writer is finished writing. + * + * <p> + * This example use two mutex to demonstrate the concurrent access of multiple readers and writers. + * + * + * @author hongshuwei@gmail.com + */ +public class App { + + /** + * Program entry point + * + * @param args command line args + */ + public static void main(String[] args) { + + ExecutorService executeService = Executors.newFixedThreadPool(10); + ReaderWriterLock lock = new ReaderWriterLock(); + + // Start 5 readers + IntStream.range(0, 5) + .forEach(i -> executeService.submit(new Reader("Reader " + i, lock.readLock()))); + + // Start 5 writers + IntStream.range(0, 5) + .forEach(i -> executeService.submit(new Writer("Writer " + i, lock.writeLock()))); + // In the system console, it can see that the read operations are executed concurrently while + // write operations are exclusive. + executeService.shutdown(); + try { + executeService.awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + System.out.println("Error waiting for ExecutorService shutdown"); + } + + } + +} diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java new file mode 100644 index 000000000..214528080 --- /dev/null +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Reader.java @@ -0,0 +1,40 @@ +package com.iluwatar.reader.writer.lock; + +import java.util.concurrent.locks.Lock; + +/** + * Reader class, read when it acquired the read lock + */ +public class Reader implements Runnable { + + private Lock readLock; + + private String name; + + public Reader(String name, Lock readLock) { + this.name = name; + this.readLock = readLock; + } + + @Override + public void run() { + readLock.lock(); + try { + read(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + readLock.unlock(); + } + } + + /** + * Simulate the read operation + * + */ + public void read() throws InterruptedException { + System.out.println(name + " begin"); + Thread.sleep(250); + System.out.println(name + " finish"); + } +} diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java new file mode 100644 index 000000000..b7edd149c --- /dev/null +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/ReaderWriterLock.java @@ -0,0 +1,211 @@ +package com.iluwatar.reader.writer.lock; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; + +/** + * Class responsible for control the access for reader or writer + * + * Allows multiple readers to hold the lock at same time, but if any writer holds the lock then + * readers wait. If reader holds the lock then writer waits. This lock is not fair. + */ +public class ReaderWriterLock implements ReadWriteLock { + + + private Object readerMutex = new Object(); + + private int currentReaderCount = 0; + + /** + * Global mutex is used to indicate that whether reader or writer gets the lock in the moment. + * <p> + * 1. When it contains the reference of {@link readerLock}, it means that the lock is acquired by + * the reader, another reader can also do the read operation concurrently. <br> + * 2. When it contains the reference of reference of {@link writerLock}, it means that the lock is + * acquired by the writer exclusively, no more reader or writer can get the lock. + * <p> + * This is the most important field in this class to control the access for reader/writer. + */ + private Set<Object> globalMutex = new HashSet<>(); + + private ReadLock readerLock = new ReadLock(); + private WriteLock writerLock = new WriteLock(); + + @Override + public Lock readLock() { + return readerLock; + } + + @Override + public Lock writeLock() { + return writerLock; + } + + /** + * return true when globalMutex hold the reference of writerLock + */ + private boolean doesWriterOwnThisLock() { + return globalMutex.contains(writerLock); + } + + /** + * return true when globalMutex hold the reference of readerLock + */ + private boolean doesReaderOwnThisLock() { + return globalMutex.contains(readerLock); + } + + /** + * Nobody get the lock when globalMutex contains nothing + * + */ + private boolean isLockFree() { + return globalMutex.isEmpty(); + } + + private void waitUninterruptibly(Object o) { + try { + o.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * Reader Lock, can be access for more than one reader concurrently if no writer get the lock + */ + private class ReadLock implements Lock { + + @Override + public void lock() { + + synchronized (readerMutex) { + + currentReaderCount++; + if (currentReaderCount == 1) { + // Try to get the globalMutex lock for the first reader + synchronized (globalMutex) { + while (true) { + // If the no one get the lock or the lock is locked by reader, just set the reference + // to the globalMutex to indicate that the lock is locked by Reader. + if (isLockFree() || doesReaderOwnThisLock()) { + globalMutex.add(this); + break; + } else { + // If lock is acquired by the write, let the thread wait until the writer release + // the lock + waitUninterruptibly(globalMutex); + } + } + } + + } + } + } + + @Override + public void unlock() { + + synchronized (readerMutex) { + currentReaderCount--; + // Release the lock only when it is the last reader, it is ensure that the lock is released + // when all reader is completely. + if (currentReaderCount == 0) { + synchronized (globalMutex) { + // Notify the waiter, mostly the writer + globalMutex.remove(this); + globalMutex.notifyAll(); + } + } + } + + } + + @Override + public void lockInterruptibly() throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean tryLock() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public Condition newCondition() { + throw new UnsupportedOperationException(); + } + + } + + /** + * Writer Lock, can only be accessed by one writer concurrently + */ + private class WriteLock implements Lock { + + @Override + public void lock() { + + synchronized (globalMutex) { + + while (true) { + // When there is no one acquired the lock, just put the writeLock reference to the + // globalMutex to indicate that the lock is acquired by one writer. + // It is ensure that writer can only get the lock when no reader/writer acquired the lock. + if (isLockFree()) { + globalMutex.add(this); + break; + } else if (doesWriterOwnThisLock()) { + // Wait when other writer get the lock + waitUninterruptibly(globalMutex); + } else if (doesReaderOwnThisLock()) { + // Wait when other reader get the lock + waitUninterruptibly(globalMutex); + } else { + throw new AssertionError("it should never reach here"); + } + } + } + } + + @Override + public void unlock() { + + synchronized (globalMutex) { + globalMutex.remove(this); + // Notify the waiter, other writer or reader + globalMutex.notifyAll(); + } + } + + @Override + public void lockInterruptibly() throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean tryLock() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public Condition newCondition() { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java new file mode 100644 index 000000000..ae7b17080 --- /dev/null +++ b/reader-writer-lock/src/main/java/com/iluwatar/reader/writer/lock/Writer.java @@ -0,0 +1,40 @@ +package com.iluwatar.reader.writer.lock; + +import java.util.concurrent.locks.Lock; + +/** + * Writer class, write when it acquired the write lock + */ +public class Writer implements Runnable { + + private Lock writeLock = null; + + private String name; + + public Writer(String name, Lock writeLock) { + this.name = name; + this.writeLock = writeLock; + } + + + @Override + public void run() { + writeLock.lock(); + try { + write(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + writeLock.unlock(); + } + } + + /** + * Simulate the write operation + */ + public void write() throws InterruptedException { + System.out.println(name + " begin"); + Thread.sleep(250); + System.out.println(name + " finish"); + } +} diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/AppTest.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/AppTest.java new file mode 100644 index 000000000..5dd6feaab --- /dev/null +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/AppTest.java @@ -0,0 +1,16 @@ +package com.iluwatar.reader.writer.lock; + +import org.junit.Test; + +/** + * Application test + */ +public class AppTest { + + @Test + public void test() throws Exception { + String[] args = {}; + App.main(args); + + } +} diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/ReaderAndWriterTest.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/ReaderAndWriterTest.java new file mode 100644 index 000000000..e29f57889 --- /dev/null +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/ReaderAndWriterTest.java @@ -0,0 +1,81 @@ +package com.iluwatar.reader.writer.lock; + +import static org.mockito.Mockito.inOrder; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.junit.Test; +import org.mockito.InOrder; + +/** + * @author hongshuwei@gmail.com + */ +public class ReaderAndWriterTest extends StdOutTest { + + + + /** + * Verify reader and writer can only get the lock to read and write orderly + */ + @Test + public void testReadAndWrite() throws Exception { + + ReaderWriterLock lock = new ReaderWriterLock(); + + Reader reader1 = new Reader("Reader 1", lock.readLock()); + Writer writer1 = new Writer("Writer 1", lock.writeLock()); + + ExecutorService executeService = Executors.newFixedThreadPool(2); + executeService.submit(reader1); + // Let reader1 execute first + Thread.sleep(150); + executeService.submit(writer1); + + executeService.shutdown(); + try { + executeService.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + System.out.println("Error waiting for ExecutorService shutdown"); + } + + final InOrder inOrder = inOrder(getStdOutMock()); + inOrder.verify(getStdOutMock()).println("Reader 1 begin"); + inOrder.verify(getStdOutMock()).println("Reader 1 finish"); + inOrder.verify(getStdOutMock()).println("Writer 1 begin"); + inOrder.verify(getStdOutMock()).println("Writer 1 finish"); + } + + /** + * Verify reader and writer can only get the lock to read and write orderly + */ + @Test + public void testWriteAndRead() throws Exception { + + ExecutorService executeService = Executors.newFixedThreadPool(2); + ReaderWriterLock lock = new ReaderWriterLock(); + + Reader reader1 = new Reader("Reader 1", lock.readLock()); + Writer writer1 = new Writer("Writer 1", lock.writeLock()); + + executeService.submit(writer1); + // Let writer1 execute first + Thread.sleep(150); + executeService.submit(reader1); + + executeService.shutdown(); + try { + executeService.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + System.out.println("Error waiting for ExecutorService shutdown"); + } + + final InOrder inOrder = inOrder(getStdOutMock()); + inOrder.verify(getStdOutMock()).println("Writer 1 begin"); + inOrder.verify(getStdOutMock()).println("Writer 1 finish"); + inOrder.verify(getStdOutMock()).println("Reader 1 begin"); + inOrder.verify(getStdOutMock()).println("Reader 1 finish"); + } +} + diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/ReaderTest.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/ReaderTest.java new file mode 100644 index 000000000..e76fe29c2 --- /dev/null +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/ReaderTest.java @@ -0,0 +1,50 @@ +package com.iluwatar.reader.writer.lock; + +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.spy; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.junit.Test; +import org.mockito.InOrder; + +/** + * @author hongshuwei@gmail.com + */ +public class ReaderTest extends StdOutTest { + + /** + * Verify that multiple readers can get the read lock concurrently + */ + @Test + public void testRead() throws Exception { + + ExecutorService executeService = Executors.newFixedThreadPool(2); + ReaderWriterLock lock = new ReaderWriterLock(); + + Reader reader1 = spy(new Reader("Reader 1", lock.readLock())); + Reader reader2 = spy(new Reader("Reader 2", lock.readLock())); + + executeService.submit(reader1); + Thread.sleep(150); + executeService.submit(reader2); + + executeService.shutdown(); + try { + executeService.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + System.out.println("Error waiting for ExecutorService shutdown"); + } + + // Read operation will hold the read lock 250 milliseconds, so here we prove that multiple reads + // can be performed in the same time. + final InOrder inOrder = inOrder(getStdOutMock()); + inOrder.verify(getStdOutMock()).println("Reader 1 begin"); + inOrder.verify(getStdOutMock()).println("Reader 2 begin"); + inOrder.verify(getStdOutMock()).println("Reader 1 finish"); + inOrder.verify(getStdOutMock()).println("Reader 2 finish"); + + } +} diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/StdOutTest.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/StdOutTest.java new file mode 100644 index 000000000..762574b66 --- /dev/null +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/StdOutTest.java @@ -0,0 +1,53 @@ +package com.iluwatar.reader.writer.lock; + +import org.junit.After; +import org.junit.Before; + +import java.io.PrintStream; + +import static org.mockito.Mockito.mock; + +/** + * Date: 12/10/15 - 8:37 PM + * + * @author Jeroen Meulemeester + */ +public abstract class StdOutTest { + + /** + * The mocked standard out {@link PrintStream}, required since some actions don't have any + * influence on accessible objects, except for writing to std-out using {@link System#out} + */ + private final PrintStream stdOutMock = mock(PrintStream.class); + + /** + * Keep the original std-out so it can be restored after the test + */ + private final PrintStream stdOutOrig = System.out; + + /** + * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test + */ + @Before + public void setUp() { + System.setOut(this.stdOutMock); + } + + /** + * Removed the mocked std-out {@link PrintStream} again from the {@link System} class + */ + @After + public void tearDown() { + System.setOut(this.stdOutOrig); + } + + /** + * Get the mocked stdOut {@link PrintStream} + * + * @return The stdOut print stream mock, renewed before each test + */ + final PrintStream getStdOutMock() { + return this.stdOutMock; + } + +} diff --git a/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/WriterTest.java b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/WriterTest.java new file mode 100644 index 000000000..ed37bf3e5 --- /dev/null +++ b/reader-writer-lock/src/test/java/com/iluwatar/reader/writer/lock/WriterTest.java @@ -0,0 +1,50 @@ +package com.iluwatar.reader.writer.lock; + +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.spy; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.junit.Test; +import org.mockito.InOrder; + +/** + * @author hongshuwei@gmail.com + */ +public class WriterTest extends StdOutTest { + + /** + * Verify that multiple writers will get the lock in order. + */ + @Test + public void testWrite() throws Exception { + + ExecutorService executeService = Executors.newFixedThreadPool(2); + ReaderWriterLock lock = new ReaderWriterLock(); + + Writer writer1 = spy(new Writer("Writer 1", lock.writeLock())); + Writer writer2 = spy(new Writer("Writer 2", lock.writeLock())); + + executeService.submit(writer1); + // Let write1 execute first + Thread.sleep(150); + executeService.submit(writer2); + + executeService.shutdown(); + try { + executeService.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + System.out.println("Error waiting for ExecutorService shutdown"); + } + // Write operation will hold the write lock 250 milliseconds, so here we verify that when two + // writer execute concurrently, the second writer can only writes only when the first one is + // finished. + final InOrder inOrder = inOrder(getStdOutMock()); + inOrder.verify(getStdOutMock()).println("Writer 1 begin"); + inOrder.verify(getStdOutMock()).println("Writer 1 finish"); + inOrder.verify(getStdOutMock()).println("Writer 2 begin"); + inOrder.verify(getStdOutMock()).println("Writer 2 finish"); + } +} diff --git a/repository/index.md b/repository/index.md index 697c708f9..67b3ea44e 100644 --- a/repository/index.md +++ b/repository/index.md @@ -10,7 +10,8 @@ tags: - Spring --- -**Intent:** Repository layer is added between the domain and data mapping +## Intent +Repository layer is added between the domain and data mapping layers to isolate domain objects from details of the database access code and to minimize scattering and duplication of query code. The Repository pattern is especially useful in systems where number of domain classes is large or heavy @@ -18,19 +19,19 @@ querying is utilized.  -**Applicability:** Use the Repository pattern when +## Applicability +Use the Repository pattern when * the number of domain objects is large * you want to avoid duplication of query code * you want to keep the database querying code in single place * you have multiple data sources -**Real world examples:** +## Real world examples * [Spring Data](http://projects.spring.io/spring-data/) -**Credits:** +## Credits * [Don’t use DAO, use Repository](http://thinkinginobjects.com/2012/08/26/dont-use-dao-use-repository/) * [Advanced Spring Data JPA - Specifications and Querydsl](https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/) - diff --git a/resource-acquisition-is-initialization/index.md b/resource-acquisition-is-initialization/index.md index e808783fb..821f220d7 100644 --- a/resource-acquisition-is-initialization/index.md +++ b/resource-acquisition-is-initialization/index.md @@ -10,10 +10,12 @@ tags: - Idiom --- -**Intent:** Resource Acquisition Is Initialization pattern can be used to implement exception safe resource management. +## Intent +Resource Acquisition Is Initialization pattern can be used to implement exception safe resource management.  -**Applicability:** Use the Resource Acquisition Is Initialization pattern when +## Applicability +Use the Resource Acquisition Is Initialization pattern when * you have resources that must be closed in every condition diff --git a/servant/index.md b/servant/index.md index 9cf20a53e..895b87502 100644 --- a/servant/index.md +++ b/servant/index.md @@ -9,12 +9,14 @@ tags: - Difficulty-Beginner --- -**Intent:** Servant is used for providing some behavior to a group of classes. +## Intent +Servant is used for providing some behavior to a group of classes. Instead of defining that behavior in each class - or when we cannot factor out this behavior in the common parent class - it is defined once in the Servant.  -**Applicability:** Use the Servant pattern when +## Applicability +Use the Servant pattern when * when we want some objects to perform a common action and don't want to define this action as a method in every class. diff --git a/service-layer/index.md b/service-layer/index.md index 68f4f6130..9b685d4e3 100644 --- a/service-layer/index.md +++ b/service-layer/index.md @@ -9,7 +9,8 @@ tags: - Difficulty-Intermediate --- -**Intent:** Service Layer is an abstraction over domain logic. Typically +## Intent +Service Layer is an abstraction over domain logic. Typically applications require multiple kinds of interfaces to the data they store and logic they implement: data loaders, user interfaces, integration gateways, and others. Despite their different purposes, these interfaces often need common @@ -18,12 +19,13 @@ its business logic. The Service Layer fulfills this role.  -**Applicability:** Use the Service Layer pattern when +## Applicability +Use the Service Layer pattern when * you want to encapsulate domain logic under API * you need to implement multiple interfaces with common logic and data -**Credits:** +## Credits * [Martin Fowler - Service Layer](http://martinfowler.com/eaaCatalog/serviceLayer.html) * [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420) diff --git a/service-locator/index.md b/service-locator/index.md index 7357a0ac0..af4d8c3ac 100644 --- a/service-locator/index.md +++ b/service-locator/index.md @@ -10,12 +10,14 @@ tags: - Performance --- -**Intent:** Encapsulate the processes involved in obtaining a service with a +## Intent +Encapsulate the processes involved in obtaining a service with a strong abstraction layer.  -**Applicability:** The service locator pattern is applicable whenever we want +## Applicability +The service locator pattern is applicable whenever we want to locate/fetch various services using JNDI which, typically, is a redundant and expensive lookup. The service Locator pattern addresses this expensive lookup by making use of caching techniques ie. for the very first time a @@ -24,12 +26,12 @@ the relevant service and then finally caches this service object. Now, further lookups of the same service via Service Locator is done in its cache which improves the performance of application to great extent. -**Typical Use Case:** +## Typical Use Case * when network hits are expensive and time consuming * lookups of services are done quite frequently * large number of services are being used -**Credits:** +## Credits * [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2) diff --git a/singleton/index.md b/singleton/index.md index 18c137448..dcbd63902 100644 --- a/singleton/index.md +++ b/singleton/index.md @@ -10,26 +10,28 @@ tags: - Difficulty-Beginner --- -**Intent:** Ensure a class only has one instance, and provide a global point of +## Intent +Ensure a class only has one instance, and provide a global point of access to it.  -**Applicability:** Use the Singleton pattern when +## Applicability +Use the Singleton pattern when * there must be exactly one instance of a class, and it must be accessible to clients from a well-known access point * when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code -**Typical Use Case:** +## Typical Use Case * the logging class * managing a connection to a database * file manager -**Real world examples:** +## Real world examples * [java.lang.Runtime#getRuntime()](http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#getRuntime%28%29) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/specification/index.md b/specification/index.md index f95c7921a..df6a4c3eb 100644 --- a/specification/index.md +++ b/specification/index.md @@ -9,18 +9,20 @@ tags: - Difficulty-Beginner --- -**Intent:** Specification pattern separates the statement of how to match a +## Intent +Specification pattern separates the statement of how to match a candidate, from the candidate object that it is matched against. As well as its usefulness in selection, it is also valuable for validation and for building to order  -**Applicability:** Use the Specification pattern when +## Applicability +Use the Specification pattern when * you need to select a subset of objects based on some criteria, and to refresh the selection at various times * you need to check that only suitable objects are used for a certain role (validation) -**Credits:** +## Credits * [Martin Fowler - Specifications](http://martinfowler.com/apsupp/spec.pdf) diff --git a/state/index.md b/state/index.md index 3beeb480a..f5cb189fd 100644 --- a/state/index.md +++ b/state/index.md @@ -10,18 +10,21 @@ tags: - Gang Of Four --- -**Also known as:** Objects for States +## Also known as +Objects for States -**Intent:** Allow an object to alter its behavior when its internal state +## Intent +Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.  -**Applicability:** Use the State pattern in either of the following cases +## Applicability +Use the State pattern in either of the following cases * an object's behavior depends on its state, and it must change its behavior at run-time depending on that state * operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects. -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/step-builder/index.md b/step-builder/index.md index 7ca93c276..bc636e37a 100644 --- a/step-builder/index.md +++ b/step-builder/index.md @@ -9,13 +9,15 @@ tags: - Difficulty-Intermediate --- -**Intent:** An extension of the Builder pattern that fully guides the user through the creation of the object with no chances of confusion. +## Intent +An extension of the Builder pattern that fully guides the user through the creation of the object with no chances of confusion. The user experience will be much more improved by the fact that he will only see the next step methods available, NO build method until is the right time to build the object.  -**Applicability:** Use the Step Builder pattern when the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled the construction process must allow different representations for the object that's constructed when in the process of constructing the order is important. +## Applicability +Use the Step Builder pattern when the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled the construction process must allow different representations for the object that's constructed when in the process of constructing the order is important. -**Credits:** +## Credits * [Marco Castigliego - Step Builder](http://rdafbn.blogspot.co.uk/2012/07/step-builder-pattern_28.html) diff --git a/strategy/index.md b/strategy/index.md index 288276015..9b35b806d 100644 --- a/strategy/index.md +++ b/strategy/index.md @@ -10,21 +10,24 @@ tags: - Gang Of Four --- -**Also known as:** Policy +## Also known as +Policy -**Intent:** Define a family of algorithms, encapsulate each one, and make them +## Intent +Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.  -**Applicability:** Use the Strategy pattern when +## Applicability +Use the Strategy pattern when * many related classes differ only in their behavior. Strategies provide a way to configure a class either one of many behaviors * you need different variants of an algorithm. for example, you might define algorithms reflecting different space/time trade-offs. Strategies can be used when these variants are implemented as a class hierarchy of algorithms * an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures * a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/template-method/index.md b/template-method/index.md index 8b8b7878e..ad972f06b 100644 --- a/template-method/index.md +++ b/template-method/index.md @@ -10,18 +10,20 @@ tags: - Gang Of Four --- -**Intent:** Define the skeleton of an algorithm in an operation, deferring some +## Intent +Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.  -**Applicability:** The Template Method pattern should be used +## Applicability +The Template Method pattern should be used * to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary * when common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is good example of "refactoring to generalize" as described by Opdyke and Johnson. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations * to control subclasses extensions. You can define a template method that calls "hook" operations at specific points, thereby permitting extensions only at those points -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/thread-pool/index.md b/thread-pool/index.md index d4b61607d..9806fa8e0 100644 --- a/thread-pool/index.md +++ b/thread-pool/index.md @@ -10,7 +10,8 @@ tags: - Performance --- -**Intent:** It is often the case that tasks to be executed are short-lived and +## Intent +It is often the case that tasks to be executed are short-lived and the number of tasks is large. Creating a new thread for each task would make the system spend more time creating and destroying the threads than executing the actual tasks. Thread Pool solves this problem by reusing existing threads @@ -18,6 +19,7 @@ and eliminating the latency of creating new threads.  -**Applicability:** Use the Thread Pool pattern when +## Applicability +Use the Thread Pool pattern when * you have a large number of short-lived tasks to be executed in parallel diff --git a/tolerant-reader/index.md b/tolerant-reader/index.md index 895886f77..be0085f2c 100644 --- a/tolerant-reader/index.md +++ b/tolerant-reader/index.md @@ -9,17 +9,19 @@ tags: - Difficulty-Beginner --- -**Intent:** Tolerant Reader is an integration pattern that helps creating +## Intent +Tolerant Reader is an integration pattern that helps creating robust communication systems. The idea is to be as tolerant as possible when reading data from another service. This way, when the communication schema changes, the readers must not break.  -**Applicability:** Use the Tolerant Reader pattern when +## Applicability +Use the Tolerant Reader pattern when * the communication schema can evolve and change and yet the receiving side should not break -**Credits:** +## Credits * [Martin Fowler - Tolerant Reader](http://martinfowler.com/bliki/TolerantReader.html) diff --git a/twin/index.md b/twin/index.md index e0e449047..3795236bb 100644 --- a/twin/index.md +++ b/twin/index.md @@ -9,16 +9,18 @@ tags: - Difficulty-Intermediate --- -**Intent:** Twin pattern is a design pattern which provides a standard solution to simulate multiple +## Intent + Twin pattern is a design pattern which provides a standard solution to simulate multiple inheritance in java  -**Applicability:** Use the Twin idiom when +## Applicability +Use the Twin idiom when * to simulate multiple inheritance in a language that does not support this feature. * to avoid certain problems of multiple inheritance such as name clashes. -**Credits:** +## Credits * [Twin – A Design Pattern for Modeling Multiple Inheritance](http://www.ssw.uni-linz.ac.at/Research/Papers/Moe99/Paper.pdf) diff --git a/visitor/index.md b/visitor/index.md index 760f2c705..c1e24a624 100644 --- a/visitor/index.md +++ b/visitor/index.md @@ -10,22 +10,24 @@ tags: - Gang Of Four --- -**Intent:** Represent an operation to be performed on the elements of an object +## Intent +Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.  -**Applicability:** Use the Visitor pattern when +## Applicability +Use the Visitor pattern when * an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes * many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them * the classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes -**Real world examples:** +## Real world examples * [Apache Wicket](https://github.com/apache/wicket) component tree, see [MarkupContainer](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java) -**Credits** +## Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) From 89e0e3e73e55d8bcab5154e196cd66c2013393ae Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Mon, 25 Jan 2016 21:16:35 +0000 Subject: [PATCH 04/22] #354 Remove generated copyright banner --- feature-toggle/pom.xml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index 98c140f37..249d999a1 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -1,27 +1,4 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ The MIT License (MIT) - ~ - ~ Copyright (c) 2016 Orange Foundry - ~ - ~ 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" From 0b834128b9898c094af2510428ef76537cee5db9 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Mon, 25 Jan 2016 21:29:05 +0000 Subject: [PATCH 05/22] #354 Add Blank index.md --- feature-toggle/index.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 feature-toggle/index.md diff --git a/feature-toggle/index.md b/feature-toggle/index.md new file mode 100644 index 000000000..e69de29bb From 72733acfc67055300a3ebf5352d2467ca8c4ad19 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Tue, 26 Jan 2016 18:41:08 +0000 Subject: [PATCH 06/22] #354 added usergroup for version of feature toggle --- feature-toggle/pom.xml | 8 ++++ .../com/iluwatar/featuretoggle/user/User.java | 7 ++++ .../featuretoggle/user/UserGroup.java | 37 +++++++++++++++++++ .../featuretoggle/user/UserGroupTest.java | 37 +++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java create mode 100644 feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java create mode 100644 feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index 249d999a1..9a2b04de3 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -13,4 +13,12 @@ <artifactId>feature-toggle</artifactId> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + +</dependencies> </project> \ No newline at end of file diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java new file mode 100644 index 000000000..f25747997 --- /dev/null +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java @@ -0,0 +1,7 @@ +package com.iluwatar.featuretoggle.user; + +/** + * Created by joseph on 26/01/16. + */ +public class User { +} diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java new file mode 100644 index 000000000..315c88b45 --- /dev/null +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -0,0 +1,37 @@ +package com.iluwatar.featuretoggle.user; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by joseph on 26/01/16. + */ +public class UserGroup { + + private static List<User> freeGroup = new ArrayList<>(); + private static List<User> paidGroup = new ArrayList<>(); + + public static void addUserToFreeGroup(final User user){ + if(paidGroup.contains(user)){ + throw new IllegalArgumentException("User all ready member of paid group."); + }else{ + if(!freeGroup.contains(user)){ + freeGroup.add(user); + } + } + } + + public static void addUserToPaidGroup(final User user){ + if(freeGroup.contains(user)){ + throw new IllegalArgumentException("User all ready member of free group."); + }else{ + if(!paidGroup.contains(user)){ + paidGroup.add(user); + } + } + } + + public static boolean isPaid(User user) { + return paidGroup.contains(user); + } +} diff --git a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java new file mode 100644 index 000000000..f74d79064 --- /dev/null +++ b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java @@ -0,0 +1,37 @@ +package com.iluwatar.featuretoggle.user; + +import org.junit.Test; + +import static junit.framework.TestCase.assertFalse; +import static org.junit.Assert.assertTrue; + +public class UserGroupTest { + + @Test + public void testAddUserToFreeGroup() throws Exception { + User user = new User(); + UserGroup.addUserToFreeGroup(user); + assertFalse(UserGroup.isPaid(user)); + } + + @Test + public void testAddUserToPaidGroup() throws Exception { + User user = new User(); + UserGroup.addUserToPaidGroup(user); + assertTrue(UserGroup.isPaid(user)); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddUserToPaidWhenOnFree() throws Exception { + User user = new User(); + UserGroup.addUserToFreeGroup(user); + UserGroup.addUserToPaidGroup(user); + } + + @Test(expected = IllegalArgumentException.class) + public void testAddUserToFreeWhenOnPaid() throws Exception { + User user = new User(); + UserGroup.addUserToPaidGroup(user); + UserGroup.addUserToFreeGroup(user); + } +} \ No newline at end of file From a1ede8980f5d68e960b8a03eae9bebd33bb45e7b Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Tue, 26 Jan 2016 18:49:25 +0000 Subject: [PATCH 07/22] #354 Added WelcomeMessage Service and Tests for tier example of featureToggle --- .../featuretoggle/pattern/Service.java | 11 ++++++ .../TieredFeatureToggleVersion.java | 21 ++++++++++ .../TieredFeatureToggleVersionTest.java | 39 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java create mode 100644 feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java create mode 100644 feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java new file mode 100644 index 000000000..058a8f59a --- /dev/null +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java @@ -0,0 +1,11 @@ +package com.iluwatar.featuretoggle.pattern; + +import com.iluwatar.featuretoggle.user.User; + +/** + * Created by joseph on 26/01/16. + */ +public interface Service { + + public String getWelcomeMessage(User user); +} diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java new file mode 100644 index 000000000..3a27453b1 --- /dev/null +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java @@ -0,0 +1,21 @@ +package com.iluwatar.featuretoggle.pattern.tieredversion; + +import com.iluwatar.featuretoggle.pattern.Service; +import com.iluwatar.featuretoggle.user.User; +import com.iluwatar.featuretoggle.user.UserGroup; + +/** + * Created by joseph on 26/01/16. + */ +public class TieredFeatureToggleVersion implements Service { + + @Override + public String getWelcomeMessage(User user) { + if(UserGroup.isPaid(user)){ + return "You're amazing thanks for paying for this awesome software."; + } + + return "I suppose you can use this software."; + } + +} diff --git a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java new file mode 100644 index 000000000..b793c4614 --- /dev/null +++ b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java @@ -0,0 +1,39 @@ +package com.iluwatar.featuretoggle.pattern.tieredversion; + +import com.iluwatar.featuretoggle.pattern.Service; +import com.iluwatar.featuretoggle.user.User; +import com.iluwatar.featuretoggle.user.UserGroup; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by joseph on 26/01/16. + */ +public class TieredFeatureToggleVersionTest { + + User paidUser = new User(); + User freeUser = new User(); + + @Before + public void setUp() throws Exception { + UserGroup.addUserToPaidGroup(paidUser); + UserGroup.addUserToFreeGroup(freeUser); + + } + + @Test + public void testGetWelcomeMessageForPaidUser() throws Exception { + Service service = new TieredFeatureToggleVersion(); + String welcomeMessage = service.getWelcomeMessage(paidUser); + assertEquals("You're amazing thanks for paying for this awesome software.",welcomeMessage); + } + + @Test + public void testGetWelcomeMessageForFreeUser() throws Exception { + Service service = new TieredFeatureToggleVersion(); + String welcomeMessage = service.getWelcomeMessage(freeUser); + assertEquals("I suppose you can use this software.",welcomeMessage); + } +} \ No newline at end of file From 32f9cf3ab1ece2cbf2061b537fb5b4491aa2755e Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Tue, 26 Jan 2016 18:58:35 +0000 Subject: [PATCH 08/22] #354 Some clean up and show the difference between paid and free a bit more. --- .../featuretoggle/pattern/Service.java | 7 +++---- .../TieredFeatureToggleVersion.java | 5 +---- .../com/iluwatar/featuretoggle/user/User.java | 13 +++++++++--- .../featuretoggle/user/UserGroup.java | 3 --- .../TieredFeatureToggleVersionTest.java | 21 ++++++++----------- .../featuretoggle/user/UserGroupTest.java | 8 +++---- 6 files changed, 27 insertions(+), 30 deletions(-) diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java index 058a8f59a..e87983145 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java @@ -2,10 +2,9 @@ package com.iluwatar.featuretoggle.pattern; import com.iluwatar.featuretoggle.user.User; -/** - * Created by joseph on 26/01/16. - */ + public interface Service { - public String getWelcomeMessage(User user); + String getWelcomeMessage(User user); + } diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java index 3a27453b1..16e7c5da7 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java @@ -4,15 +4,12 @@ import com.iluwatar.featuretoggle.pattern.Service; import com.iluwatar.featuretoggle.user.User; import com.iluwatar.featuretoggle.user.UserGroup; -/** - * Created by joseph on 26/01/16. - */ public class TieredFeatureToggleVersion implements Service { @Override public String getWelcomeMessage(User user) { if(UserGroup.isPaid(user)){ - return "You're amazing thanks for paying for this awesome software."; + return "You're amazing " + user.getName() + ". Thanks for paying for this awesome software."; } return "I suppose you can use this software."; diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java index f25747997..a712e4f02 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java @@ -1,7 +1,14 @@ package com.iluwatar.featuretoggle.user; -/** - * Created by joseph on 26/01/16. - */ public class User { + + private String name; + + public User(String name) { + this.name = name; + } + + public String getName() { + return name; + } } diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java index 315c88b45..92b94f678 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -3,9 +3,6 @@ package com.iluwatar.featuretoggle.user; import java.util.ArrayList; import java.util.List; -/** - * Created by joseph on 26/01/16. - */ public class UserGroup { private static List<User> freeGroup = new ArrayList<>(); diff --git a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java index b793c4614..66b6bfc41 100644 --- a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java +++ b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java @@ -8,32 +8,29 @@ import org.junit.Test; import static org.junit.Assert.*; -/** - * Created by joseph on 26/01/16. - */ public class TieredFeatureToggleVersionTest { - User paidUser = new User(); - User freeUser = new User(); + final User paidUser = new User("Jamie Coder"); + final User freeUser = new User("Alan Defect"); + final Service service = new TieredFeatureToggleVersion(); @Before public void setUp() throws Exception { UserGroup.addUserToPaidGroup(paidUser); UserGroup.addUserToFreeGroup(freeUser); - } @Test public void testGetWelcomeMessageForPaidUser() throws Exception { - Service service = new TieredFeatureToggleVersion(); - String welcomeMessage = service.getWelcomeMessage(paidUser); - assertEquals("You're amazing thanks for paying for this awesome software.",welcomeMessage); + final String welcomeMessage = service.getWelcomeMessage(paidUser); + final String expected = "You're amazing Jamie Coder. Thanks for paying for this awesome software."; + assertEquals(expected,welcomeMessage); } @Test public void testGetWelcomeMessageForFreeUser() throws Exception { - Service service = new TieredFeatureToggleVersion(); - String welcomeMessage = service.getWelcomeMessage(freeUser); - assertEquals("I suppose you can use this software.",welcomeMessage); + final String welcomeMessage = service.getWelcomeMessage(freeUser); + final String expected = "I suppose you can use this software."; + assertEquals(expected,welcomeMessage); } } \ No newline at end of file diff --git a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java index f74d79064..372e58c19 100644 --- a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java +++ b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java @@ -9,28 +9,28 @@ public class UserGroupTest { @Test public void testAddUserToFreeGroup() throws Exception { - User user = new User(); + User user = new User("Free User"); UserGroup.addUserToFreeGroup(user); assertFalse(UserGroup.isPaid(user)); } @Test public void testAddUserToPaidGroup() throws Exception { - User user = new User(); + User user = new User("Paid User"); UserGroup.addUserToPaidGroup(user); assertTrue(UserGroup.isPaid(user)); } @Test(expected = IllegalArgumentException.class) public void testAddUserToPaidWhenOnFree() throws Exception { - User user = new User(); + User user = new User("Paid User"); UserGroup.addUserToFreeGroup(user); UserGroup.addUserToPaidGroup(user); } @Test(expected = IllegalArgumentException.class) public void testAddUserToFreeWhenOnPaid() throws Exception { - User user = new User(); + User user = new User("Free User"); UserGroup.addUserToPaidGroup(user); UserGroup.addUserToFreeGroup(user); } From 91b2379fd0d767bc2456b4d5a7fa9498f2fd2785 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Tue, 26 Jan 2016 19:20:28 +0000 Subject: [PATCH 09/22] #354 Fixed CheckStyle Issues --- feature-toggle/pom.xml | 16 +++--- .../featuretoggle/pattern/Service.java | 2 +- .../TieredFeatureToggleVersion.java | 14 ++--- .../com/iluwatar/featuretoggle/user/User.java | 14 ++--- .../featuretoggle/user/UserGroup.java | 53 +++++++++++-------- .../TieredFeatureToggleVersionTest.java | 42 +++++++-------- .../featuretoggle/user/UserGroupTest.java | 48 ++++++++--------- 7 files changed, 100 insertions(+), 89 deletions(-) diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index 9a2b04de3..c6dde055d 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://maven.apache.org/POM/4.0.0" 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> @@ -14,11 +14,11 @@ <dependencies> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> -</dependencies> + </dependencies> </project> \ No newline at end of file diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java index e87983145..843ee173f 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java @@ -5,6 +5,6 @@ import com.iluwatar.featuretoggle.user.User; public interface Service { - String getWelcomeMessage(User user); + String getWelcomeMessage(User user); } diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java index 16e7c5da7..8411339ef 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java @@ -6,13 +6,13 @@ import com.iluwatar.featuretoggle.user.UserGroup; public class TieredFeatureToggleVersion implements Service { - @Override - public String getWelcomeMessage(User user) { - if(UserGroup.isPaid(user)){ - return "You're amazing " + user.getName() + ". Thanks for paying for this awesome software."; - } - - return "I suppose you can use this software."; + @Override + public String getWelcomeMessage(User user) { + if (UserGroup.isPaid(user)) { + return "You're amazing " + user.getName() + ". Thanks for paying for this awesome software."; } + return "I suppose you can use this software."; + } + } diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java index a712e4f02..732d06c61 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java @@ -2,13 +2,13 @@ package com.iluwatar.featuretoggle.user; public class User { - private String name; + private String name; - public User(String name) { - this.name = name; - } + public User(String name) { + this.name = name; + } - public String getName() { - return name; - } + public String getName() { + return name; + } } diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java index 92b94f678..1328afbc8 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -3,32 +3,43 @@ package com.iluwatar.featuretoggle.user; import java.util.ArrayList; import java.util.List; +/** + * Contains the lists of users of different groups paid and free + */ public class UserGroup { - private static List<User> freeGroup = new ArrayList<>(); - private static List<User> paidGroup = new ArrayList<>(); + private static List<User> freeGroup = new ArrayList<>(); + private static List<User> paidGroup = new ArrayList<>(); - public static void addUserToFreeGroup(final User user){ - if(paidGroup.contains(user)){ - throw new IllegalArgumentException("User all ready member of paid group."); - }else{ - if(!freeGroup.contains(user)){ - freeGroup.add(user); - } - } + /** + * + * @param user {@link User} to be added to the free group + */ + public static void addUserToFreeGroup(final User user) { + if (paidGroup.contains(user)) { + throw new IllegalArgumentException("User all ready member of paid group."); + } else { + if (!freeGroup.contains(user)) { + freeGroup.add(user); + } } + } - public static void addUserToPaidGroup(final User user){ - if(freeGroup.contains(user)){ - throw new IllegalArgumentException("User all ready member of free group."); - }else{ - if(!paidGroup.contains(user)){ - paidGroup.add(user); - } - } + /** + * + * @param user {@link User} to be added to the paid group + */ + public static void addUserToPaidGroup(final User user) { + if (freeGroup.contains(user)) { + throw new IllegalArgumentException("User all ready member of free group."); + } else { + if (!paidGroup.contains(user)) { + paidGroup.add(user); + } } + } - public static boolean isPaid(User user) { - return paidGroup.contains(user); - } + public static boolean isPaid(User user) { + return paidGroup.contains(user); + } } diff --git a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java index 66b6bfc41..bf9487a2d 100644 --- a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java +++ b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java @@ -6,31 +6,31 @@ import com.iluwatar.featuretoggle.user.UserGroup; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class TieredFeatureToggleVersionTest { - final User paidUser = new User("Jamie Coder"); - final User freeUser = new User("Alan Defect"); - final Service service = new TieredFeatureToggleVersion(); + final User paidUser = new User("Jamie Coder"); + final User freeUser = new User("Alan Defect"); + final Service service = new TieredFeatureToggleVersion(); - @Before - public void setUp() throws Exception { - UserGroup.addUserToPaidGroup(paidUser); - UserGroup.addUserToFreeGroup(freeUser); - } + @Before + public void setUp() throws Exception { + UserGroup.addUserToPaidGroup(paidUser); + UserGroup.addUserToFreeGroup(freeUser); + } - @Test - public void testGetWelcomeMessageForPaidUser() throws Exception { - final String welcomeMessage = service.getWelcomeMessage(paidUser); - final String expected = "You're amazing Jamie Coder. Thanks for paying for this awesome software."; - assertEquals(expected,welcomeMessage); - } + @Test + public void testGetWelcomeMessageForPaidUser() throws Exception { + final String welcomeMessage = service.getWelcomeMessage(paidUser); + final String expected = "You're amazing Jamie Coder. Thanks for paying for this awesome software."; + assertEquals(expected, welcomeMessage); + } - @Test - public void testGetWelcomeMessageForFreeUser() throws Exception { - final String welcomeMessage = service.getWelcomeMessage(freeUser); - final String expected = "I suppose you can use this software."; - assertEquals(expected,welcomeMessage); - } + @Test + public void testGetWelcomeMessageForFreeUser() throws Exception { + final String welcomeMessage = service.getWelcomeMessage(freeUser); + final String expected = "I suppose you can use this software."; + assertEquals(expected, welcomeMessage); + } } \ No newline at end of file diff --git a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java index 372e58c19..0b3ca6ba4 100644 --- a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java +++ b/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java @@ -7,31 +7,31 @@ import static org.junit.Assert.assertTrue; public class UserGroupTest { - @Test - public void testAddUserToFreeGroup() throws Exception { - User user = new User("Free User"); - UserGroup.addUserToFreeGroup(user); - assertFalse(UserGroup.isPaid(user)); - } + @Test + public void testAddUserToFreeGroup() throws Exception { + User user = new User("Free User"); + UserGroup.addUserToFreeGroup(user); + assertFalse(UserGroup.isPaid(user)); + } - @Test - public void testAddUserToPaidGroup() throws Exception { - User user = new User("Paid User"); - UserGroup.addUserToPaidGroup(user); - assertTrue(UserGroup.isPaid(user)); - } + @Test + public void testAddUserToPaidGroup() throws Exception { + User user = new User("Paid User"); + UserGroup.addUserToPaidGroup(user); + assertTrue(UserGroup.isPaid(user)); + } - @Test(expected = IllegalArgumentException.class) - public void testAddUserToPaidWhenOnFree() throws Exception { - User user = new User("Paid User"); - UserGroup.addUserToFreeGroup(user); - UserGroup.addUserToPaidGroup(user); - } + @Test(expected = IllegalArgumentException.class) + public void testAddUserToPaidWhenOnFree() throws Exception { + User user = new User("Paid User"); + UserGroup.addUserToFreeGroup(user); + UserGroup.addUserToPaidGroup(user); + } - @Test(expected = IllegalArgumentException.class) - public void testAddUserToFreeWhenOnPaid() throws Exception { - User user = new User("Free User"); - UserGroup.addUserToPaidGroup(user); - UserGroup.addUserToFreeGroup(user); - } + @Test(expected = IllegalArgumentException.class) + public void testAddUserToFreeWhenOnPaid() throws Exception { + User user = new User("Free User"); + UserGroup.addUserToPaidGroup(user); + UserGroup.addUserToFreeGroup(user); + } } \ No newline at end of file From d627b7af6b5992bda71a3436c73f8b41f7e13ca2 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Tue, 26 Jan 2016 20:24:43 +0000 Subject: [PATCH 10/22] #354 Moved Tests to the correct area --- .../pattern/tieredversion/TieredFeatureToggleVersionTest.java | 0 .../java}/com/iluwatar/featuretoggle/user/UserGroupTest.java | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename feature-toggle/src/{main/test => test/java}/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java (100%) rename feature-toggle/src/{main/test => test/java}/com/iluwatar/featuretoggle/user/UserGroupTest.java (100%) diff --git a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java similarity index 100% rename from feature-toggle/src/main/test/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java rename to feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java diff --git a/feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/user/UserGroupTest.java similarity index 100% rename from feature-toggle/src/main/test/com/iluwatar/featuretoggle/user/UserGroupTest.java rename to feature-toggle/src/test/java/com/iluwatar/featuretoggle/user/UserGroupTest.java From ba1d3a0fbfbeb09be8c7fa79dcf37777bc6eca32 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Tue, 26 Jan 2016 21:08:28 +0000 Subject: [PATCH 11/22] #354 Added Configuration Based Example of Feature Toggle --- .../PropertiesFeatureToggleVersion.java | 27 ++++++++++++++++ .../TieredFeatureToggleVersion.java | 2 +- .../com/iluwatar/featuretoggle/user/User.java | 3 +- .../PropertiesFeatureToggleVersionTest.java | 31 +++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java create mode 100644 feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java new file mode 100644 index 000000000..bccf5bd6f --- /dev/null +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java @@ -0,0 +1,27 @@ +package com.iluwatar.featuretoggle.pattern.propertiesversion; + +import com.iluwatar.featuretoggle.pattern.Service; +import com.iluwatar.featuretoggle.user.User; + +import java.util.Properties; + +public class PropertiesFeatureToggleVersion implements Service { + + private Properties properties; + + public PropertiesFeatureToggleVersion(final Properties properties) { + this.properties = properties; + } + + @Override + public String getWelcomeMessage(final User user) { + + final boolean enhancedWelcome = (boolean) properties.get("enhancedWelcome"); + + if (enhancedWelcome) { + return "Welcome " + user + ". You're using the enhanced welcome message."; + } + + return "Welcome to the application."; + } +} diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java index 8411339ef..330015ac3 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java @@ -9,7 +9,7 @@ public class TieredFeatureToggleVersion implements Service { @Override public String getWelcomeMessage(User user) { if (UserGroup.isPaid(user)) { - return "You're amazing " + user.getName() + ". Thanks for paying for this awesome software."; + return "You're amazing " + user + ". Thanks for paying for this awesome software."; } return "I suppose you can use this software."; diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java index 732d06c61..12b4cc06e 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java @@ -8,7 +8,8 @@ public class User { this.name = name; } - public String getName() { + @Override + public String toString() { return name; } } diff --git a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java new file mode 100644 index 000000000..de10480c3 --- /dev/null +++ b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java @@ -0,0 +1,31 @@ + +package com.iluwatar.featuretoggle.pattern.propertiesversion; + +import com.iluwatar.featuretoggle.pattern.Service; +import com.iluwatar.featuretoggle.user.User; +import org.junit.Test; + +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +public class PropertiesFeatureToggleVersionTest { + + @Test + public void testFeatureTurnedOn() throws Exception { + final Properties properties = new Properties(); + properties.put("enhancedWelcome",true); + Service service = new PropertiesFeatureToggleVersion(properties); + final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); + assertEquals("Welcome Jamie No Code. You're using the enhanced welcome message.",welcomeMessage); + } + + @Test + public void testFeatureTurnedOff() throws Exception { + final Properties properties = new Properties(); + properties.put("enhancedWelcome",false); + Service service = new PropertiesFeatureToggleVersion(properties); + final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); + assertEquals("Welcome to the application.",welcomeMessage); + } +} \ No newline at end of file From 4a49f82f2366e9e39f7298a11e7e09de6e82401c Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Tue, 26 Jan 2016 21:18:47 +0000 Subject: [PATCH 12/22] #354 add general boolean method to services for feature status. Change user.toString --- .../featuretoggle/pattern/Service.java | 2 ++ .../PropertiesFeatureToggleVersion.java | 25 +++++++++++++++---- .../TieredFeatureToggleVersion.java | 5 ++++ .../PropertiesFeatureToggleVersionTest.java | 4 +++ .../TieredFeatureToggleVersionTest.java | 6 +++++ 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java index 843ee173f..c3849a45f 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java @@ -7,4 +7,6 @@ public interface Service { String getWelcomeMessage(User user); + boolean isEnhanced(); + } diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java index bccf5bd6f..aa795b975 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java @@ -7,21 +7,36 @@ import java.util.Properties; public class PropertiesFeatureToggleVersion implements Service { - private Properties properties; + private boolean isEnhanced; + /** + * + * @param properties {@link Properties} used to configure the service and toggle features. + */ public PropertiesFeatureToggleVersion(final Properties properties) { - this.properties = properties; + if (properties == null) { + throw new IllegalArgumentException("No Properties Provided."); + } else { + try { + isEnhanced = (boolean) properties.get("enhancedWelcome"); + } catch (Exception e) { + throw new IllegalArgumentException("Invalid Enhancement Settings Provided."); + } + } } @Override public String getWelcomeMessage(final User user) { - final boolean enhancedWelcome = (boolean) properties.get("enhancedWelcome"); - - if (enhancedWelcome) { + if (isEnhanced()) { return "Welcome " + user + ". You're using the enhanced welcome message."; } return "Welcome to the application."; } + + @Override + public boolean isEnhanced() { + return isEnhanced; + } } diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java index 330015ac3..2942618f1 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java @@ -15,4 +15,9 @@ public class TieredFeatureToggleVersion implements Service { return "I suppose you can use this software."; } + @Override + public boolean isEnhanced() { + return true; + } + } diff --git a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java index de10480c3..7a07193c8 100644 --- a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java +++ b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java @@ -8,6 +8,8 @@ import org.junit.Test; import java.util.Properties; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class PropertiesFeatureToggleVersionTest { @@ -16,6 +18,7 @@ public class PropertiesFeatureToggleVersionTest { final Properties properties = new Properties(); properties.put("enhancedWelcome",true); Service service = new PropertiesFeatureToggleVersion(properties); + assertTrue(service.isEnhanced()); final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); assertEquals("Welcome Jamie No Code. You're using the enhanced welcome message.",welcomeMessage); } @@ -25,6 +28,7 @@ public class PropertiesFeatureToggleVersionTest { final Properties properties = new Properties(); properties.put("enhancedWelcome",false); Service service = new PropertiesFeatureToggleVersion(properties); + assertFalse(service.isEnhanced()); final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); assertEquals("Welcome to the application.",welcomeMessage); } diff --git a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java index bf9487a2d..f96e99ba0 100644 --- a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java +++ b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java @@ -7,6 +7,7 @@ import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class TieredFeatureToggleVersionTest { @@ -33,4 +34,9 @@ public class TieredFeatureToggleVersionTest { final String expected = "I suppose you can use this software."; assertEquals(expected, welcomeMessage); } + + @Test + public void testIsEnhancedAlwaysTrueAsTiered() throws Exception { + assertTrue(service.isEnhanced()); + } } \ No newline at end of file From 77e14f00693114168853b62595144684ef87af07 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Tue, 26 Jan 2016 23:38:28 +0000 Subject: [PATCH 13/22] #354 Add tests for Properties --- .../com/iluwatar/featuretoggle/user/UserGroup.java | 1 + .../PropertiesFeatureToggleVersionTest.java | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java index 1328afbc8..d3052ac21 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -11,6 +11,7 @@ public class UserGroup { private static List<User> freeGroup = new ArrayList<>(); private static List<User> paidGroup = new ArrayList<>(); + /** * * @param user {@link User} to be added to the free group diff --git a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java index 7a07193c8..714eb5070 100644 --- a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java +++ b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java @@ -13,6 +13,18 @@ import static org.junit.Assert.assertTrue; public class PropertiesFeatureToggleVersionTest { + @Test(expected = IllegalArgumentException.class) + public void testNullPropertiesPassed() throws Exception { + new PropertiesFeatureToggleVersion(null); + } + + @Test(expected = IllegalArgumentException.class) + public void testNonBooleanProperty() throws Exception { + final Properties properties = new Properties(); + properties.setProperty("enhancedWelcome","Something"); + new PropertiesFeatureToggleVersion(properties); + } + @Test public void testFeatureTurnedOn() throws Exception { final Properties properties = new Properties(); From 98326a1e5e27d112f91949bcdfede5ecfda40704 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Thu, 28 Jan 2016 21:14:40 +0000 Subject: [PATCH 14/22] #354 Start Adding Java docs --- .../com/iluwatar/featuretoggle/user/User.java | 12 ++++++++++++ .../iluwatar/featuretoggle/user/UserGroup.java | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java index 12b4cc06e..70b241389 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java @@ -1,13 +1,25 @@ package com.iluwatar.featuretoggle.user; +/** + * Used to demonstrate the purpose of the feature toggle. This class actually has nothing to do with the pattern. + */ public class User { private String name; + /** + * Default Constructor setting the username. + * + * @param name {@link String} to represent the name of the user. + */ public User(String name) { this.name = name; } + /** + * {@inheritDoc} + * @return The {@link String} representation of the User, in this case just return the name of the user. + */ @Override public String toString() { return name; diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java index d3052ac21..fec972eb1 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -4,7 +4,10 @@ import java.util.ArrayList; import java.util.List; /** - * Contains the lists of users of different groups paid and free + * Contains the lists of users of different groups paid and free. Used to demonstrate the tiered example of feature + * toggle. Allowing certain features to be available to only certain groups of users. + * + * @see User */ public class UserGroup { @@ -13,10 +16,13 @@ public class UserGroup { /** + * Add the passed {@link User} to the free user group list. * * @param user {@link User} to be added to the free group + * @throws IllegalArgumentException + * @see User */ - public static void addUserToFreeGroup(final User user) { + public static void addUserToFreeGroup(final User user) throws IllegalArgumentException { if (paidGroup.contains(user)) { throw new IllegalArgumentException("User all ready member of paid group."); } else { @@ -27,10 +33,13 @@ public class UserGroup { } /** + * Add the passed {@link User} to the paid user group list. * * @param user {@link User} to be added to the paid group + * @throws IllegalArgumentException + * @see User */ - public static void addUserToPaidGroup(final User user) { + public static void addUserToPaidGroup(final User user) throws IllegalArgumentException { if (freeGroup.contains(user)) { throw new IllegalArgumentException("User all ready member of free group."); } else { From c2e750aca1fa5669a8eb7b354784b881ad7bd20c Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Sun, 31 Jan 2016 13:46:34 +0000 Subject: [PATCH 15/22] #354 finished method javadocs --- .../featuretoggle/pattern/Service.java | 22 ++++++++++++++- .../PropertiesFeatureToggleVersion.java | 27 +++++++++++++++++++ .../TieredFeatureToggleVersion.java | 21 +++++++++++++++ .../featuretoggle/user/UserGroup.java | 11 ++++++-- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java index c3849a45f..970780714 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java @@ -2,11 +2,31 @@ package com.iluwatar.featuretoggle.pattern; import com.iluwatar.featuretoggle.user.User; - +/** + * Simple interfaces to allow the calling of the method to generate the welcome message for a given user. While there is + * a helper method to gather the the status of the feature toggle. In some cases there is no need for the + * {@link Service#isEnhanced()} in {@link com.iluwatar.featuretoggle.pattern.tieredversion.TieredFeatureToggleVersion} + * where the toggle is determined by the actual {@link User}. + * + * @see com.iluwatar.featuretoggle.pattern.propertiesversion.PropertiesFeatureToggleVersion + * @see com.iluwatar.featuretoggle.pattern.tieredversion.TieredFeatureToggleVersion + * @see User + */ public interface Service { + /** + * Generates a welcome message for the passed user. + * + * @param user the {@link User} to be used if the message is to be personalised. + * @return Generated {@link String} welcome message + */ String getWelcomeMessage(User user); + /** + * Returns if the welcome message to be displayed will be the enhanced version. + * + * @return Boolean {@value true} if enhanced. + */ boolean isEnhanced(); } diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java index aa795b975..947efec6a 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java @@ -5,13 +5,21 @@ import com.iluwatar.featuretoggle.user.User; import java.util.Properties; +/** + * + */ public class PropertiesFeatureToggleVersion implements Service { private boolean isEnhanced; /** + * Creates an instance of {@link PropertiesFeatureToggleVersion} using the passed {@link Properties} to determine, + * the status of the feature toggle {@link PropertiesFeatureToggleVersion#isEnhanced()}. There is also some defensive + * code to ensure the {@link Properties} passed are as expected. * * @param properties {@link Properties} used to configure the service and toggle features. + * @throws IllegalArgumentException when the passed {@link Properties} is not as expected + * @see Properties */ public PropertiesFeatureToggleVersion(final Properties properties) { if (properties == null) { @@ -25,6 +33,18 @@ public class PropertiesFeatureToggleVersion implements Service { } } + /** + * Generate a welcome message based on the user being passed and the status of the feature toggle. If the enhanced + * version is enabled, then the message will be personalised with the name of the passed {@link User}. However if + * disabled then a generic version fo the message is returned. + * + * @param user the {@link User} to be displayed in the message if the enhanced version is enabled see + * {@link PropertiesFeatureToggleVersion#isEnhanced()}. If the enhanced version is enabled, then the + * message will be personalised with the name of the passed {@link User}. However if disabled then a + * generic version fo the message is returned. + * @return Resulting welcome message. + * @see User + */ @Override public String getWelcomeMessage(final User user) { @@ -35,6 +55,13 @@ public class PropertiesFeatureToggleVersion implements Service { return "Welcome to the application."; } + /** + * Method that checks if the welcome message to be returned is the enhanced venison or not. For this service it will + * see the value of the boolean that was set in the constructor + * {@link PropertiesFeatureToggleVersion#PropertiesFeatureToggleVersion(Properties)} + * + * @return Boolean value {@value true} if enhanced. + */ @Override public boolean isEnhanced() { return isEnhanced; diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java index 2942618f1..a011b7b61 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java @@ -4,8 +4,22 @@ import com.iluwatar.featuretoggle.pattern.Service; import com.iluwatar.featuretoggle.user.User; import com.iluwatar.featuretoggle.user.UserGroup; +/** + * + */ public class TieredFeatureToggleVersion implements Service { + /** + * Generates a welcome message from the passed {@link User}. The resulting message depends on the group of the + * {@link User}. So if the {@link User} is in the {@link UserGroup#paidGroup} then the enhanced version of the + * welcome message will be returned where the username is displayed. + * + * @param user the {@link User} to generate the welcome message for, different messages are displayed if the user is + * in the {@link UserGroup#isPaid(User)} or {@link UserGroup#freeGroup} + * @return Resulting welcome message. + * @see User + * @see UserGroup + */ @Override public String getWelcomeMessage(User user) { if (UserGroup.isPaid(user)) { @@ -15,6 +29,13 @@ public class TieredFeatureToggleVersion implements Service { return "I suppose you can use this software."; } + /** + * Method that checks if the welcome message to be returned is the enhanced version. For this instance as the logic + * is driven by the user group. This method is a little redundant. However can be used to show that there is an + * enhanced version available. + * + * @return Boolean value {@value true} if enhanced. + */ @Override public boolean isEnhanced() { return true; diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java index fec972eb1..2bdfcfdfc 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -19,7 +19,7 @@ public class UserGroup { * Add the passed {@link User} to the free user group list. * * @param user {@link User} to be added to the free group - * @throws IllegalArgumentException + * @throws IllegalArgumentException when user is already added to the paid group * @see User */ public static void addUserToFreeGroup(final User user) throws IllegalArgumentException { @@ -36,7 +36,7 @@ public class UserGroup { * Add the passed {@link User} to the paid user group list. * * @param user {@link User} to be added to the paid group - * @throws IllegalArgumentException + * @throws IllegalArgumentException when the user is already added to the free group * @see User */ public static void addUserToPaidGroup(final User user) throws IllegalArgumentException { @@ -49,6 +49,13 @@ public class UserGroup { } } + /** + * Method to take a {@link User} to determine if the user is in the {@link UserGroup#paidGroup}. + * + * @param user {@link User} to check if they are in the {@link UserGroup#paidGroup} + * + * @return true if the {@link User} is in {@link UserGroup#paidGroup} + */ public static boolean isPaid(User user) { return paidGroup.contains(user); } From 8603333e5d065207e8af68fe229e7252726e68e7 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Sun, 31 Jan 2016 14:10:34 +0000 Subject: [PATCH 16/22] #354 Adding Class Diagram --- feature-toggle/etc/feature-toggle.png | Bin 0 -> 55425 bytes feature-toggle/etc/feature-toggle.ucls | 111 +++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 feature-toggle/etc/feature-toggle.png create mode 100644 feature-toggle/etc/feature-toggle.ucls diff --git a/feature-toggle/etc/feature-toggle.png b/feature-toggle/etc/feature-toggle.png new file mode 100644 index 0000000000000000000000000000000000000000..5c118e57e44e86a22a426dcfa9aff8291dc246ac GIT binary patch literal 55425 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ⅈ_4h)^X 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 literal 0 HcmV?d00001 diff --git a/feature-toggle/etc/feature-toggle.ucls b/feature-toggle/etc/feature-toggle.ucls new file mode 100644 index 000000000..538d3f416 --- /dev/null +++ b/feature-toggle/etc/feature-toggle.ucls @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8"?> +<class-diagram version="1.1.9" icons="true" automaticImage="PNG" always-add-relationships="true" generalizations="true" + realizations="true" associations="true" dependencies="true" nesting-relationships="true" router="FAN"> + <interface id="1" language="java" name="com.iluwatar.featuretoggle.pattern.Service" project="feature-toggle" + file="/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java" binary="false" + corner="BOTTOM_RIGHT"> + <position height="-1" width="-1" x="238" y="187"/> + <display autosize="true" stereotype="true" package="true" initial-value="true" 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="2" language="java" + name="com.iluwatar.featuretoggle.pattern.propertiesversion.PropertiesFeatureToggleVersion" project="feature-toggle" + file="/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java" + binary="false" corner="BOTTOM_RIGHT"> + <position height="-1" width="-1" x="241" y="449"/> + <display autosize="true" stereotype="true" package="true" initial-value="true" 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.featuretoggle.pattern.tieredversion.TieredFeatureToggleVersion" + project="feature-toggle" + file="/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java" + binary="false" corner="BOTTOM_RIGHT"> + <position height="149" width="230" x="502" y="119"/> + <display autosize="false" stereotype="true" package="true" initial-value="true" 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.featuretoggle.user.User" project="feature-toggle" + file="/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java" binary="false" corner="BOTTOM_RIGHT"> + <position height="-1" width="-1" x="616" y="453"/> + <display autosize="true" stereotype="true" package="true" initial-value="true" 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.featuretoggle.user.UserGroup" project="feature-toggle" + file="/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java" binary="false" + corner="BOTTOM_RIGHT"> + <position height="-1" width="-1" x="956" y="187"/> + <display autosize="true" stereotype="true" package="true" initial-value="true" 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> + <dependency id="6"> + <end type="SOURCE" refId="1"/> + <end type="TARGET" refId="4"/> + </dependency> + <dependency id="7"> + <end type="SOURCE" refId="3"/> + <end type="TARGET" refId="5"/> + </dependency> + <association id="8"> + <bendpoint x="911" y="415"/> + <end type="SOURCE" refId="5" navigable="false"> + <attribute id="9" name="freeGroup"> + <position height="19" width="63" x="846" y="368"/> + </attribute> + <multiplicity id="10" minimum="0" maximum="2147483647"> + <position height="17" width="23" x="707" y="418"/> + </multiplicity> + </end> + <end type="TARGET" refId="4" navigable="true"/> + <display labels="true" multiplicity="true"/> + </association> + <realization id="11"> + <end type="SOURCE" refId="2"/> + <end type="TARGET" refId="1"/> + </realization> + <dependency id="12"> + <end type="SOURCE" refId="2"/> + <end type="TARGET" refId="4"/> + </dependency> + <dependency id="13"> + <end type="SOURCE" refId="3"/> + <end type="TARGET" refId="4"/> + </dependency> + <association id="14"> + <bendpoint x="953" y="459"/> + <end type="SOURCE" refId="5" navigable="false"> + <attribute id="15" name="paidGroup"> + <position height="19" width="66" x="963" y="419"/> + </attribute> + <multiplicity id="16" minimum="0" maximum="2147483647"> + <position height="17" width="23" x="711" y="463"/> + </multiplicity> + </end> + <end type="TARGET" refId="4" navigable="true"/> + <display labels="true" multiplicity="true"/> + </association> + <realization id="17"> + <end type="SOURCE" refId="3"/> + <end type="TARGET" refId="1"/> + </realization> + <classifier-display autosize="true" stereotype="true" package="true" initial-value="true" 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> \ No newline at end of file From bf5ba442608f720880b1bd635c5d8dd94f87369c Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Sun, 31 Jan 2016 23:24:35 +0000 Subject: [PATCH 17/22] #354 add App.java --- .../java/com/iluwatar/featuretoggle/App.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java new file mode 100644 index 000000000..74db991ba --- /dev/null +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java @@ -0,0 +1,65 @@ +/** + * 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. + */ + +package com.iluwatar.featuretoggle; + +import com.iluwatar.featuretoggle.pattern.Service; +import com.iluwatar.featuretoggle.pattern.propertiesversion.PropertiesFeatureToggleVersion; +import com.iluwatar.featuretoggle.user.User; +import com.iluwatar.featuretoggle.user.UserGroup; + +import java.util.Properties; + +/** + * + */ +public class App { + + /** + * + */ + public static void main(String[] args) { + final Properties properties = new Properties(); + properties.put("enhancedWelcome", true); + Service service = new PropertiesFeatureToggleVersion(properties); + final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); + System.out.println(welcomeMessage); + + final Properties turnedOff = new Properties(); + turnedOff.put("enhancedWelcome", false); + Service turnedOffService = new PropertiesFeatureToggleVersion(turnedOff); + final String welcomeMessageturnedOff = turnedOffService.getWelcomeMessage(new User("Jamie No Code")); + System.out.println(welcomeMessageturnedOff); + + final User paidUser = new User("Jamie Coder"); + final User freeUser = new User("Alan Defect"); + + UserGroup.addUserToPaidGroup(paidUser); + UserGroup.addUserToFreeGroup(freeUser); + + final String welcomeMessagePaidUser = service.getWelcomeMessage(paidUser); + final String welcomeMessageFreeUser = service.getWelcomeMessage(freeUser); + System.out.println(welcomeMessageFreeUser); + System.out.println(welcomeMessagePaidUser); + } +} From 37da470178e05a7461c50c433c292199c211dcd2 Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Mon, 1 Feb 2016 18:45:54 +0000 Subject: [PATCH 18/22] #354 Finish Readme --- feature-toggle/index.md | 32 +++++++++++++++++++ .../java/com/iluwatar/featuretoggle/App.java | 6 ++-- .../featuretoggle/pattern/Service.java | 6 ++-- .../PropertiesFeatureToggleVersion.java | 15 +++++++-- .../TieredFeatureToggleVersion.java | 15 +++++++-- .../com/iluwatar/featuretoggle/user/User.java | 6 ++-- .../featuretoggle/user/UserGroup.java | 6 ++-- .../PropertiesFeatureToggleVersionTest.java | 16 +++++----- .../TieredFeatureToggleVersionTest.java | 6 ++-- .../featuretoggle/user/UserGroupTest.java | 6 ++-- 10 files changed, 82 insertions(+), 32 deletions(-) diff --git a/feature-toggle/index.md b/feature-toggle/index.md index e69de29bb..51747ac09 100644 --- a/feature-toggle/index.md +++ b/feature-toggle/index.md @@ -0,0 +1,32 @@ +--- +layout: pattern +title: Feature Toggle +folder: feature-toggle +permalink: /patterns/feature-toggle/ +categories: Behavioral +tags: + - Java + - Difficulty-Beginner +--- + +## Also known as +Feature Flag + +## Intent +Used to switch code execution paths based on properties or groupings. Allowing new features to be released, tested +and rolled out. Allowing switching back to the older feature quickly if needed. It should be noted that this pattern, +can easily introduce code complexity. There is also cause for concern that the old feature that the toggle is eventually +going to phase out is never removed, causing redundant code smells and increased maintainability. + + + +## Applicability +Use the Feature Toogle pattern when + +* Giving different features to different users. +* Rolling out a new feature incrementally. +* Switching between development and production environments. + +## Credits + +* [Martin Fowler 29 October 2010 (2010-10-29).](http://martinfowler.com/bliki/FeatureToggle.html) \ No newline at end of file diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java index 74db991ba..71cdb3781 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java index 337fdc386..d2542b2b7 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/Service.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java index 7c4e8e3b0..761d7d39a 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersion.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 @@ -28,7 +28,16 @@ import com.iluwatar.featuretoggle.user.User; import java.util.Properties; /** + * This example of the Feature Toogle pattern is less dynamic version than + * {@link com.iluwatar.featuretoggle.pattern.tieredversion.TieredFeatureToggleVersion} where the feature is turned on + * or off at the time of creation of the service. This example uses simple Java {@link Properties} however it could as + * easily be done with an external configuration file loaded by Spring and so on. A good example of when to use this + * version of the feature toggle is when new features are being developed. So you could have a configuration property + * boolean named development or some sort of system environment variable. * + * @see Service + * @see com.iluwatar.featuretoggle.pattern.tieredversion.TieredFeatureToggleVersion + * @see User */ public class PropertiesFeatureToggleVersion implements Service { diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java index e62ea1a6e..124c9533f 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersion.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 @@ -27,7 +27,16 @@ import com.iluwatar.featuretoggle.user.User; import com.iluwatar.featuretoggle.user.UserGroup; /** + * This example of the Feature Toogle pattern shows how it could be implemented based on a {@link User}. Therefore + * showing its use within a tiered application where the paying users get access to different content or + * better versions of features. So in this instance a {@link User} is passed in and if they are found to be + * on the {@link UserGroup#isPaid(User)} they are welcomed with a personalised message. While the other is more + * generic. However this pattern is limited to simple examples such as the one below. * + * @see Service + * @see User + * @see com.iluwatar.featuretoggle.pattern.propertiesversion.PropertiesFeatureToggleVersion + * @see UserGroup */ public class TieredFeatureToggleVersion implements Service { diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java index b9882a711..ce7b54b7b 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/User.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java index 1fe556119..c9d9fd027 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/user/UserGroup.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 diff --git a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java index 61c20ba71..69afc9bb4 100644 --- a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java +++ b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/propertiesversion/PropertiesFeatureToggleVersionTest.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 @@ -43,27 +43,27 @@ public class PropertiesFeatureToggleVersionTest { @Test(expected = IllegalArgumentException.class) public void testNonBooleanProperty() throws Exception { final Properties properties = new Properties(); - properties.setProperty("enhancedWelcome","Something"); + properties.setProperty("enhancedWelcome", "Something"); new PropertiesFeatureToggleVersion(properties); } @Test public void testFeatureTurnedOn() throws Exception { final Properties properties = new Properties(); - properties.put("enhancedWelcome",true); + properties.put("enhancedWelcome", true); Service service = new PropertiesFeatureToggleVersion(properties); assertTrue(service.isEnhanced()); final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); - assertEquals("Welcome Jamie No Code. You're using the enhanced welcome message.",welcomeMessage); + assertEquals("Welcome Jamie No Code. You're using the enhanced welcome message.", welcomeMessage); } @Test public void testFeatureTurnedOff() throws Exception { final Properties properties = new Properties(); - properties.put("enhancedWelcome",false); + properties.put("enhancedWelcome", false); Service service = new PropertiesFeatureToggleVersion(properties); assertFalse(service.isEnhanced()); final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); - assertEquals("Welcome to the application.",welcomeMessage); + assertEquals("Welcome to the application.", welcomeMessage); } } \ No newline at end of file diff --git a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java index 04122160d..dca1d9b82 100644 --- a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java +++ b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/pattern/tieredversion/TieredFeatureToggleVersionTest.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 diff --git a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/user/UserGroupTest.java b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/user/UserGroupTest.java index 716060e6f..6659815d3 100644 --- a/feature-toggle/src/test/java/com/iluwatar/featuretoggle/user/UserGroupTest.java +++ b/feature-toggle/src/test/java/com/iluwatar/featuretoggle/user/UserGroupTest.java @@ -1,17 +1,17 @@ /** * The MIT License * Copyright (c) 2014 Ilkka Seppälä - * + * <p> * 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: - * + * <p> * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * <p> * 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 From c7f4311706c33a743aeb9a853d303877d3a2e68b Mon Sep 17 00:00:00 2001 From: Joseph McCarthy <luckymikuhatsune@gmail.com> Date: Mon, 1 Feb 2016 18:57:05 +0000 Subject: [PATCH 19/22] #354 Clean up --- .../java/com/iluwatar/featuretoggle/App.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java index 71cdb3781..debe99580 100644 --- a/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java +++ b/feature-toggle/src/main/java/com/iluwatar/featuretoggle/App.java @@ -31,26 +31,57 @@ import com.iluwatar.featuretoggle.user.UserGroup; import java.util.Properties; /** + * The Feature Toggle pattern allows for complete code executions to be turned on or off with ease. This allows features + * to be controlled by either dynamic methods just as {@link User} information or by {@link Properties}. In the App + * below there are two examples. Firstly the {@link Properties} version of the feature toggle, where the enhanced + * version of the welcome message which is personalised is turned either on or off at instance creation. This method + * is not as dynamic as the {@link User} driven version where the feature of the personalised welcome message is + * dependant on the {@link UserGroup} the {@link User} is in. So if the user is a memeber of the + * {@link UserGroup#isPaid(User)} then they get an ehanced version of the welcome message. + * + * Note that this pattern can easily introduce code complexity, and if not kept in check can result in redundant + * unmaintained code within the codebase. * */ public class App { /** + * Block 1 shows the {@link PropertiesFeatureToggleVersion} being run with {@link Properties} setting the feature + * toggle to enabled. * + * Block 2 shows the {@link PropertiesFeatureToggleVersion} being run with {@link Properties} setting the feature + * toggle to disabled. Notice the difference with the printed welcome message the username is not included. + * + * Block 3 shows the {@link com.iluwatar.featuretoggle.pattern.tieredversion.TieredFeatureToggleVersion} being + * set up with two users on who is on the free level, while the other is on the paid level. When the + * {@link Service#getWelcomeMessage(User)} is called with the paid {@link User} note that the welcome message + * contains their username, while the same service call with the free tier user is more generic. No username is + * printed. + * + * @see User + * @see UserGroup + * @see Service + * @see PropertiesFeatureToggleVersion + * @see com.iluwatar.featuretoggle.pattern.tieredversion.TieredFeatureToggleVersion; */ public static void main(String[] args) { + final Properties properties = new Properties(); properties.put("enhancedWelcome", true); Service service = new PropertiesFeatureToggleVersion(properties); final String welcomeMessage = service.getWelcomeMessage(new User("Jamie No Code")); System.out.println(welcomeMessage); + // --------------------------------------------- + final Properties turnedOff = new Properties(); turnedOff.put("enhancedWelcome", false); Service turnedOffService = new PropertiesFeatureToggleVersion(turnedOff); final String welcomeMessageturnedOff = turnedOffService.getWelcomeMessage(new User("Jamie No Code")); System.out.println(welcomeMessageturnedOff); + // -------------------------------------------- + final User paidUser = new User("Jamie Coder"); final User freeUser = new User("Alan Defect"); From 6caea8557bb76518d2356b7e1a82901cc76131c8 Mon Sep 17 00:00:00 2001 From: Markus Moser <markusmo3@zoho.com> Date: Tue, 2 Feb 2016 17:31:12 +0100 Subject: [PATCH 20/22] added missing space, 'cause website didnt display correctly --- execute-around/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/execute-around/index.md b/execute-around/index.md index 784a02b15..f669f18ff 100644 --- a/execute-around/index.md +++ b/execute-around/index.md @@ -23,5 +23,5 @@ Use the Execute Around idiom when * you use an API that requires methods to be called in pairs such as open/close or allocate/deallocate. -##Credits +## Credits * [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](http://www.amazon.com/Functional-Programming-Java-Harnessing-Expressions/dp/1937785467/ref=sr_1_1) From 4f56f7b0976ad1eff2acc0dbd4117a5bed661da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= <iluwatar@gmail.com> Date: Tue, 2 Feb 2016 22:11:38 +0200 Subject: [PATCH 21/22] Achieved milestone 1.10.0 --- abstract-factory/pom.xml | 2 +- adapter/pom.xml | 2 +- async-method-invocation/pom.xml | 2 +- bridge/pom.xml | 2 +- builder/pom.xml | 2 +- business-delegate/pom.xml | 2 +- caching/pom.xml | 2 +- callback/pom.xml | 2 +- chain/pom.xml | 2 +- command/pom.xml | 2 +- composite/pom.xml | 2 +- dao/pom.xml | 2 +- decorator/pom.xml | 2 +- delegation/pom.xml | 2 +- dependency-injection/pom.xml | 2 +- double-checked-locking/pom.xml | 2 +- double-dispatch/pom.xml | 2 +- event-aggregator/pom.xml | 2 +- event-driven-architecture/pom.xml | 2 +- execute-around/pom.xml | 2 +- facade/pom.xml | 2 +- factory-method/pom.xml | 2 +- feature-toggle/pom.xml | 2 +- fluentinterface/pom.xml | 2 +- flux/pom.xml | 2 +- flyweight/pom.xml | 2 +- front-controller/pom.xml | 2 +- half-sync-half-async/pom.xml | 2 +- intercepting-filter/pom.xml | 2 +- interpreter/pom.xml | 2 +- iterator/pom.xml | 2 +- layers/pom.xml | 2 +- lazy-loading/pom.xml | 2 +- mediator/pom.xml | 2 +- memento/pom.xml | 2 +- message-channel/pom.xml | 2 +- model-view-controller/pom.xml | 2 +- model-view-presenter/pom.xml | 2 +- monostate/pom.xml | 2 +- multiton/pom.xml | 2 +- naked-objects/dom/pom.xml | 2 +- naked-objects/fixture/pom.xml | 2 +- naked-objects/integtests/pom.xml | 2 +- naked-objects/pom.xml | 8 ++++---- naked-objects/webapp/pom.xml | 2 +- null-object/pom.xml | 2 +- object-pool/pom.xml | 2 +- observer/pom.xml | 2 +- poison-pill/pom.xml | 2 +- pom.xml | 2 +- private-class-data/pom.xml | 2 +- producer-consumer/pom.xml | 2 +- property/pom.xml | 2 +- prototype/pom.xml | 2 +- proxy/pom.xml | 2 +- publish-subscribe/pom.xml | 2 +- reactor/pom.xml | 2 +- reader-writer-lock/pom.xml | 2 +- repository/pom.xml | 2 +- resource-acquisition-is-initialization/pom.xml | 2 +- servant/pom.xml | 2 +- service-layer/pom.xml | 2 +- service-locator/pom.xml | 2 +- singleton/pom.xml | 2 +- specification/pom.xml | 2 +- state/pom.xml | 2 +- step-builder/pom.xml | 2 +- strategy/pom.xml | 2 +- template-method/pom.xml | 2 +- thread-pool/pom.xml | 2 +- tolerant-reader/pom.xml | 2 +- twin/pom.xml | 2 +- visitor/pom.xml | 2 +- 73 files changed, 76 insertions(+), 76 deletions(-) diff --git a/abstract-factory/pom.xml b/abstract-factory/pom.xml index 00118f62c..feedab5c7 100644 --- a/abstract-factory/pom.xml +++ b/abstract-factory/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>abstract-factory</artifactId> <dependencies> diff --git a/adapter/pom.xml b/adapter/pom.xml index fc5fdff23..5b34dd1db 100644 --- a/adapter/pom.xml +++ b/adapter/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>adapter</artifactId> <dependencies> diff --git a/async-method-invocation/pom.xml b/async-method-invocation/pom.xml index 815b347da..dd57da865 100644 --- a/async-method-invocation/pom.xml +++ b/async-method-invocation/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>async-method-invocation</artifactId> <dependencies> diff --git a/bridge/pom.xml b/bridge/pom.xml index eee2e1c6c..457afcdeb 100644 --- a/bridge/pom.xml +++ b/bridge/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>bridge</artifactId> <dependencies> diff --git a/builder/pom.xml b/builder/pom.xml index c099818ce..a20843a07 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>builder</artifactId> <dependencies> diff --git a/business-delegate/pom.xml b/business-delegate/pom.xml index 933518ec0..e6c58f488 100644 --- a/business-delegate/pom.xml +++ b/business-delegate/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>business-delegate</artifactId> <dependencies> diff --git a/caching/pom.xml b/caching/pom.xml index 969ca7d40..80e151bb5 100644 --- a/caching/pom.xml +++ b/caching/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>caching</artifactId> <dependencies> diff --git a/callback/pom.xml b/callback/pom.xml index 2c63059e4..7a5da0f92 100644 --- a/callback/pom.xml +++ b/callback/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>callback</artifactId> <dependencies> diff --git a/chain/pom.xml b/chain/pom.xml index 007a1a224..1962e6f01 100644 --- a/chain/pom.xml +++ b/chain/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>chain</artifactId> <dependencies> diff --git a/command/pom.xml b/command/pom.xml index 2ee281cee..43ac2d73e 100644 --- a/command/pom.xml +++ b/command/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>command</artifactId> <dependencies> diff --git a/composite/pom.xml b/composite/pom.xml index 3c35d1eda..a2573c962 100644 --- a/composite/pom.xml +++ b/composite/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>composite</artifactId> <dependencies> diff --git a/dao/pom.xml b/dao/pom.xml index 422134ec8..4d54c4df1 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>dao</artifactId> diff --git a/decorator/pom.xml b/decorator/pom.xml index e98842da3..4ed52ab54 100644 --- a/decorator/pom.xml +++ b/decorator/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>decorator</artifactId> <dependencies> diff --git a/delegation/pom.xml b/delegation/pom.xml index 62726d4ad..79ab70fca 100644 --- a/delegation/pom.xml +++ b/delegation/pom.xml @@ -30,7 +30,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml index a5ce41ef5..643d1c599 100644 --- a/dependency-injection/pom.xml +++ b/dependency-injection/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>dependency-injection</artifactId> <dependencies> diff --git a/double-checked-locking/pom.xml b/double-checked-locking/pom.xml index e5985a84e..6801bec6e 100644 --- a/double-checked-locking/pom.xml +++ b/double-checked-locking/pom.xml @@ -27,7 +27,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>double-checked-locking</artifactId> <dependencies> diff --git a/double-dispatch/pom.xml b/double-dispatch/pom.xml index 57da13a09..a73c20b01 100644 --- a/double-dispatch/pom.xml +++ b/double-dispatch/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>double-dispatch</artifactId> <dependencies> diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml index d773abf0d..1a951bb4c 100644 --- a/event-aggregator/pom.xml +++ b/event-aggregator/pom.xml @@ -28,7 +28,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>event-aggregator</artifactId> <dependencies> diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index 0a77eec8e..cf1e18695 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -31,7 +31,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>event-driven-architecture</artifactId> diff --git a/execute-around/pom.xml b/execute-around/pom.xml index 569747ff2..38900b888 100644 --- a/execute-around/pom.xml +++ b/execute-around/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>execute-around</artifactId> <dependencies> diff --git a/facade/pom.xml b/facade/pom.xml index e4440b234..fba6d6294 100644 --- a/facade/pom.xml +++ b/facade/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>facade</artifactId> <dependencies> diff --git a/factory-method/pom.xml b/factory-method/pom.xml index e7a56518f..fa9a3540d 100644 --- a/factory-method/pom.xml +++ b/factory-method/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>factory-method</artifactId> <dependencies> diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index 06271524c..cfbe417ac 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -30,7 +30,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml index 9912139f9..9997f29af 100644 --- a/fluentinterface/pom.xml +++ b/fluentinterface/pom.xml @@ -29,7 +29,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/flux/pom.xml b/flux/pom.xml index e35868c3e..f0159daa0 100644 --- a/flux/pom.xml +++ b/flux/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>flux</artifactId> <dependencies> diff --git a/flyweight/pom.xml b/flyweight/pom.xml index 341d03c7c..38573d5c5 100644 --- a/flyweight/pom.xml +++ b/flyweight/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>flyweight</artifactId> <dependencies> diff --git a/front-controller/pom.xml b/front-controller/pom.xml index 44aed6265..463812be0 100644 --- a/front-controller/pom.xml +++ b/front-controller/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>front-controller</artifactId> <dependencies> diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml index 487afc3a0..66a8d379d 100644 --- a/half-sync-half-async/pom.xml +++ b/half-sync-half-async/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>half-sync-half-async</artifactId> <dependencies> diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index 6758d81aa..8bf58e611 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>intercepting-filter</artifactId> <dependencies> diff --git a/interpreter/pom.xml b/interpreter/pom.xml index 91efe5033..65b831e74 100644 --- a/interpreter/pom.xml +++ b/interpreter/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>interpreter</artifactId> <dependencies> diff --git a/iterator/pom.xml b/iterator/pom.xml index abc18311c..d241ab91e 100644 --- a/iterator/pom.xml +++ b/iterator/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>iterator</artifactId> <dependencies> diff --git a/layers/pom.xml b/layers/pom.xml index 3ac0156c0..d154904e4 100644 --- a/layers/pom.xml +++ b/layers/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <groupId>com.iluwatar.layers</groupId> <artifactId>layers</artifactId> diff --git a/lazy-loading/pom.xml b/lazy-loading/pom.xml index bbdf88995..c52c0a9dc 100644 --- a/lazy-loading/pom.xml +++ b/lazy-loading/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>lazy-loading</artifactId> <dependencies> diff --git a/mediator/pom.xml b/mediator/pom.xml index f7d1a5fd4..7429b667f 100644 --- a/mediator/pom.xml +++ b/mediator/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>mediator</artifactId> <dependencies> diff --git a/memento/pom.xml b/memento/pom.xml index 22a67c5d9..6741d287c 100644 --- a/memento/pom.xml +++ b/memento/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>memento</artifactId> <dependencies> diff --git a/message-channel/pom.xml b/message-channel/pom.xml index e8b0ca567..0edb6d075 100644 --- a/message-channel/pom.xml +++ b/message-channel/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>message-channel</artifactId> <dependencies> diff --git a/model-view-controller/pom.xml b/model-view-controller/pom.xml index eaf9f210d..e02b1e34b 100644 --- a/model-view-controller/pom.xml +++ b/model-view-controller/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>model-view-controller</artifactId> <dependencies> diff --git a/model-view-presenter/pom.xml b/model-view-presenter/pom.xml index 343a39f57..286511382 100644 --- a/model-view-presenter/pom.xml +++ b/model-view-presenter/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>model-view-presenter</artifactId> <name>model-view-presenter</name> diff --git a/monostate/pom.xml b/monostate/pom.xml index 61598db4f..838b00276 100644 --- a/monostate/pom.xml +++ b/monostate/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>monostate</artifactId> <dependencies> diff --git a/multiton/pom.xml b/multiton/pom.xml index 22bd12861..69df8b94d 100644 --- a/multiton/pom.xml +++ b/multiton/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>multiton</artifactId> <dependencies> diff --git a/naked-objects/dom/pom.xml b/naked-objects/dom/pom.xml index 24a054c67..626f84b54 100644 --- a/naked-objects/dom/pom.xml +++ b/naked-objects/dom/pom.xml @@ -16,7 +16,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>naked-objects</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>naked-objects-dom</artifactId> diff --git a/naked-objects/fixture/pom.xml b/naked-objects/fixture/pom.xml index 2cc097e92..9ec93892b 100644 --- a/naked-objects/fixture/pom.xml +++ b/naked-objects/fixture/pom.xml @@ -16,7 +16,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>naked-objects</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>naked-objects-fixture</artifactId> diff --git a/naked-objects/integtests/pom.xml b/naked-objects/integtests/pom.xml index d5fb3c581..e460cb113 100644 --- a/naked-objects/integtests/pom.xml +++ b/naked-objects/integtests/pom.xml @@ -16,7 +16,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>naked-objects</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>naked-objects-integtests</artifactId> diff --git a/naked-objects/pom.xml b/naked-objects/pom.xml index c5b188098..ea51dee3b 100644 --- a/naked-objects/pom.xml +++ b/naked-objects/pom.xml @@ -15,7 +15,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>naked-objects</artifactId> @@ -350,17 +350,17 @@ <dependency> <groupId>${project.groupId}</groupId> <artifactId>naked-objects-dom</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>naked-objects-fixture</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>naked-objects-webapp</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </dependency> </dependencies> diff --git a/naked-objects/webapp/pom.xml b/naked-objects/webapp/pom.xml index ad43bf91f..4d1f62afd 100644 --- a/naked-objects/webapp/pom.xml +++ b/naked-objects/webapp/pom.xml @@ -16,7 +16,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>naked-objects</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>naked-objects-webapp</artifactId> diff --git a/null-object/pom.xml b/null-object/pom.xml index 204b874fd..a95f5ff90 100644 --- a/null-object/pom.xml +++ b/null-object/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>null-object</artifactId> <dependencies> diff --git a/object-pool/pom.xml b/object-pool/pom.xml index c681d957d..7b089170c 100644 --- a/object-pool/pom.xml +++ b/object-pool/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>object-pool</artifactId> <dependencies> diff --git a/observer/pom.xml b/observer/pom.xml index 682125cdc..dc0a7a3ff 100644 --- a/observer/pom.xml +++ b/observer/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>observer</artifactId> <dependencies> diff --git a/poison-pill/pom.xml b/poison-pill/pom.xml index 85f030036..93fbd0c96 100644 --- a/poison-pill/pom.xml +++ b/poison-pill/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>poison-pill</artifactId> <dependencies> diff --git a/pom.xml b/pom.xml index 077d3c95e..7e35567e0 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> <packaging>pom</packaging> <inceptionYear>2014</inceptionYear> diff --git a/private-class-data/pom.xml b/private-class-data/pom.xml index c3f536abb..a5b115edc 100644 --- a/private-class-data/pom.xml +++ b/private-class-data/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>private-class-data</artifactId> <dependencies> diff --git a/producer-consumer/pom.xml b/producer-consumer/pom.xml index 90e323241..b970b2a4f 100644 --- a/producer-consumer/pom.xml +++ b/producer-consumer/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>producer-consumer</artifactId> <dependencies> diff --git a/property/pom.xml b/property/pom.xml index 6906bee68..454f20323 100644 --- a/property/pom.xml +++ b/property/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>property</artifactId> <dependencies> diff --git a/prototype/pom.xml b/prototype/pom.xml index 1cc5d9599..80fcd0738 100644 --- a/prototype/pom.xml +++ b/prototype/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>prototype</artifactId> <dependencies> diff --git a/proxy/pom.xml b/proxy/pom.xml index 890f95b5c..5a86b4e30 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>proxy</artifactId> <dependencies> diff --git a/publish-subscribe/pom.xml b/publish-subscribe/pom.xml index ae90fdbf1..8afaa3b53 100644 --- a/publish-subscribe/pom.xml +++ b/publish-subscribe/pom.xml @@ -28,7 +28,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>publish-subscribe</artifactId> <dependencies> diff --git a/reactor/pom.xml b/reactor/pom.xml index b22d9669d..5dd39d824 100644 --- a/reactor/pom.xml +++ b/reactor/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>reactor</artifactId> <dependencies> diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml index e5eae25a2..d95daa4cb 100644 --- a/reader-writer-lock/pom.xml +++ b/reader-writer-lock/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>reader-writer-lock</artifactId> <dependencies> diff --git a/repository/pom.xml b/repository/pom.xml index 4b89917fe..79d8f5897 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>repository</artifactId> <dependencies> diff --git a/resource-acquisition-is-initialization/pom.xml b/resource-acquisition-is-initialization/pom.xml index f183d16a1..17ec6e217 100644 --- a/resource-acquisition-is-initialization/pom.xml +++ b/resource-acquisition-is-initialization/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>resource-acquisition-is-initialization</artifactId> <dependencies> diff --git a/servant/pom.xml b/servant/pom.xml index bc5f6a61c..6d92991ab 100644 --- a/servant/pom.xml +++ b/servant/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>servant</artifactId> <dependencies> diff --git a/service-layer/pom.xml b/service-layer/pom.xml index b480a75b8..1c12694b2 100644 --- a/service-layer/pom.xml +++ b/service-layer/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>service-layer</artifactId> <dependencies> diff --git a/service-locator/pom.xml b/service-locator/pom.xml index 8d388ccc8..78ed58a26 100644 --- a/service-locator/pom.xml +++ b/service-locator/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>service-locator</artifactId> <dependencies> diff --git a/singleton/pom.xml b/singleton/pom.xml index 2375fe70f..d18ed2190 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>singleton</artifactId> <dependencies> diff --git a/specification/pom.xml b/specification/pom.xml index cb7b046ae..8ad3ff3e9 100644 --- a/specification/pom.xml +++ b/specification/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>specification</artifactId> <dependencies> diff --git a/state/pom.xml b/state/pom.xml index ecf41e038..590eda4b0 100644 --- a/state/pom.xml +++ b/state/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>state</artifactId> <dependencies> diff --git a/step-builder/pom.xml b/step-builder/pom.xml index 2123f0758..30bbdfad5 100644 --- a/step-builder/pom.xml +++ b/step-builder/pom.xml @@ -30,7 +30,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>step-builder</artifactId> <dependencies> diff --git a/strategy/pom.xml b/strategy/pom.xml index 9b09ede1a..703d0c307 100644 --- a/strategy/pom.xml +++ b/strategy/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>strategy</artifactId> <dependencies> diff --git a/template-method/pom.xml b/template-method/pom.xml index f734cfd35..7d3cbbfaa 100644 --- a/template-method/pom.xml +++ b/template-method/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>template-method</artifactId> <dependencies> diff --git a/thread-pool/pom.xml b/thread-pool/pom.xml index 7eeae44e2..7e50843ac 100644 --- a/thread-pool/pom.xml +++ b/thread-pool/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>thread-pool</artifactId> <dependencies> diff --git a/tolerant-reader/pom.xml b/tolerant-reader/pom.xml index c6b980fb3..e0ce85e9f 100644 --- a/tolerant-reader/pom.xml +++ b/tolerant-reader/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>tolerant-reader</artifactId> <dependencies> diff --git a/twin/pom.xml b/twin/pom.xml index 6c5ac7473..b4bac4e29 100644 --- a/twin/pom.xml +++ b/twin/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>twin</artifactId> <dependencies> diff --git a/visitor/pom.xml b/visitor/pom.xml index d46a7e0f7..992c82c04 100644 --- a/visitor/pom.xml +++ b/visitor/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0-SNAPSHOT</version> + <version>1.10.0</version> </parent> <artifactId>visitor</artifactId> <dependencies> From 33224dd7d7b6d4d3a0845ba8f9ecdf5d699ca2e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= <iluwatar@gmail.com> Date: Tue, 2 Feb 2016 22:14:20 +0200 Subject: [PATCH 22/22] Prepare for next development iteration --- abstract-factory/pom.xml | 2 +- adapter/pom.xml | 2 +- async-method-invocation/pom.xml | 2 +- bridge/pom.xml | 2 +- builder/pom.xml | 2 +- business-delegate/pom.xml | 2 +- caching/pom.xml | 2 +- callback/pom.xml | 2 +- chain/pom.xml | 2 +- command/pom.xml | 2 +- composite/pom.xml | 2 +- dao/pom.xml | 2 +- decorator/pom.xml | 2 +- delegation/pom.xml | 2 +- dependency-injection/pom.xml | 2 +- double-checked-locking/pom.xml | 2 +- double-dispatch/pom.xml | 2 +- event-aggregator/pom.xml | 2 +- event-driven-architecture/pom.xml | 2 +- execute-around/pom.xml | 2 +- facade/pom.xml | 2 +- factory-method/pom.xml | 2 +- feature-toggle/pom.xml | 2 +- fluentinterface/pom.xml | 2 +- flux/pom.xml | 2 +- flyweight/pom.xml | 2 +- front-controller/pom.xml | 2 +- half-sync-half-async/pom.xml | 2 +- intercepting-filter/pom.xml | 2 +- interpreter/pom.xml | 2 +- iterator/pom.xml | 2 +- layers/pom.xml | 2 +- lazy-loading/pom.xml | 2 +- mediator/pom.xml | 2 +- memento/pom.xml | 2 +- message-channel/pom.xml | 2 +- model-view-controller/pom.xml | 2 +- model-view-presenter/pom.xml | 2 +- monostate/pom.xml | 2 +- multiton/pom.xml | 2 +- naked-objects/dom/pom.xml | 2 +- naked-objects/fixture/pom.xml | 2 +- naked-objects/integtests/pom.xml | 2 +- naked-objects/pom.xml | 8 ++++---- naked-objects/webapp/pom.xml | 2 +- null-object/pom.xml | 2 +- object-pool/pom.xml | 2 +- observer/pom.xml | 2 +- poison-pill/pom.xml | 2 +- pom.xml | 2 +- private-class-data/pom.xml | 2 +- producer-consumer/pom.xml | 2 +- property/pom.xml | 2 +- prototype/pom.xml | 2 +- proxy/pom.xml | 2 +- publish-subscribe/pom.xml | 2 +- reactor/pom.xml | 2 +- reader-writer-lock/pom.xml | 2 +- repository/pom.xml | 2 +- resource-acquisition-is-initialization/pom.xml | 2 +- servant/pom.xml | 2 +- service-layer/pom.xml | 2 +- service-locator/pom.xml | 2 +- singleton/pom.xml | 2 +- specification/pom.xml | 2 +- state/pom.xml | 2 +- step-builder/pom.xml | 2 +- strategy/pom.xml | 2 +- template-method/pom.xml | 2 +- thread-pool/pom.xml | 2 +- tolerant-reader/pom.xml | 2 +- twin/pom.xml | 2 +- visitor/pom.xml | 2 +- 73 files changed, 76 insertions(+), 76 deletions(-) diff --git a/abstract-factory/pom.xml b/abstract-factory/pom.xml index feedab5c7..32171a5f2 100644 --- a/abstract-factory/pom.xml +++ b/abstract-factory/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>abstract-factory</artifactId> <dependencies> diff --git a/adapter/pom.xml b/adapter/pom.xml index 5b34dd1db..3c231d60a 100644 --- a/adapter/pom.xml +++ b/adapter/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>adapter</artifactId> <dependencies> diff --git a/async-method-invocation/pom.xml b/async-method-invocation/pom.xml index dd57da865..d640b890e 100644 --- a/async-method-invocation/pom.xml +++ b/async-method-invocation/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>async-method-invocation</artifactId> <dependencies> diff --git a/bridge/pom.xml b/bridge/pom.xml index 457afcdeb..ba474af55 100644 --- a/bridge/pom.xml +++ b/bridge/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>bridge</artifactId> <dependencies> diff --git a/builder/pom.xml b/builder/pom.xml index a20843a07..66f679cc6 100644 --- a/builder/pom.xml +++ b/builder/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>builder</artifactId> <dependencies> diff --git a/business-delegate/pom.xml b/business-delegate/pom.xml index e6c58f488..920672062 100644 --- a/business-delegate/pom.xml +++ b/business-delegate/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>business-delegate</artifactId> <dependencies> diff --git a/caching/pom.xml b/caching/pom.xml index 80e151bb5..1dad83d0e 100644 --- a/caching/pom.xml +++ b/caching/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>caching</artifactId> <dependencies> diff --git a/callback/pom.xml b/callback/pom.xml index 7a5da0f92..55b1abbc5 100644 --- a/callback/pom.xml +++ b/callback/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>callback</artifactId> <dependencies> diff --git a/chain/pom.xml b/chain/pom.xml index 1962e6f01..4a0c5a96a 100644 --- a/chain/pom.xml +++ b/chain/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>chain</artifactId> <dependencies> diff --git a/command/pom.xml b/command/pom.xml index 43ac2d73e..69c499371 100644 --- a/command/pom.xml +++ b/command/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>command</artifactId> <dependencies> diff --git a/composite/pom.xml b/composite/pom.xml index a2573c962..551dc1f2d 100644 --- a/composite/pom.xml +++ b/composite/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>composite</artifactId> <dependencies> diff --git a/dao/pom.xml b/dao/pom.xml index 4d54c4df1..3b6fc7d1e 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>dao</artifactId> diff --git a/decorator/pom.xml b/decorator/pom.xml index 4ed52ab54..d8f253bd2 100644 --- a/decorator/pom.xml +++ b/decorator/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>decorator</artifactId> <dependencies> diff --git a/delegation/pom.xml b/delegation/pom.xml index 79ab70fca..1cfb3e4e3 100644 --- a/delegation/pom.xml +++ b/delegation/pom.xml @@ -30,7 +30,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/dependency-injection/pom.xml b/dependency-injection/pom.xml index 643d1c599..cb210ca5a 100644 --- a/dependency-injection/pom.xml +++ b/dependency-injection/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>dependency-injection</artifactId> <dependencies> diff --git a/double-checked-locking/pom.xml b/double-checked-locking/pom.xml index 6801bec6e..e3b4c5bff 100644 --- a/double-checked-locking/pom.xml +++ b/double-checked-locking/pom.xml @@ -27,7 +27,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>double-checked-locking</artifactId> <dependencies> diff --git a/double-dispatch/pom.xml b/double-dispatch/pom.xml index a73c20b01..8414a6aa1 100644 --- a/double-dispatch/pom.xml +++ b/double-dispatch/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>double-dispatch</artifactId> <dependencies> diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml index 1a951bb4c..6627bdb1a 100644 --- a/event-aggregator/pom.xml +++ b/event-aggregator/pom.xml @@ -28,7 +28,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>event-aggregator</artifactId> <dependencies> diff --git a/event-driven-architecture/pom.xml b/event-driven-architecture/pom.xml index cf1e18695..b0b588c6b 100644 --- a/event-driven-architecture/pom.xml +++ b/event-driven-architecture/pom.xml @@ -31,7 +31,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>event-driven-architecture</artifactId> diff --git a/execute-around/pom.xml b/execute-around/pom.xml index 38900b888..a8654ac77 100644 --- a/execute-around/pom.xml +++ b/execute-around/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>execute-around</artifactId> <dependencies> diff --git a/facade/pom.xml b/facade/pom.xml index fba6d6294..daa3853cd 100644 --- a/facade/pom.xml +++ b/facade/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>facade</artifactId> <dependencies> diff --git a/factory-method/pom.xml b/factory-method/pom.xml index fa9a3540d..25ca9f726 100644 --- a/factory-method/pom.xml +++ b/factory-method/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>factory-method</artifactId> <dependencies> diff --git a/feature-toggle/pom.xml b/feature-toggle/pom.xml index cfbe417ac..5f732f5a3 100644 --- a/feature-toggle/pom.xml +++ b/feature-toggle/pom.xml @@ -30,7 +30,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml index 9997f29af..5faf359d1 100644 --- a/fluentinterface/pom.xml +++ b/fluentinterface/pom.xml @@ -29,7 +29,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/flux/pom.xml b/flux/pom.xml index f0159daa0..25182d784 100644 --- a/flux/pom.xml +++ b/flux/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>flux</artifactId> <dependencies> diff --git a/flyweight/pom.xml b/flyweight/pom.xml index 38573d5c5..a066c8924 100644 --- a/flyweight/pom.xml +++ b/flyweight/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>flyweight</artifactId> <dependencies> diff --git a/front-controller/pom.xml b/front-controller/pom.xml index 463812be0..8cb7ddc6d 100644 --- a/front-controller/pom.xml +++ b/front-controller/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>front-controller</artifactId> <dependencies> diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml index 66a8d379d..357cabf4b 100644 --- a/half-sync-half-async/pom.xml +++ b/half-sync-half-async/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>half-sync-half-async</artifactId> <dependencies> diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index 8bf58e611..0ff3be16b 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>intercepting-filter</artifactId> <dependencies> diff --git a/interpreter/pom.xml b/interpreter/pom.xml index 65b831e74..3a09ae310 100644 --- a/interpreter/pom.xml +++ b/interpreter/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>interpreter</artifactId> <dependencies> diff --git a/iterator/pom.xml b/iterator/pom.xml index d241ab91e..2aeea6100 100644 --- a/iterator/pom.xml +++ b/iterator/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>iterator</artifactId> <dependencies> diff --git a/layers/pom.xml b/layers/pom.xml index d154904e4..c6e68150b 100644 --- a/layers/pom.xml +++ b/layers/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <groupId>com.iluwatar.layers</groupId> <artifactId>layers</artifactId> diff --git a/lazy-loading/pom.xml b/lazy-loading/pom.xml index c52c0a9dc..0ca7272a0 100644 --- a/lazy-loading/pom.xml +++ b/lazy-loading/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>lazy-loading</artifactId> <dependencies> diff --git a/mediator/pom.xml b/mediator/pom.xml index 7429b667f..8e24da4b9 100644 --- a/mediator/pom.xml +++ b/mediator/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>mediator</artifactId> <dependencies> diff --git a/memento/pom.xml b/memento/pom.xml index 6741d287c..fc78cb65b 100644 --- a/memento/pom.xml +++ b/memento/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>memento</artifactId> <dependencies> diff --git a/message-channel/pom.xml b/message-channel/pom.xml index 0edb6d075..a6f626a11 100644 --- a/message-channel/pom.xml +++ b/message-channel/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>message-channel</artifactId> <dependencies> diff --git a/model-view-controller/pom.xml b/model-view-controller/pom.xml index e02b1e34b..4e8697171 100644 --- a/model-view-controller/pom.xml +++ b/model-view-controller/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>model-view-controller</artifactId> <dependencies> diff --git a/model-view-presenter/pom.xml b/model-view-presenter/pom.xml index 286511382..c4f1c82dd 100644 --- a/model-view-presenter/pom.xml +++ b/model-view-presenter/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>model-view-presenter</artifactId> <name>model-view-presenter</name> diff --git a/monostate/pom.xml b/monostate/pom.xml index 838b00276..bb6119253 100644 --- a/monostate/pom.xml +++ b/monostate/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>monostate</artifactId> <dependencies> diff --git a/multiton/pom.xml b/multiton/pom.xml index 69df8b94d..6b07c638d 100644 --- a/multiton/pom.xml +++ b/multiton/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>multiton</artifactId> <dependencies> diff --git a/naked-objects/dom/pom.xml b/naked-objects/dom/pom.xml index 626f84b54..102c7178e 100644 --- a/naked-objects/dom/pom.xml +++ b/naked-objects/dom/pom.xml @@ -16,7 +16,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>naked-objects</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>naked-objects-dom</artifactId> diff --git a/naked-objects/fixture/pom.xml b/naked-objects/fixture/pom.xml index 9ec93892b..6f476bc9b 100644 --- a/naked-objects/fixture/pom.xml +++ b/naked-objects/fixture/pom.xml @@ -16,7 +16,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>naked-objects</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>naked-objects-fixture</artifactId> diff --git a/naked-objects/integtests/pom.xml b/naked-objects/integtests/pom.xml index e460cb113..6dbfc9946 100644 --- a/naked-objects/integtests/pom.xml +++ b/naked-objects/integtests/pom.xml @@ -16,7 +16,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>naked-objects</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>naked-objects-integtests</artifactId> diff --git a/naked-objects/pom.xml b/naked-objects/pom.xml index ea51dee3b..451944aa5 100644 --- a/naked-objects/pom.xml +++ b/naked-objects/pom.xml @@ -15,7 +15,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>naked-objects</artifactId> @@ -350,17 +350,17 @@ <dependency> <groupId>${project.groupId}</groupId> <artifactId>naked-objects-dom</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>naked-objects-fixture</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>naked-objects-webapp</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </dependency> </dependencies> diff --git a/naked-objects/webapp/pom.xml b/naked-objects/webapp/pom.xml index 4d1f62afd..c8b483513 100644 --- a/naked-objects/webapp/pom.xml +++ b/naked-objects/webapp/pom.xml @@ -16,7 +16,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>naked-objects</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>naked-objects-webapp</artifactId> diff --git a/null-object/pom.xml b/null-object/pom.xml index a95f5ff90..e8b1d2465 100644 --- a/null-object/pom.xml +++ b/null-object/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>null-object</artifactId> <dependencies> diff --git a/object-pool/pom.xml b/object-pool/pom.xml index 7b089170c..5a2e4b8b6 100644 --- a/object-pool/pom.xml +++ b/object-pool/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>object-pool</artifactId> <dependencies> diff --git a/observer/pom.xml b/observer/pom.xml index dc0a7a3ff..c8cca3edc 100644 --- a/observer/pom.xml +++ b/observer/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>observer</artifactId> <dependencies> diff --git a/poison-pill/pom.xml b/poison-pill/pom.xml index 93fbd0c96..0cc3bd6e8 100644 --- a/poison-pill/pom.xml +++ b/poison-pill/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>poison-pill</artifactId> <dependencies> diff --git a/pom.xml b/pom.xml index 7e35567e0..482110e64 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> <packaging>pom</packaging> <inceptionYear>2014</inceptionYear> diff --git a/private-class-data/pom.xml b/private-class-data/pom.xml index a5b115edc..97d623b46 100644 --- a/private-class-data/pom.xml +++ b/private-class-data/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>private-class-data</artifactId> <dependencies> diff --git a/producer-consumer/pom.xml b/producer-consumer/pom.xml index b970b2a4f..5c00b85f9 100644 --- a/producer-consumer/pom.xml +++ b/producer-consumer/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>producer-consumer</artifactId> <dependencies> diff --git a/property/pom.xml b/property/pom.xml index 454f20323..a5cd459df 100644 --- a/property/pom.xml +++ b/property/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>property</artifactId> <dependencies> diff --git a/prototype/pom.xml b/prototype/pom.xml index 80fcd0738..da1aa0fd2 100644 --- a/prototype/pom.xml +++ b/prototype/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>prototype</artifactId> <dependencies> diff --git a/proxy/pom.xml b/proxy/pom.xml index 5a86b4e30..4640a1bba 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>proxy</artifactId> <dependencies> diff --git a/publish-subscribe/pom.xml b/publish-subscribe/pom.xml index 8afaa3b53..bfa4838e7 100644 --- a/publish-subscribe/pom.xml +++ b/publish-subscribe/pom.xml @@ -28,7 +28,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>publish-subscribe</artifactId> <dependencies> diff --git a/reactor/pom.xml b/reactor/pom.xml index 5dd39d824..9e228ce6e 100644 --- a/reactor/pom.xml +++ b/reactor/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>reactor</artifactId> <dependencies> diff --git a/reader-writer-lock/pom.xml b/reader-writer-lock/pom.xml index d95daa4cb..dbfafff66 100644 --- a/reader-writer-lock/pom.xml +++ b/reader-writer-lock/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>reader-writer-lock</artifactId> <dependencies> diff --git a/repository/pom.xml b/repository/pom.xml index 79d8f5897..82e4b4d67 100644 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>repository</artifactId> <dependencies> diff --git a/resource-acquisition-is-initialization/pom.xml b/resource-acquisition-is-initialization/pom.xml index 17ec6e217..e79ec99ee 100644 --- a/resource-acquisition-is-initialization/pom.xml +++ b/resource-acquisition-is-initialization/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>resource-acquisition-is-initialization</artifactId> <dependencies> diff --git a/servant/pom.xml b/servant/pom.xml index 6d92991ab..0161e71f6 100644 --- a/servant/pom.xml +++ b/servant/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>servant</artifactId> <dependencies> diff --git a/service-layer/pom.xml b/service-layer/pom.xml index 1c12694b2..ff88256a9 100644 --- a/service-layer/pom.xml +++ b/service-layer/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>service-layer</artifactId> <dependencies> diff --git a/service-locator/pom.xml b/service-locator/pom.xml index 78ed58a26..4a64e8615 100644 --- a/service-locator/pom.xml +++ b/service-locator/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>service-locator</artifactId> <dependencies> diff --git a/singleton/pom.xml b/singleton/pom.xml index d18ed2190..66c02e664 100644 --- a/singleton/pom.xml +++ b/singleton/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>singleton</artifactId> <dependencies> diff --git a/specification/pom.xml b/specification/pom.xml index 8ad3ff3e9..125c34e0b 100644 --- a/specification/pom.xml +++ b/specification/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>specification</artifactId> <dependencies> diff --git a/state/pom.xml b/state/pom.xml index 590eda4b0..08b4846e6 100644 --- a/state/pom.xml +++ b/state/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>state</artifactId> <dependencies> diff --git a/step-builder/pom.xml b/step-builder/pom.xml index 30bbdfad5..dde7443f9 100644 --- a/step-builder/pom.xml +++ b/step-builder/pom.xml @@ -30,7 +30,7 @@ <parent> <artifactId>java-design-patterns</artifactId> <groupId>com.iluwatar</groupId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>step-builder</artifactId> <dependencies> diff --git a/strategy/pom.xml b/strategy/pom.xml index 703d0c307..0b6b2dc4e 100644 --- a/strategy/pom.xml +++ b/strategy/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>strategy</artifactId> <dependencies> diff --git a/template-method/pom.xml b/template-method/pom.xml index 7d3cbbfaa..0feb89c02 100644 --- a/template-method/pom.xml +++ b/template-method/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>template-method</artifactId> <dependencies> diff --git a/thread-pool/pom.xml b/thread-pool/pom.xml index 7e50843ac..a2e683359 100644 --- a/thread-pool/pom.xml +++ b/thread-pool/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>thread-pool</artifactId> <dependencies> diff --git a/tolerant-reader/pom.xml b/tolerant-reader/pom.xml index e0ce85e9f..6c8c96b3c 100644 --- a/tolerant-reader/pom.xml +++ b/tolerant-reader/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>tolerant-reader</artifactId> <dependencies> diff --git a/twin/pom.xml b/twin/pom.xml index b4bac4e29..dc23b26ef 100644 --- a/twin/pom.xml +++ b/twin/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>twin</artifactId> <dependencies> diff --git a/visitor/pom.xml b/visitor/pom.xml index 992c82c04..cdffb0151 100644 --- a/visitor/pom.xml +++ b/visitor/pom.xml @@ -29,7 +29,7 @@ <parent> <groupId>com.iluwatar</groupId> <artifactId>java-design-patterns</artifactId> - <version>1.10.0</version> + <version>1.11.0-SNAPSHOT</version> </parent> <artifactId>visitor</artifactId> <dependencies>