fixed merge conflict
This commit is contained in:
commit
1e988c10f9
20
.travis.yml
20
.travis.yml
@ -1,14 +1,18 @@
|
||||
language: java
|
||||
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- oraclejdk8
|
||||
|
||||
before_install:
|
||||
- "export DISPLAY=:99.0"
|
||||
- "sh -e /etc/init.d/xvfb start"
|
||||
env:
|
||||
global:
|
||||
- GH_REF: github.com/iluwatar/java-design-patterns.git
|
||||
- secure: LxTDuNS/rBWIvKkaEqr79ImZAe48mCdoYCF41coxNXgNoippo4GIBArknqtv+XvdkiuRZ1yGyj6pn8GU33c/yn+krddTUkVCwTbVatbalW5jhQjDbHYym/JcxaK9ZS/3JTeGcWrBgiPqHEEDhCf26vPZsXoMSeVCEORVKTp1BSg=
|
||||
|
||||
after_success:
|
||||
- mvn clean test jacoco:report coveralls:report
|
||||
before_install:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
|
||||
after_success:
|
||||
- mvn clean test jacoco:report coveralls:report
|
||||
- bash update-ghpages.sh
|
||||
|
||||
# Migration to container-based infrastructure
|
||||
sudo: false
|
||||
|
13
README.md
13
README.md
@ -21,13 +21,23 @@ Reusing design patterns helps to prevent subtle issues that can cause major
|
||||
problems, and it also improves code readability for coders and architects who
|
||||
are familiar with the patterns.
|
||||
|
||||
# Getting started
|
||||
|
||||
Before you dive into the material, you should be familiar with various
|
||||
[Programming/Software Design Principles](http://webpro.github.io/programming-principles/).
|
||||
|
||||
Once you are familiar with these concepts you can start drilling down into patterns by any of the following approaches
|
||||
|
||||
- Using difficulty tags, `Difficulty-Beginner`, `Difficulty-Intermediate` & `Difficulty-Expert`.
|
||||
- Using pattern categories, `Creational`, `Behavioral` and others.
|
||||
- Search for a specific pattern. Can't find one? Please report a new pattern [here](https://github.com/iluwatar/java-design-patterns/issues).
|
||||
|
||||
# How to contribute
|
||||
|
||||
If you are willing to contribute to the project you will find the relevant information in our [developer wiki](https://github.com/iluwatar/java-design-patterns/wiki).
|
||||
|
||||
# Credits
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
* [Effective Java (2nd Edition)](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)
|
||||
* [Java Generics and Collections](http://www.amazon.com/Java-Generics-Collections-Maurice-Naftalin/dp/0596527756/)
|
||||
* [Let's Modify the Objects-First Approach into Design-Patterns-First](http://edu.pecinovsky.cz/papers/2006_ITiCSE_Design_Patterns_First.pdf)
|
||||
@ -37,7 +47,6 @@ If you are willing to contribute to the project you will find the relevant infor
|
||||
* [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420)
|
||||
* [Spring Data](http://www.amazon.com/Spring-Data-Mark-Pollack/dp/1449323952/ref=sr_1_1)
|
||||
* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
|
||||
* [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697)
|
||||
|
||||
# License
|
||||
|
||||
|
@ -4,7 +4,9 @@ title: Abstract Factory
|
||||
folder: abstract-factory
|
||||
permalink: /patterns/abstract-factory/
|
||||
categories: Creational
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Provide an interface for creating families of related or dependent
|
||||
@ -22,3 +24,7 @@ objects without specifying their concrete classes.
|
||||
**Real world examples:**
|
||||
|
||||
* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
|
||||
|
||||
**Credits**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>abstract-factory</artifactId>
|
||||
<dependencies>
|
||||
|
@ -3,12 +3,21 @@ package com.iluwatar.abstractfactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* The Abstract Factory pattern provides a way to encapsulate a group of individual
|
||||
* factories that have a common theme without specifying their concrete classes. In
|
||||
* normal usage, the client software creates a concrete implementation of the abstract
|
||||
* factory and then uses the generic interface of the factory to create the concrete
|
||||
* objects that are part of the theme. The client does not know (or care) which
|
||||
* concrete objects it gets from each of these internal factories, since it uses only
|
||||
* the generic interfaces of their products. This pattern separates the details of
|
||||
* implementation of a set of objects from their general usage and relies on object
|
||||
* composition, as object creation is implemented in methods exposed in the factory
|
||||
* interface.
|
||||
* <p>
|
||||
* The essence of the Abstract Factory pattern is a factory interface
|
||||
* ({@link KingdomFactory}) and its implementations ({@link ElfKingdomFactory},
|
||||
* {@link OrcKingdomFactory}).
|
||||
* <p>
|
||||
* The example uses both concrete implementations to create a king, a castle and
|
||||
* an army.
|
||||
* {@link OrcKingdomFactory}). The example uses both concrete implementations to
|
||||
* create a king, a castle and an army.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
@ -4,7 +4,9 @@ title: Adapter
|
||||
folder: adapter
|
||||
permalink: /patterns/adapter/
|
||||
categories: Structural
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Convert the interface of a class into another interface the clients
|
||||
@ -22,3 +24,7 @@ incompatible interfaces.
|
||||
**Real world examples:**
|
||||
|
||||
* [java.util.Arrays#asList()](http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29)
|
||||
|
||||
**Credits**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>adapter</artifactId>
|
||||
<dependencies>
|
||||
|
@ -1,7 +1,13 @@
|
||||
package com.iluwatar.adapter;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* An adapter helps two incompatible interfaces to work together. This is the real
|
||||
* world definition for an adapter. Interfaces may be incompatible but the inner
|
||||
* functionality should suit the need. The Adapter design pattern allows otherwise
|
||||
* incompatible classes to work together by converting the interface of one class
|
||||
* into an interface expected by the clients.
|
||||
* <p>
|
||||
* There are two variations of the Adapter pattern: The class adapter implements
|
||||
* the adaptee's interface whereas the object adapter uses composition to
|
||||
* contain the adaptee in the adapter object. This example uses the object
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>async-method-invocation</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,7 +4,9 @@ title: Bridge
|
||||
folder: bridge
|
||||
permalink: /patterns/bridge/
|
||||
categories: Structural
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Decouple an abstraction from its implementation so that the two can
|
||||
@ -20,3 +22,7 @@ vary independently.
|
||||
* changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled.
|
||||
* 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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>bridge</artifactId>
|
||||
<dependencies>
|
||||
|
@ -2,6 +2,9 @@ package com.iluwatar.bridge;
|
||||
|
||||
/**
|
||||
*
|
||||
* The Bridge pattern can also be thought of as two layers of abstraction. With Bridge,
|
||||
* you can decouple an abstraction from its implementation so that the two can vary independently.
|
||||
* <p>
|
||||
* In Bridge pattern both abstraction ({@link MagicWeapon}) and implementation
|
||||
* ({@link MagicWeaponImpl}) have their own class hierarchies. The interface of the
|
||||
* implementations can be changed without affecting the clients.
|
||||
|
@ -4,7 +4,9 @@ title: Builder
|
||||
folder: builder
|
||||
permalink: /patterns/builder/
|
||||
categories: Creational
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Separate the construction of a complex object from its
|
||||
@ -22,3 +24,7 @@ representations.
|
||||
|
||||
* [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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>builder</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,7 +4,20 @@ import com.iluwatar. builder.Hero.HeroBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* This is the Builder pattern variation as described by Joshua Bloch in
|
||||
* The intention of the Builder pattern is to find a solution to the telescoping
|
||||
* constructor anti-pattern. The telescoping constructor anti-pattern occurs when the
|
||||
* increase of object constructor parameter combination leads to an exponential list
|
||||
* of constructors. Instead of using numerous constructors, the builder pattern uses
|
||||
* another object, a builder, that receives each initialization parameter step by step
|
||||
* and then returns the resulting constructed object at once.
|
||||
* <p>
|
||||
* The Builder pattern has another benefit. It can be used for objects that contain
|
||||
* flat data (html code, SQL query, X.509 certificate...), that is to say, data that
|
||||
* can't be easily edited. This type of data cannot be edited step by step and must
|
||||
* be edited at once. The best way to construct such an object is to use a builder
|
||||
* class.
|
||||
* <p>
|
||||
* In this example we have the Builder pattern variation as described by Joshua Bloch in
|
||||
* Effective Java 2nd Edition.
|
||||
* <p>
|
||||
* We want to build {@link Hero} objects, but its construction is complex because of the
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>business-delegate</artifactId>
|
||||
<dependencies>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>callback</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,7 +4,9 @@ title: Chain of responsibility
|
||||
folder: chain
|
||||
permalink: /patterns/chain/
|
||||
categories: Behavioral
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Avoid coupling the sender of a request to its receiver by giving
|
||||
@ -23,3 +25,7 @@ objects and pass the request along the chain until an object handles it.
|
||||
|
||||
* [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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>chain</artifactId>
|
||||
<dependencies>
|
||||
|
@ -2,10 +2,16 @@ package com.iluwatar.chain;
|
||||
|
||||
/**
|
||||
*
|
||||
* Chain of Responsibility organizes request handlers ({@link RequestHandler}) into a
|
||||
* chain where each handler has a chance to act on the request on its turn. In
|
||||
* this example the king ({@link OrcKing}) makes requests and the military orcs
|
||||
* ({@link OrcCommander}, {@link OrcOfficer}, {@link OrcSoldier}) form the handler chain.
|
||||
* The Chain of Responsibility pattern is a design pattern consisting of command
|
||||
* objects and a series of processing objects. Each processing object contains
|
||||
* logic that defines the types of command objects that it can handle; the rest are
|
||||
* passed to the next processing object in the chain. A mechanism also exists for
|
||||
* adding new processing objects to the end of this chain.
|
||||
* <p>
|
||||
* In this example we organize the request handlers ({@link RequestHandler}) into a
|
||||
* chain where each handler has a chance to act on the request on its turn. Here
|
||||
* the king ({@link OrcKing}) makes requests and the military orcs ({@link OrcCommander},
|
||||
* {@link OrcOfficer}, {@link OrcSoldier}) form the handler chain.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
208
checkstyle.xml
Normal file
208
checkstyle.xml
Normal file
@ -0,0 +1,208 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Source = https://github.com/checkstyle/checkstyle/tree/master/src/main/resources
|
||||
|
||||
Checkstyle configurartion that checks the Google coding conventions from:
|
||||
|
||||
- Google Java Style
|
||||
https://google-styleguide.googlecode.com/svn-history/r130/trunk/javaguide.html
|
||||
|
||||
Checkstyle is very configurable. Be sure to read the documentation at
|
||||
http://checkstyle.sf.net (or in your downloaded distribution).
|
||||
|
||||
Most Checks are configurable, be sure to consult the documentation.
|
||||
|
||||
To completely disable a check, just comment it out or delete it from the file.
|
||||
|
||||
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
|
||||
|
||||
-->
|
||||
|
||||
<module name="Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
|
||||
<property name="severity" value="warning"/>
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
|
||||
<module name="FileTabCharacter">
|
||||
<property name="eachLine" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<module name="OuterTypeFilename"/>
|
||||
<module name="IllegalTokenText">
|
||||
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
|
||||
<property name="format"
|
||||
value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
|
||||
<property name="message" value="Avoid using corresponding octal or Unicode escape."/>
|
||||
</module>
|
||||
<module name="AvoidEscapedUnicodeCharacters">
|
||||
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||
<property name="allowByTailComment" value="true"/>
|
||||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
</module>
|
||||
<module name="LineLength">
|
||||
<property name="max" value="100"/>
|
||||
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||
</module>
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="OneTopLevelClass"/>
|
||||
<module name="NoLineWrap"/>
|
||||
<module name="EmptyBlock">
|
||||
<property name="option" value="TEXT"/>
|
||||
<property name="tokens"
|
||||
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
|
||||
</module>
|
||||
<module name="NeedBraces"/>
|
||||
<module name="LeftCurly">
|
||||
<property name="maxLineLength" value="100"/>
|
||||
</module>
|
||||
<module name="RightCurly"/>
|
||||
<module name="RightCurly">
|
||||
<property name="option" value="alone"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, STATIC_INIT, INSTANCE_INIT"/>
|
||||
</module>
|
||||
<module name="WhitespaceAround">
|
||||
<property name="allowEmptyConstructors" value="true"/>
|
||||
<property name="allowEmptyMethods" value="true"/>
|
||||
<property name="allowEmptyTypes" value="true"/>
|
||||
<property name="allowEmptyLoops" value="true"/>
|
||||
<message key="ws.notFollowed"
|
||||
value="WhitespaceAround: ''{0}'' is not followed by whitespace."/>
|
||||
<message key="ws.notPreceded"
|
||||
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
|
||||
</module>
|
||||
<module name="OneStatementPerLine"/>
|
||||
<module name="MultipleVariableDeclarations"/>
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<module name="FallThrough"/>
|
||||
<module name="UpperEll"/>
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="tokens" value="DOT"/>
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="tokens" value="COMMA"/>
|
||||
<property name="option" value="EOL"/>
|
||||
</module>
|
||||
<module name="PackageName">
|
||||
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Package name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="TypeName">
|
||||
<message key="name.invalidPattern"
|
||||
value="Type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="MemberName">
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Member name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="ParameterName">
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="LocalVariableName">
|
||||
<property name="tokens" value="VARIABLE_DEF"/>
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
||||
<property name="allowOneCharVarInForLoop" value="true"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="ClassTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Class type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="MethodTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Method type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="NoFinalizer"/>
|
||||
<module name="GenericWhitespace">
|
||||
<message key="ws.followed"
|
||||
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
|
||||
<message key="ws.preceded"
|
||||
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
|
||||
<message key="ws.illegalFollow"
|
||||
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
|
||||
<message key="ws.notPreceded"
|
||||
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
|
||||
</module>
|
||||
<module name="Indentation">
|
||||
<property name="basicOffset" value="2"/>
|
||||
<property name="braceAdjustment" value="0"/>
|
||||
<property name="caseIndent" value="2"/>
|
||||
<property name="throwsIndent" value="4"/>
|
||||
<property name="lineWrappingIndentation" value="4"/>
|
||||
<property name="arrayInitIndent" value="2"/>
|
||||
</module>
|
||||
<module name="AbbreviationAsWordInName">
|
||||
<property name="ignoreFinal" value="false"/>
|
||||
<property name="allowedAbbreviationLength" value="1"/>
|
||||
</module>
|
||||
<module name="OverloadMethodsDeclarationOrder"/>
|
||||
<module name="VariableDeclarationUsageDistance"/>
|
||||
<module name="CustomImportOrder">
|
||||
<property name="thirdPartyPackageRegExp" value=".*"/>
|
||||
<property name="specialImportsRegExp" value="com.google"/>
|
||||
<property name="sortImportsInGroupAlphabetically" value="true"/>
|
||||
<property name="customImportOrderRules"
|
||||
value="STATIC###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE"/>
|
||||
</module>
|
||||
<module name="MethodParamPad"/>
|
||||
<module name="OperatorWrap">
|
||||
<property name="option" value="NL"/>
|
||||
<property name="tokens"
|
||||
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR "/>
|
||||
</module>
|
||||
<module name="AnnotationLocation">
|
||||
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
|
||||
</module>
|
||||
<module name="AnnotationLocation">
|
||||
<property name="tokens" value="VARIABLE_DEF"/>
|
||||
<property name="allowSamelineMultipleAnnotations" value="true"/>
|
||||
</module>
|
||||
<module name="NonEmptyAtclauseDescription"/>
|
||||
<module name="JavadocTagContinuationIndentation"/>
|
||||
<module name="SummaryJavadocCheck">
|
||||
<property name="forbiddenSummaryFragments"
|
||||
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
|
||||
</module>
|
||||
<module name="JavadocParagraph"/>
|
||||
<module name="AtclauseOrder">
|
||||
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
|
||||
<property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
||||
</module>
|
||||
<module name="JavadocMethod">
|
||||
<property name="scope" value="public"/>
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
<property name="allowMissingThrowsTags" value="true"/>
|
||||
<property name="allowMissingReturnTag" value="true"/>
|
||||
<property name="minLineCount" value="2"/>
|
||||
<property name="allowedAnnotations" value="Override, Test"/>
|
||||
<property name="allowThrowsTagsForSubclasses" value="true"/>
|
||||
</module>
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Method name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="SingleLineJavadoc"/>
|
||||
</module>
|
||||
</module>
|
@ -4,7 +4,9 @@ title: Command
|
||||
folder: command
|
||||
permalink: /patterns/command/
|
||||
categories: Behavioral
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Encapsulate a request as an object, thereby letting you
|
||||
@ -30,3 +32,7 @@ support undoable operations.
|
||||
**Real world examples:**
|
||||
|
||||
* [java.lang.Runnable](http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html)
|
||||
|
||||
**Credits**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>command</artifactId>
|
||||
<dependencies>
|
||||
|
@ -2,7 +2,9 @@ package com.iluwatar.command;
|
||||
|
||||
/**
|
||||
*
|
||||
* In Command pattern actions are objects that can be executed and undone.
|
||||
* The Command pattern is a behavioral design pattern in which an object is used to encapsulate all information
|
||||
* needed to perform an action or trigger an event at a later time. This information includes the method name,
|
||||
* the object that owns the method and values for the method parameters.
|
||||
* <p>
|
||||
* Four terms always associated with the command pattern are command, receiver, invoker and client. A command
|
||||
* object (spell) knows about the receiver (target) and invokes a method of the receiver. Values for parameters of
|
||||
|
@ -4,7 +4,9 @@ title: Composite
|
||||
folder: composite
|
||||
permalink: /patterns/composite/
|
||||
categories: Structural
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Compose objects into tree structures to represent part-whole
|
||||
@ -22,3 +24,7 @@ of objects uniformly.
|
||||
|
||||
* [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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>composite</artifactId>
|
||||
<dependencies>
|
||||
|
@ -1,10 +1,14 @@
|
||||
package com.iluwatar.composite;
|
||||
|
||||
/**
|
||||
*
|
||||
* With Composite we can treat tree hierarchies of objects with uniform
|
||||
* interface ({@link LetterComposite}). In this example we have sentences composed of
|
||||
* words composed of letters.
|
||||
* The Composite pattern is a partitioning design pattern. The Composite pattern
|
||||
* describes that a group of objects is to be treated in the same way as a single
|
||||
* instance of an object. The intent of a composite is to "compose" objects into
|
||||
* tree structures to represent part-whole hierarchies. Implementing the Composite
|
||||
* pattern lets clients treat individual objects and compositions uniformly.
|
||||
* <p>
|
||||
* In this example we have sentences composed of words composed of letters. All of
|
||||
* the objects can be treated through the same interface ({@link LetterComposite}).
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
@ -4,7 +4,9 @@ title: Data Access Object
|
||||
folder: dao
|
||||
permalink: /patterns/dao/
|
||||
categories: Architectural
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Beginner
|
||||
---
|
||||
|
||||
**Intent:** Object provides an abstract interface to some type of database or
|
||||
@ -16,3 +18,7 @@ other persistence mechanism.
|
||||
|
||||
* when you want to consolidate how the data layer is accessed
|
||||
* when you want to avoid writing multiple data retrieval/persistence layers
|
||||
|
||||
**Credits:**
|
||||
|
||||
* [J2EE Design Patterns](http://www.amazon.com/J2EE-Design-Patterns-William-Crawford/dp/0596004273/ref=sr_1_2)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>dao</artifactId>
|
||||
<dependencies>
|
||||
|
@ -5,8 +5,14 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* Data Access Object (DAO) is an object that provides an abstract interface to some type of database or other
|
||||
* persistence mechanism. By mapping application calls to the persistence layer, DAO provide some specific data
|
||||
* operations without exposing details of the database. This isolation supports the Single responsibility principle.
|
||||
* It separates what data accesses the application needs, in terms of domain-specific objects and data types
|
||||
* (the public interface of the DAO), from how these needs can be satisfied with a specific DBMS.
|
||||
* <p>
|
||||
* With the DAO pattern, we can use various method calls to retrieve/add/delete/update data without directly
|
||||
* interacting with the data. The below example demonstrates basic operations(CRUD): select, add, update, and delete.
|
||||
* interacting with the data. The below example demonstrates basic CRUD operations: select, add, update, and delete.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
@ -4,7 +4,9 @@ title: Decorator
|
||||
folder: decorator
|
||||
permalink: /patterns/decorator/
|
||||
categories: Structural
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Attach additional responsibilities to an object dynamically.
|
||||
@ -18,3 +20,7 @@ functionality.
|
||||
* 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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>decorator</artifactId>
|
||||
<dependencies>
|
||||
|
@ -2,12 +2,15 @@ package com.iluwatar.decorator;
|
||||
|
||||
/**
|
||||
*
|
||||
* Decorator pattern is a more flexible alternative to subclassing. The decorator
|
||||
* The Decorator pattern is a more flexible alternative to subclassing. The Decorator
|
||||
* class implements the same interface as the target and uses composition to
|
||||
* "decorate" calls to the target.
|
||||
* "decorate" calls to the target. Using the Decorator pattern it is possible to
|
||||
* change the behavior of the class during runtime.
|
||||
* <p>
|
||||
* Using decorator pattern it is possible to change class behavior during
|
||||
* runtime, as the example shows.
|
||||
* 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 can see how the behavior changes after the
|
||||
* decoration.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
@ -23,11 +26,13 @@ public class App {
|
||||
Hostile troll = new Troll();
|
||||
troll.attack();
|
||||
troll.fleeBattle();
|
||||
System.out.printf("Simple troll power %d.\n", troll.getAttackPower());
|
||||
|
||||
// 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);
|
||||
smart.attack();
|
||||
smart.fleeBattle();
|
||||
System.out.printf("Smart troll power %d.\n", smart.getAttackPower());
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ public interface Hostile {
|
||||
|
||||
void attack();
|
||||
|
||||
int getAttackPower();
|
||||
|
||||
void fleeBattle();
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,12 @@ public class SmartTroll implements Hostile {
|
||||
decorated.attack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttackPower() {
|
||||
// decorated troll power + 20 because it is smart
|
||||
return decorated.getAttackPower() + 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fleeBattle() {
|
||||
System.out.println("The troll calls for help!");
|
||||
|
@ -11,6 +11,11 @@ public class Troll implements Hostile {
|
||||
System.out.println("The troll swings at you with a club!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttackPower() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public void fleeBattle() {
|
||||
System.out.println("The troll shrieks in horror and runs away!");
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>dependency-injection</artifactId>
|
||||
<dependencies>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>double-checked-locking</artifactId>
|
||||
<dependencies>
|
||||
|
@ -5,6 +5,11 @@ import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
*
|
||||
* Double Checked Locking is a concurrency design pattern used to 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.
|
||||
* <p>
|
||||
* In {@link Inventory} we store the items with a given size. However, we do not store
|
||||
* more items than the inventory size. To address concurrent access problems we
|
||||
* use double checked locking to add item to inventory. In this method, the
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>double-dispatch</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>event-aggregator</artifactId>
|
||||
<dependencies>
|
||||
|
@ -5,8 +5,12 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* The Event Aggregator pattern channels events from multiple objects
|
||||
* into a single object to simplify registration for clients.
|
||||
* 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.
|
||||
* <p>
|
||||
* An Event Aggregator acts as a single source of events for many objects. It registers
|
||||
* for all the events of the many objects allowing clients to register with just the aggregator.
|
||||
* <p>
|
||||
* In the example {@link LordBaelish}, {@link LordVarys} and {@link Scout} deliver events to
|
||||
* {@link KingsHand}. {@link KingsHand}, the event aggregator, then delivers the events
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>execute-around</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,7 +4,9 @@ title: Facade
|
||||
folder: facade
|
||||
permalink: /patterns/facade/
|
||||
categories: Structural
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Provide a unified interface to a set of interfaces in a subsystem.
|
||||
@ -17,3 +19,7 @@ Facade defines a higher-level interface that makes the subsystem easier to use.
|
||||
* 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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>facade</artifactId>
|
||||
<dependencies>
|
||||
|
@ -2,9 +2,15 @@ package com.iluwatar.facade;
|
||||
|
||||
/**
|
||||
*
|
||||
* Facade ({@link DwarvenGoldmineFacade}) provides simpler interface to subsystem.
|
||||
* The Facade design pattern is often used when a system is very complex or difficult
|
||||
* to understand because the system has a large number of interdependent classes or
|
||||
* its source code is unavailable. This pattern hides the complexities of the larger
|
||||
* system and provides a simpler interface to the client. It typically involves a single
|
||||
* wrapper class which contains a set of members required by client. These members access
|
||||
* the system on behalf of the facade client and hide the implementation details.
|
||||
* <p>
|
||||
* http://en.wikipedia.org/wiki/Facade_pattern
|
||||
* In this example the Facade is ({@link DwarvenGoldmineFacade}) and it provides a simpler
|
||||
* interface to the goldmine subsystem.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
@ -4,7 +4,10 @@ title: Factory Method
|
||||
folder: factory-method
|
||||
permalink: /patterns/factory-method/
|
||||
categories: Creational
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Beginner
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Define an interface for creating an object, but let subclasses
|
||||
@ -18,3 +21,7 @@ instantiation to subclasses.
|
||||
* 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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>factory-method</artifactId>
|
||||
<dependencies>
|
||||
|
@ -2,7 +2,14 @@ package com.iluwatar.factory.method;
|
||||
|
||||
/**
|
||||
*
|
||||
* In Factory Method we have an interface ({@link Blacksmith}) with a method for
|
||||
* The Factory Method is a creational design pattern which uses factory methods to deal
|
||||
* with the problem of creating objects without specifying the exact class of object
|
||||
* that will be created. This is done by creating objects via calling a factory
|
||||
* method either specified in an interface and implemented by child classes, or implemented
|
||||
* in a base class and optionally overridden by derived classes—rather than by calling a
|
||||
* constructor.
|
||||
* <p>
|
||||
* In this Factory Method example we have an interface ({@link Blacksmith}) with a method for
|
||||
* creating objects ({@link Blacksmith#manufactureWeapon}). The concrete subclasses
|
||||
* ({@link OrcBlacksmith}, {@link ElfBlacksmith}) then override the method to produce
|
||||
* objects of their liking.
|
||||
|
4
faq.md
4
faq.md
@ -61,3 +61,7 @@ As for performance and scalability, pools can become bottlenecks, if all the
|
||||
pooled objects are in use and more clients need them, threads will become
|
||||
blocked waiting for available object from the pool. This is not the case with
|
||||
Flyweight.
|
||||
|
||||
### Q7: What are the differences between FluentInterface and Builder patterns? {#Q7}
|
||||
|
||||
Fluent interfaces are sometimes confused with the Builder pattern, because they share method chaining and a fluent usage. However, fluent interfaces are not primarily used to create shared (mutable) objects, but to configure complex objects without having to respecify the target object on every property change.
|
BIN
fluentinterface/etc/fluentinterface.png
Normal file
BIN
fluentinterface/etc/fluentinterface.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
100
fluentinterface/etc/fluentinterface.ucls
Normal file
100
fluentinterface/etc/fluentinterface.ucls
Normal file
@ -0,0 +1,100 @@
|
||||
<?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.fluentinterface.app.App" project="fluentinterface"
|
||||
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/app/App.java" binary="false" corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="289" y="-8"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="false" protected="false" private="false" static="false"/>
|
||||
<operations public="true" package="true" protected="true" private="false" static="true"/>
|
||||
</display>
|
||||
</class>
|
||||
<class id="2" language="java" name="com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable"
|
||||
project="fluentinterface"
|
||||
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java"
|
||||
binary="false" corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="450" y="430"/>
|
||||
<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.fluentinterface.fluentiterable.lazy.LazyFluentIterable"
|
||||
project="fluentinterface"
|
||||
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java"
|
||||
binary="false" corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="860" y="391"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</class>
|
||||
<interface id="4" language="java" name="com.iluwatar.fluentinterface.fluentiterable.FluentIterable"
|
||||
project="fluentinterface"
|
||||
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterable.java" binary="false"
|
||||
corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="794" y="55"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</interface>
|
||||
<class id="5" language="java" name="com.iluwatar.fluentinterface.fluentiterable.lazy.DecoratingIterator"
|
||||
project="fluentinterface"
|
||||
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java"
|
||||
binary="false" corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="1245" y="391"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</class>
|
||||
<interface id="6" language="java" name="java.lang.Iterable" project="fluentinterface"
|
||||
file="C:/Program Files/Java/jdk1.8.0_25/jre/lib/rt.jar" binary="true" corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="793" y="-163"/>
|
||||
<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>
|
||||
<dependency id="7">
|
||||
<end type="SOURCE" refId="3"/>
|
||||
<end type="TARGET" refId="5"/>
|
||||
</dependency>
|
||||
<dependency id="8">
|
||||
<end type="SOURCE" refId="1"/>
|
||||
<end type="TARGET" refId="3"/>
|
||||
</dependency>
|
||||
<dependency id="9">
|
||||
<end type="SOURCE" refId="1"/>
|
||||
<end type="TARGET" refId="4"/>
|
||||
</dependency>
|
||||
<realization id="10">
|
||||
<end type="SOURCE" refId="2"/>
|
||||
<end type="TARGET" refId="4"/>
|
||||
</realization>
|
||||
<realization id="11">
|
||||
<end type="SOURCE" refId="3"/>
|
||||
<end type="TARGET" refId="4"/>
|
||||
</realization>
|
||||
<dependency id="12">
|
||||
<end type="SOURCE" refId="1"/>
|
||||
<end type="TARGET" refId="2"/>
|
||||
</dependency>
|
||||
<generalization id="13">
|
||||
<end type="SOURCE" refId="4"/>
|
||||
<end type="TARGET" refId="6"/>
|
||||
</generalization>
|
||||
<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>
|
42
fluentinterface/index.md
Normal file
42
fluentinterface/index.md
Normal file
@ -0,0 +1,42 @@
|
||||
---
|
||||
layout: pattern
|
||||
title: Fluent Interface
|
||||
folder: fluentinterface
|
||||
permalink: /patterns/fluentinterface/
|
||||
categories: Other
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Intermediate
|
||||
---
|
||||
|
||||
**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:**
|
||||
|
||||
A fluent interface can be implemented using any of
|
||||
|
||||
* Method Chaining - calling a method returns some object on which further methods can be called.
|
||||
* Static Factory Methods and Imports
|
||||
* Named parameters - can be simulated in Java using static factory methods.
|
||||
|
||||

|
||||
|
||||
|
||||
**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:**
|
||||
|
||||
* [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)
|
||||
* [JOOQ](http://www.jooq.org/doc/3.0/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder/)
|
||||
* [Mockito](http://mockito.org/)
|
||||
* [Java Hamcrest](http://code.google.com/p/hamcrest/wiki/Tutorial)
|
||||
|
||||
**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/)
|
||||
* [Internal DSL](http://www.infoq.com/articles/internal-dsls-java)
|
20
fluentinterface/pom.xml
Normal file
20
fluentinterface/pom.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?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.7.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>fluentinterface</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,102 @@
|
||||
package com.iluwatar.fluentinterface.app;
|
||||
|
||||
import com.iluwatar.fluentinterface.fluentiterable.FluentIterable;
|
||||
import com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable;
|
||||
import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static java.lang.String.valueOf;
|
||||
|
||||
/**
|
||||
* The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API. Those
|
||||
* interfaces tend to mimic domain specific languages, so they can nearly be read as human languages.
|
||||
* <p>
|
||||
* In this example two implementations of a {@link FluentIterable} interface are given. The
|
||||
* {@link SimpleFluentIterable} evaluates eagerly and would be too costly for real world applications.
|
||||
* The {@link LazyFluentIterable} is evaluated on termination. Their usage is demonstrated with a
|
||||
* simple number list that is filtered, transformed and collected. The result is printed afterwards.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
List<Integer> integerList = new ArrayList<>();
|
||||
integerList.addAll(Arrays.asList(
|
||||
1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97,
|
||||
45, 23, 2, -68, 45
|
||||
));
|
||||
|
||||
prettyPrint("The initial list contains: ", integerList);
|
||||
|
||||
List<Integer> firstFiveNegatives =
|
||||
SimpleFluentIterable.fromCopyOf(integerList).filter(negatives()).first(3).asList();
|
||||
prettyPrint("The first three negative values are: ", firstFiveNegatives);
|
||||
|
||||
|
||||
List<Integer> lastTwoPositives =
|
||||
SimpleFluentIterable.fromCopyOf(integerList).filter(positives()).last(2).asList();
|
||||
prettyPrint("The last two positive values are: ", lastTwoPositives);
|
||||
|
||||
SimpleFluentIterable
|
||||
.fromCopyOf(integerList)
|
||||
.filter(number -> number % 2 == 0)
|
||||
.first()
|
||||
.ifPresent(
|
||||
evenNumber -> System.out.println(String.format("The first even number is: %d",
|
||||
evenNumber)));
|
||||
|
||||
|
||||
List<String> transformedList =
|
||||
SimpleFluentIterable.fromCopyOf(integerList).filter(negatives()).map(transformToString())
|
||||
.asList();
|
||||
prettyPrint("A string-mapped list of negative numbers contains: ", transformedList);
|
||||
|
||||
|
||||
List<String> lastTwoOfFirstFourStringMapped =
|
||||
LazyFluentIterable.from(integerList).filter(positives()).first(4).last(2)
|
||||
.map(number -> "String[" + String.valueOf(number) + "]").asList();
|
||||
prettyPrint(
|
||||
"The lazy list contains the last two of the first four positive numbers mapped to Strings: ",
|
||||
lastTwoOfFirstFourStringMapped);
|
||||
|
||||
LazyFluentIterable
|
||||
.from(integerList)
|
||||
.filter(negatives())
|
||||
.first(2)
|
||||
.last()
|
||||
.ifPresent(
|
||||
lastOfFirstTwo -> System.out.println(String.format(
|
||||
"The last of the first two negatives is: %d", lastOfFirstTwo)));
|
||||
}
|
||||
|
||||
private static Function<Integer, String> transformToString() {
|
||||
return integer -> "String[" + valueOf(integer) + "]";
|
||||
}
|
||||
|
||||
private static Predicate<? super Integer> negatives() {
|
||||
return integer -> (integer < 0);
|
||||
}
|
||||
|
||||
private static Predicate<? super Integer> positives() {
|
||||
return integer -> (integer > 0);
|
||||
}
|
||||
|
||||
private static <TYPE> void prettyPrint(String prefix, Iterable<TYPE> iterable) {
|
||||
prettyPrint(", ", prefix, ".", iterable);
|
||||
}
|
||||
|
||||
private static <TYPE> void prettyPrint(String delimiter, String prefix, String suffix,
|
||||
Iterable<TYPE> iterable) {
|
||||
StringJoiner joiner = new StringJoiner(delimiter, prefix, ".");
|
||||
Iterator<TYPE> iterator = iterable.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
joiner.add(iterator.next().toString());
|
||||
}
|
||||
|
||||
System.out.println(joiner);
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.iluwatar.fluentinterface.fluentiterable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* The FluentIterable is a more convenient implementation of the common iterable interface based on
|
||||
* the fluent interface design pattern. This interface defines common operations, but doesn't aim to
|
||||
* be complete. It was inspired by Guava's com.google.common.collect.FluentIterable.
|
||||
*
|
||||
* @param <TYPE> is the class of objects the iterable contains
|
||||
*/
|
||||
public interface FluentIterable<TYPE> extends Iterable<TYPE> {
|
||||
|
||||
/**
|
||||
* Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy
|
||||
* the predicate.
|
||||
*
|
||||
* @param predicate the condition to test with for the filtering. If the test is negative, the
|
||||
* tested object is removed by the iterator.
|
||||
* @return a filtered FluentIterable
|
||||
*/
|
||||
FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate);
|
||||
|
||||
/**
|
||||
* Returns an Optional containing the first element of this iterable if present, else returns
|
||||
* Optional.empty().
|
||||
*
|
||||
* @return the first element after the iteration is evaluated
|
||||
*/
|
||||
Optional<TYPE> first();
|
||||
|
||||
/**
|
||||
* Evaluates the iteration and leaves only the count first elements.
|
||||
*
|
||||
* @return the first count elements as an Iterable
|
||||
*/
|
||||
FluentIterable<TYPE> first(int count);
|
||||
|
||||
/**
|
||||
* Evaluates the iteration and returns the last element. This is a terminating operation.
|
||||
*
|
||||
* @return the last element after the iteration is evaluated
|
||||
*/
|
||||
Optional<TYPE> last();
|
||||
|
||||
/**
|
||||
* Evaluates the iteration and leaves only the count last elements.
|
||||
*
|
||||
* @return the last counts elements as an Iterable
|
||||
*/
|
||||
FluentIterable<TYPE> last(int count);
|
||||
|
||||
/**
|
||||
* Transforms this FluentIterable into a new one containing objects of the type NEW_TYPE.
|
||||
*
|
||||
* @param function a function that transforms an instance of TYPE into an instance of NEW_TYPE
|
||||
* @param <NEW_TYPE> the target type of the transformation
|
||||
* @return a new FluentIterable of the new type
|
||||
*/
|
||||
<NEW_TYPE> FluentIterable<NEW_TYPE> map(Function<? super TYPE, NEW_TYPE> function);
|
||||
|
||||
/**
|
||||
* Returns the contents of this Iterable as a List.
|
||||
*
|
||||
* @return a List representation of this Iterable
|
||||
*/
|
||||
List<TYPE> asList();
|
||||
|
||||
/**
|
||||
* Utility method that iterates over iterable and adds the contents to a list.
|
||||
*
|
||||
* @param iterable the iterable to collect
|
||||
* @param <TYPE> the type of the objects to iterate
|
||||
* @return a list with all objects of the given iterator
|
||||
*/
|
||||
static <TYPE> List<TYPE> copyToList(Iterable<TYPE> iterable) {
|
||||
ArrayList<TYPE> copy = new ArrayList<>();
|
||||
Iterator<TYPE> iterator = iterable.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
copy.add(iterator.next());
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.iluwatar.fluentinterface.fluentiterable.lazy;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This class is used to realize LazyFluentIterables. It decorates a given iterator. Does not
|
||||
* support consecutive hasNext() calls.
|
||||
*
|
||||
* @param <TYPE>
|
||||
*/
|
||||
public abstract class DecoratingIterator<TYPE> implements Iterator<TYPE> {
|
||||
|
||||
protected final Iterator<TYPE> fromIterator;
|
||||
|
||||
private TYPE next = null;
|
||||
|
||||
/**
|
||||
* Creates an iterator that decorates the given iterator.
|
||||
*
|
||||
* @param fromIterator
|
||||
*/
|
||||
public DecoratingIterator(Iterator<TYPE> fromIterator) {
|
||||
this.fromIterator = fromIterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Precomputes and saves the next element of the Iterable. null is considered as end of data.
|
||||
*
|
||||
* @return true if a next element is available
|
||||
*/
|
||||
@Override
|
||||
public final boolean hasNext() {
|
||||
next = computeNext();
|
||||
return next != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next element of the Iterable.
|
||||
*
|
||||
* @return the next element of the Iterable, or null if not present.
|
||||
*/
|
||||
@Override
|
||||
public final TYPE next() {
|
||||
if (next == null) {
|
||||
return fromIterator.next();
|
||||
} else {
|
||||
final TYPE result = next;
|
||||
next = null;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the next object of the Iterable. Can be implemented to realize custom behaviour for an
|
||||
* iteration process. null is considered as end of data.
|
||||
*
|
||||
* @return the next element of the Iterable.
|
||||
*/
|
||||
public abstract TYPE computeNext();
|
||||
}
|
@ -0,0 +1,230 @@
|
||||
package com.iluwatar.fluentinterface.fluentiterable.lazy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.iluwatar.fluentinterface.fluentiterable.FluentIterable;
|
||||
|
||||
/**
|
||||
* This is a lazy implementation of the FluentIterable interface. It evaluates all chained
|
||||
* operations when a terminating operation is applied.
|
||||
*
|
||||
* @param <TYPE> the type of the objects the iteration is about
|
||||
*/
|
||||
public class LazyFluentIterable<TYPE> implements FluentIterable<TYPE> {
|
||||
|
||||
private final Iterable<TYPE> iterable;
|
||||
|
||||
/**
|
||||
* This constructor creates a new LazyFluentIterable. It wraps the given iterable.
|
||||
*
|
||||
* @param iterable the iterable this FluentIterable works on.
|
||||
*/
|
||||
protected LazyFluentIterable(Iterable<TYPE> iterable) {
|
||||
this.iterable = iterable;
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor can be used to implement anonymous subclasses of the LazyFluentIterable.
|
||||
*/
|
||||
protected LazyFluentIterable() {
|
||||
iterable = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy
|
||||
* the predicate.
|
||||
*
|
||||
* @param predicate the condition to test with for the filtering. If the test is negative, the
|
||||
* tested object is removed by the iterator.
|
||||
* @return a new FluentIterable object that decorates the source iterable
|
||||
*/
|
||||
@Override
|
||||
public FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate) {
|
||||
return new LazyFluentIterable<TYPE>() {
|
||||
@Override
|
||||
public Iterator<TYPE> iterator() {
|
||||
return new DecoratingIterator<TYPE>(iterable.iterator()) {
|
||||
@Override
|
||||
public TYPE computeNext() {
|
||||
while (fromIterator.hasNext()) {
|
||||
TYPE candidate = fromIterator.next();
|
||||
if (!predicate.test(candidate)) {
|
||||
continue;
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect objects from the iteration. Is a terminating operation.
|
||||
*
|
||||
* @return an Optional containing the first object of this Iterable
|
||||
*/
|
||||
@Override
|
||||
public Optional<TYPE> first() {
|
||||
Iterator<TYPE> resultIterator = first(1).iterator();
|
||||
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect objects from the iteration.
|
||||
*
|
||||
* @param count defines the number of objects to return
|
||||
* @return the same FluentIterable with a collection decimated to a maximum of 'count' first
|
||||
* objects.
|
||||
*/
|
||||
@Override
|
||||
public FluentIterable<TYPE> first(int count) {
|
||||
return new LazyFluentIterable<TYPE>() {
|
||||
@Override
|
||||
public Iterator<TYPE> iterator() {
|
||||
return new DecoratingIterator<TYPE>(iterable.iterator()) {
|
||||
int currentIndex = 0;
|
||||
|
||||
@Override
|
||||
public TYPE computeNext() {
|
||||
if (currentIndex < count) {
|
||||
if (fromIterator.hasNext()) {
|
||||
TYPE candidate = fromIterator.next();
|
||||
currentIndex++;
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect objects from the iteration. Is a terminating operation.
|
||||
*
|
||||
* @return an Optional containing the last object of this Iterable
|
||||
*/
|
||||
@Override
|
||||
public Optional<TYPE> last() {
|
||||
Iterator<TYPE> resultIterator = last(1).iterator();
|
||||
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect objects from the Iterable. Is a terminating operation. This operation is
|
||||
* memory intensive, because the contents of this Iterable are collected into a List, when the
|
||||
* next object is requested.
|
||||
*
|
||||
* @param count defines the number of objects to return
|
||||
* @return the same FluentIterable with a collection decimated to a maximum of 'count' last
|
||||
* objects
|
||||
*/
|
||||
@Override
|
||||
public FluentIterable<TYPE> last(int count) {
|
||||
return new LazyFluentIterable<TYPE>() {
|
||||
@Override
|
||||
public Iterator<TYPE> iterator() {
|
||||
return new DecoratingIterator<TYPE>(iterable.iterator()) {
|
||||
private int stopIndex;
|
||||
private int totalElementsCount;
|
||||
private List<TYPE> list;
|
||||
private int currentIndex = 0;
|
||||
|
||||
@Override
|
||||
public TYPE computeNext() {
|
||||
initialize();
|
||||
|
||||
TYPE candidate = null;
|
||||
while (currentIndex < stopIndex && fromIterator.hasNext()) {
|
||||
currentIndex++;
|
||||
fromIterator.next();
|
||||
}
|
||||
if (currentIndex >= stopIndex && fromIterator.hasNext()) {
|
||||
candidate = fromIterator.next();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
Iterator<TYPE> newIterator = iterable.iterator();
|
||||
while (newIterator.hasNext()) {
|
||||
list.add(newIterator.next());
|
||||
}
|
||||
|
||||
totalElementsCount = list.size();
|
||||
stopIndex = totalElementsCount - count;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms this FluentIterable into a new one containing objects of the type NEW_TYPE.
|
||||
*
|
||||
* @param function a function that transforms an instance of TYPE into an instance of NEW_TYPE
|
||||
* @param <NEW_TYPE> the target type of the transformation
|
||||
* @return a new FluentIterable of the new type
|
||||
*/
|
||||
@Override
|
||||
public <NEW_TYPE> FluentIterable<NEW_TYPE> map(Function<? super TYPE, NEW_TYPE> function) {
|
||||
return new LazyFluentIterable<NEW_TYPE>() {
|
||||
@Override
|
||||
public Iterator<NEW_TYPE> iterator() {
|
||||
return new DecoratingIterator<NEW_TYPE>(null) {
|
||||
Iterator<TYPE> oldTypeIterator = iterable.iterator();
|
||||
|
||||
@Override
|
||||
public NEW_TYPE computeNext() {
|
||||
while (oldTypeIterator.hasNext()) {
|
||||
TYPE candidate = oldTypeIterator.next();
|
||||
return function.apply(candidate);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects all remaining objects of this iteration into a list.
|
||||
*
|
||||
* @return a list with all remaining objects of this iteration
|
||||
*/
|
||||
@Override
|
||||
public List<TYPE> asList() {
|
||||
List<TYPE> copy = FluentIterable.copyToList(iterable);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TYPE> iterator() {
|
||||
return new DecoratingIterator<TYPE>(iterable.iterator()) {
|
||||
@Override
|
||||
public TYPE computeNext() {
|
||||
return fromIterator.next();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a FluentIterable from a given iterable. Calls the LazyFluentIterable constructor.
|
||||
*/
|
||||
public static final <TYPE> FluentIterable<TYPE> from(Iterable<TYPE> iterable) {
|
||||
return new LazyFluentIterable<>(iterable);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
package com.iluwatar.fluentinterface.fluentiterable.simple;
|
||||
|
||||
import com.iluwatar.fluentinterface.fluentiterable.FluentIterable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* This is a simple implementation of the FluentIterable interface. It evaluates all chained
|
||||
* operations eagerly. This implementation would be costly to be utilized in real applications.
|
||||
*
|
||||
* @param <TYPE> the type of the objects the iteration is about
|
||||
*/
|
||||
public class SimpleFluentIterable<TYPE> implements FluentIterable<TYPE> {
|
||||
|
||||
private final Iterable<TYPE> iterable;
|
||||
|
||||
/**
|
||||
* This constructor creates a copy of a given iterable's contents.
|
||||
*
|
||||
* @param iterable the iterable this interface copies to work on.
|
||||
*/
|
||||
protected SimpleFluentIterable(Iterable<TYPE> iterable) {
|
||||
this.iterable = iterable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy
|
||||
* the predicate.
|
||||
*
|
||||
* @param predicate the condition to test with for the filtering. If the test is negative, the
|
||||
* tested object is removed by the iterator.
|
||||
* @return the same FluentIterable with a filtered collection
|
||||
*/
|
||||
@Override
|
||||
public final FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate) {
|
||||
Iterator<TYPE> iterator = iterator();
|
||||
while (iterator.hasNext()) {
|
||||
TYPE nextElement = iterator.next();
|
||||
if (!predicate.test(nextElement)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect objects from the Iterable. Is a terminating operation.
|
||||
*
|
||||
* @return an option of the first object of the Iterable
|
||||
*/
|
||||
@Override
|
||||
public final Optional<TYPE> first() {
|
||||
Iterator<TYPE> resultIterator = first(1).iterator();
|
||||
return resultIterator.hasNext() ? Optional.of(resultIterator.next()) : Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect objects from the Iterable. Is a terminating operation.
|
||||
*
|
||||
* @param count defines the number of objects to return
|
||||
* @return the same FluentIterable with a collection decimated to a maximum of 'count' first
|
||||
* objects.
|
||||
*/
|
||||
@Override
|
||||
public final FluentIterable<TYPE> first(int count) {
|
||||
Iterator<TYPE> iterator = iterator();
|
||||
int currentCount = 0;
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
if (currentCount >= count) {
|
||||
iterator.remove();
|
||||
}
|
||||
currentCount++;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect objects from the Iterable. Is a terminating operation.
|
||||
*
|
||||
* @return an option of the last object of the Iterable
|
||||
*/
|
||||
@Override
|
||||
public final Optional<TYPE> last() {
|
||||
List<TYPE> list = last(1).asList();
|
||||
if (list.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(list.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to collect objects from the Iterable. Is a terminating operation.
|
||||
*
|
||||
* @param count defines the number of objects to return
|
||||
* @return the same FluentIterable with a collection decimated to a maximum of 'count' last
|
||||
* objects
|
||||
*/
|
||||
@Override
|
||||
public final FluentIterable<TYPE> last(int count) {
|
||||
int remainingElementsCount = getRemainingElementsCount();
|
||||
Iterator<TYPE> iterator = iterator();
|
||||
int currentIndex = 0;
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
if (currentIndex < remainingElementsCount - count) {
|
||||
iterator.remove();
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms this FluentIterable into a new one containing objects of the type NEW_TYPE.
|
||||
*
|
||||
* @param function a function that transforms an instance of TYPE into an instance of NEW_TYPE
|
||||
* @param <NEW_TYPE> the target type of the transformation
|
||||
* @return a new FluentIterable of the new type
|
||||
*/
|
||||
@Override
|
||||
public final <NEW_TYPE> FluentIterable<NEW_TYPE> map(Function<? super TYPE, NEW_TYPE> function) {
|
||||
List<NEW_TYPE> temporaryList = new ArrayList<>();
|
||||
Iterator<TYPE> iterator = iterator();
|
||||
while (iterator.hasNext()) {
|
||||
temporaryList.add(function.apply(iterator.next()));
|
||||
}
|
||||
return from(temporaryList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects all remaining objects of this Iterable into a list.
|
||||
*
|
||||
* @return a list with all remaining objects of this Iterable
|
||||
*/
|
||||
@Override
|
||||
public List<TYPE> asList() {
|
||||
return toList(iterable.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a FluentIterable from a given iterable. Calls the SimpleFluentIterable constructor.
|
||||
*/
|
||||
public static final <TYPE> FluentIterable<TYPE> from(Iterable<TYPE> iterable) {
|
||||
return new SimpleFluentIterable<>(iterable);
|
||||
}
|
||||
|
||||
public static final <TYPE> FluentIterable<TYPE> fromCopyOf(Iterable<TYPE> iterable) {
|
||||
List<TYPE> copy = FluentIterable.copyToList(iterable);
|
||||
return new SimpleFluentIterable<>(copy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TYPE> iterator() {
|
||||
return iterable.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super TYPE> action) {
|
||||
iterable.forEach(action);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Spliterator<TYPE> spliterator() {
|
||||
return iterable.spliterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the count of remaining objects of the current Iterable
|
||||
*/
|
||||
public final int getRemainingElementsCount() {
|
||||
int counter = 0;
|
||||
Iterator<TYPE> iterator = iterator();
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the remaining objects of the given iterator into a List.
|
||||
*
|
||||
* @return a new List with the remaining objects.
|
||||
*/
|
||||
public static <TYPE> List<TYPE> toList(Iterator<TYPE> iterator) {
|
||||
List<TYPE> copy = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
copy.add(iterator.next());
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.iluwatar.fluentinterface.app;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.iluwatar.fluentinterface.app.App;
|
||||
|
||||
public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>flux</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,7 +4,9 @@ title: Flyweight
|
||||
folder: flyweight
|
||||
permalink: /patterns/flyweight/
|
||||
categories: Structural
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Use sharing to support large numbers of fine-grained objects
|
||||
@ -25,3 +27,7 @@ true
|
||||
**Real world examples:**
|
||||
|
||||
* [java.lang.Integer#valueOf(int)](http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#valueOf%28int%29)
|
||||
|
||||
**Credits**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>flyweight</artifactId>
|
||||
<dependencies>
|
||||
|
@ -22,3 +22,9 @@ internationalization, routing and logging in a single place.
|
||||
**Real world examples:**
|
||||
|
||||
* [Apache Struts](https://struts.apache.org/)
|
||||
|
||||
**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)
|
||||
* [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420)
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>front-controller</artifactId>
|
||||
<dependencies>
|
||||
|
@ -30,3 +30,4 @@ degrading execution efficiency.
|
||||
**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)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>half-sync-half-async</artifactId>
|
||||
<dependencies>
|
||||
|
@ -18,6 +18,11 @@ post-processing to requests from a client to a target
|
||||
* 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:**
|
||||
|
||||
* [Struts 2 - Interceptors](https://struts.apache.org/docs/interceptors.html)
|
||||
|
||||
**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)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>intercepting-filter</artifactId>
|
||||
<dependencies>
|
||||
|
@ -1,9 +1,33 @@
|
||||
package com.iluwatar.intercepting.filter;
|
||||
|
||||
/**
|
||||
*
|
||||
* This is an app that checks whether the order request is valid through pre-processing done via {@link Filter}.
|
||||
* Each field has its own corresponding {@link Filter}
|
||||
*
|
||||
* When a request enters a Web application, it often must pass several entrance
|
||||
* tests prior to the main processing stage. For example,
|
||||
* - Has the client been authenticated?
|
||||
* - Does the client have a valid session?
|
||||
* - Is the client's IP address from a trusted network?
|
||||
* - Does the request path violate any constraints?
|
||||
* - What encoding does the client use to send the data?
|
||||
* - Do we support the browser type of the client?
|
||||
* Some of these checks are tests, resulting in a yes or no answer that determines
|
||||
* whether processing will continue. Other checks manipulate the incoming data
|
||||
* stream into a form suitable for processing.
|
||||
* <p>
|
||||
* The classic solution consists of a series of conditional checks, with any failed
|
||||
* check aborting the request. Nested if/else statements are a standard strategy,
|
||||
* but this solution leads to code fragility and a copy-and-paste style of programming,
|
||||
* because the flow of the filtering and the action of the filters is compiled into
|
||||
* the application.
|
||||
* <p>
|
||||
* The key to solving this problem in a flexible and unobtrusive manner is to have a
|
||||
* simple mechanism for adding and removing processing components, in which each
|
||||
* component completes a specific filtering action. This is the Intercepting Filter
|
||||
* pattern in action.
|
||||
* <p>
|
||||
* In this example we check whether the order request is valid through pre-processing
|
||||
* done via {@link Filter}. Each field has its own corresponding {@link Filter}
|
||||
* <p>
|
||||
* @author joshzambales
|
||||
*
|
||||
*/
|
||||
|
@ -4,7 +4,9 @@ title: Interpreter
|
||||
folder: interpreter
|
||||
permalink: /patterns/interpreter/
|
||||
categories: Behavioral
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Given a language, define a representation for its grammar along
|
||||
@ -19,3 +21,7 @@ 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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>interpreter</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,8 +4,14 @@ import java.util.Stack;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interpreter pattern breaks sentences into expressions ({@link Expression}) that can
|
||||
* be evaluated and as a whole form the result.
|
||||
* The Interpreter pattern is a design pattern that specifies how to evaluate sentences
|
||||
* in a language. The basic idea is to have a class for each symbol (terminal or nonterminal)
|
||||
* in a specialized computer language. The syntax tree of a sentence in the language is an
|
||||
* instance of the composite pattern and is used to evaluate (interpret) the sentence for a
|
||||
* client.
|
||||
* <p>
|
||||
* In this example we use the Interpreter pattern to break sentences into expressions
|
||||
* ({@link Expression}) that can be evaluated and as a whole form the result.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
@ -4,7 +4,10 @@ title: Iterator
|
||||
folder: iterator
|
||||
permalink: /patterns/iterator/
|
||||
categories: Behavioral
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Difficulty-Beginner
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Provide a way to access the elements of an aggregate object
|
||||
@ -21,3 +24,7 @@ sequentially without exposing its underlying representation.
|
||||
**Real world examples:**
|
||||
|
||||
* [java.util.Iterator](http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html)
|
||||
|
||||
**Credits**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>iterator</artifactId>
|
||||
<dependencies>
|
||||
|
@ -2,9 +2,13 @@ package com.iluwatar.iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* Iterator ({@link ItemIterator}) adds abstraction layer on top of a collection
|
||||
* ({@link TreasureChest}). This way the collection can change its internal
|
||||
* implementation without affecting its clients.
|
||||
* The Iterator pattern is a design pattern in which an iterator is used to
|
||||
* traverse a container and access the container's elements. The Iterator pattern
|
||||
* decouples algorithms from containers.
|
||||
* <p>
|
||||
* In this example the Iterator ({@link ItemIterator}) adds abstraction layer on
|
||||
* top of a collection ({@link TreasureChest}). This way the collection can change
|
||||
* its internal implementation without affecting its clients.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
@ -17,3 +17,8 @@ tags: Java
|
||||
* 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:**
|
||||
|
||||
* [Pattern Oriented Software Architecture Vol I-V](http://www.amazon.com/Pattern-Oriented-Software-Architecture-Volume-Patterns/dp/0471958697)
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<groupId>com.iluwatar.layers</groupId>
|
||||
<artifactId>layers</artifactId>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>lazy-loading</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,7 +4,10 @@ title: Mediator
|
||||
folder: mediator
|
||||
permalink: /patterns/mediator/
|
||||
categories: Behavioral
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
- Difficulty-Intermediate
|
||||
---
|
||||
|
||||
**Intent:** Define an object that encapsulates how a set of objects interact.
|
||||
@ -18,3 +21,7 @@ other explicitly, and it lets you vary their interaction independently.
|
||||
* 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**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>mediator</artifactId>
|
||||
<dependencies>
|
||||
|
@ -2,8 +2,26 @@ package com.iluwatar.mediator;
|
||||
|
||||
/**
|
||||
*
|
||||
* Mediator encapsulates how a set of objects ({@link PartyMember}) interact. Instead of
|
||||
* referring to each other directly they use a mediator ({@link Party}) interface.
|
||||
* The Mediator pattern defines an object that encapsulates how a set of objects
|
||||
* interact. This pattern is considered to be a behavioral pattern due to the way
|
||||
* it can alter the program's running behavior.
|
||||
* <p>
|
||||
* Usually a program is made up of a large number of classes. So the logic and
|
||||
* computation is distributed among these classes. However, as more classes are
|
||||
* developed in a program, especially during maintenance and/or refactoring,
|
||||
* the problem of communication between these classes may become more complex.
|
||||
* This makes the program harder to read and maintain. Furthermore, it can become
|
||||
* difficult to change the program, since any change may affect code in several
|
||||
* other classes.
|
||||
* <p>
|
||||
* With the Mediator pattern, communication between objects is encapsulated with
|
||||
* a mediator object. Objects no longer communicate directly with each other, but
|
||||
* instead communicate through the mediator. This reduces the dependencies between
|
||||
* communicating objects, thereby lowering the coupling.
|
||||
* <p>
|
||||
* In this example the mediator encapsulates how a set of objects ({@link PartyMember})
|
||||
* interact. Instead of referring to each other directly they use the mediator
|
||||
* ({@link Party}) interface.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
@ -4,7 +4,9 @@ title: Memento
|
||||
folder: memento
|
||||
permalink: /patterns/memento/
|
||||
categories: Behavioral
|
||||
tags: Java
|
||||
tags:
|
||||
- Java
|
||||
- Gang Of Four
|
||||
---
|
||||
|
||||
**Intent:** Without violating encapsulation, capture and externalize an
|
||||
@ -20,3 +22,7 @@ object's internal state so that the object can be restored to this state later.
|
||||
**Real world examples:**
|
||||
|
||||
* [java.util.Date](http://docs.oracle.com/javase/8/docs/api/java/util/Date.html)
|
||||
|
||||
**Credits**
|
||||
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>memento</artifactId>
|
||||
<dependencies>
|
||||
|
@ -4,7 +4,20 @@ import java.util.Stack;
|
||||
|
||||
/**
|
||||
*
|
||||
* Memento pattern is for storing and restoring object state. The object ({@link Star})
|
||||
* The Memento pattern is a software design pattern that provides the ability to restore
|
||||
* an object to its previous state (undo via rollback).
|
||||
* <p>
|
||||
* The Memento pattern is implemented with three objects: the originator, a caretaker and
|
||||
* a memento. The originator is some object that has an internal state. The caretaker is
|
||||
* going to do something to the originator, but wants to be able to undo the change. The
|
||||
* caretaker first asks the originator for a memento object. Then it does whatever operation
|
||||
* (or sequence of operations) it was going to do. To roll back to the state before the
|
||||
* operations, it returns the memento object to the originator. The memento object itself
|
||||
* is an opaque object (one which the caretaker cannot, or should not, change). When using
|
||||
* this pattern, care should be taken if the originator may change other objects or
|
||||
* resources - the memento pattern operates on a single object.
|
||||
* <p>
|
||||
* In this example the object ({@link Star})
|
||||
* gives out a "memento" ({@link StarMemento}) that contains the state of the object.
|
||||
* Later on the memento can be set back to the object restoring the state.
|
||||
*
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>message-channel</artifactId>
|
||||
<dependencies>
|
||||
|
@ -21,3 +21,5 @@ display.
|
||||
**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)
|
||||
* [Patterns of Enterprise Application Architecture](http://www.amazon.com/Patterns-Enterprise-Application-Architecture-Martin/dp/0321127420)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>model-view-controller</artifactId>
|
||||
<dependencies>
|
||||
|
@ -1,29 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
/**
|
||||
*
|
||||
* In this second example the model-view relationship is different. This time we use the Observer pattern to notify
|
||||
* the {@link GiantView} each time the {@link GiantModel} is changed. This way the {@link GiantController} responsibilities
|
||||
* are narrowed and it only needs to modify the {@link GiantModel} according to the user input.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
||||
/**
|
||||
* Program entry point
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main( String[] args ) {
|
||||
// create model, view and controller
|
||||
GiantModel giant = new GiantModel(Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED);
|
||||
GiantView view = new GiantView();
|
||||
GiantController controller = new GiantController(giant, view);
|
||||
// initial display
|
||||
controller.updateView();
|
||||
// controller receives some interactions that affect the giant
|
||||
// model modifications trigger the view rendering automatically
|
||||
controller.setHealth(Health.WOUNDED);
|
||||
controller.setNourishment(Nourishment.HUNGRY);
|
||||
controller.setFatigue(Fatigue.TIRED);
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Fatigue enumeration
|
||||
*
|
||||
*/
|
||||
public enum Fatigue {
|
||||
|
||||
ALERT("alert"), TIRED("tired"), SLEEPING("sleeping");
|
||||
|
||||
private String title;
|
||||
|
||||
Fatigue(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
/**
|
||||
*
|
||||
* GiantController updates the giant model.
|
||||
*
|
||||
*/
|
||||
public class GiantController {
|
||||
|
||||
private GiantModel giant;
|
||||
private GiantView view;
|
||||
|
||||
public GiantController(GiantModel giant, GiantView view) {
|
||||
this.giant = giant;
|
||||
this.view = view;
|
||||
this.giant.registerObserver(this.view);
|
||||
}
|
||||
|
||||
public Health getHealth() {
|
||||
return giant.getHealth();
|
||||
}
|
||||
|
||||
public void setHealth(Health health) {
|
||||
this.giant.setHealth(health);
|
||||
}
|
||||
|
||||
public Fatigue getFatigue() {
|
||||
return giant.getFatigue();
|
||||
}
|
||||
|
||||
public void setFatigue(Fatigue fatigue) {
|
||||
this.giant.setFatigue(fatigue);
|
||||
}
|
||||
|
||||
public Nourishment getNourishment() {
|
||||
return giant.getNourishment();
|
||||
}
|
||||
|
||||
public void setNourishment(Nourishment nourishment) {
|
||||
this.giant.setNourishment(nourishment);
|
||||
}
|
||||
|
||||
public void updateView() {
|
||||
this.view.displayGiant(giant);
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* GiantModel contains the giant data.
|
||||
*
|
||||
*/
|
||||
public class GiantModel {
|
||||
|
||||
private Health health;
|
||||
private Fatigue fatigue;
|
||||
private Nourishment nourishment;
|
||||
private List<GiantModelObserver> observers = new ArrayList<>();
|
||||
|
||||
GiantModel(Health health, Fatigue fatigue, Nourishment nourishment) {
|
||||
this.health = health;
|
||||
this.fatigue = fatigue;
|
||||
this.nourishment = nourishment;
|
||||
}
|
||||
|
||||
public Health getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
public void setHealth(Health health) {
|
||||
this.health = health;
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public Fatigue getFatigue() {
|
||||
return fatigue;
|
||||
}
|
||||
|
||||
public void setFatigue(Fatigue fatigue) {
|
||||
this.fatigue = fatigue;
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
public Nourishment getNourishment() {
|
||||
return nourishment;
|
||||
}
|
||||
|
||||
public void setNourishment(Nourishment nourishment) {
|
||||
this.nourishment = nourishment;
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("The giant looks %s, %s and %s.", health, fatigue, nourishment);
|
||||
}
|
||||
|
||||
public void registerObserver(GiantModelObserver observer) {
|
||||
observers.add(observer);
|
||||
}
|
||||
|
||||
private void notifyObservers() {
|
||||
observers.stream().forEach((GiantModelObserver o) -> o.modelChanged(this));
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
/**
|
||||
*
|
||||
* GiantModelObserver is the interface for delivering update notifications.
|
||||
*
|
||||
*/
|
||||
public interface GiantModelObserver {
|
||||
|
||||
void modelChanged(GiantModel model);
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
/**
|
||||
*
|
||||
* GiantView displays the giant
|
||||
*
|
||||
*/
|
||||
public class GiantView implements GiantModelObserver {
|
||||
|
||||
public void displayGiant(GiantModel giant) {
|
||||
System.out.println(giant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modelChanged(GiantModel model) {
|
||||
displayGiant(model);
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Health enumeration
|
||||
*
|
||||
*/
|
||||
public enum Health {
|
||||
|
||||
HEALTHY("healthy"), WOUNDED("wounded"), DEAD("dead");
|
||||
|
||||
private String title;
|
||||
|
||||
Health(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
/**
|
||||
*
|
||||
* Nourishment enumeration
|
||||
*
|
||||
*/
|
||||
public enum Nourishment {
|
||||
|
||||
SATURATED("saturated"), HUNGRY("hungry"), STARVING("starving");
|
||||
|
||||
private String title;
|
||||
|
||||
Nourishment(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.iluwatar.model.view.controller.with.observer;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.iluwatar.model.view.controller.with.observer.App;
|
||||
|
||||
/**
|
||||
*
|
||||
* Application test
|
||||
*
|
||||
*/
|
||||
public class AppTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String[] args = {};
|
||||
App.main(args);
|
||||
}
|
||||
}
|
@ -17,3 +17,7 @@ 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:**
|
||||
|
||||
* [MVP4J](https://github.com/amineoualialami/mvp4j)
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>model-view-presenter</artifactId>
|
||||
<name>model-view-presenter</name>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.iluwatar</groupId>
|
||||
<artifactId>java-design-patterns</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<version>1.7.0</version>
|
||||
</parent>
|
||||
<artifactId>multiton</artifactId>
|
||||
<dependencies>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user