Updating fork branch

This commit is contained in:
WSSIA 2016-09-11 16:24:16 +01:00
commit fce30db803
41 changed files with 1260 additions and 863 deletions

View File

@ -19,6 +19,7 @@ after_success:
- mvn clean test jacoco:report coveralls:report
- bash update-ghpages.sh
# use latest java version available instead of travis default
addons:
apt:
packages:

View File

@ -31,6 +31,8 @@ Use the Abstract Factory pattern when
## Real world examples
* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
* [javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--)
* [javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--)
## Credits

View File

@ -31,6 +31,10 @@ Use the Adapter pattern when
## Real world examples
* [java.util.Arrays#asList()](http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29)
* [java.util.Collections#list()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#list-java.util.Enumeration-)
* [java.util.Collections#enumeration()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#enumeration-java.util.Collection-)
* [javax.xml.bind.annotation.adapters.XMLAdapter](http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html#marshal-BoundType-)
## Credits

View File

@ -27,6 +27,9 @@ Use the Builder pattern when
## Real world examples
* [java.lang.StringBuilder](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html)
* [java.nio.ByteBuffer](http://docs.oracle.com/javase/8/docs/api/java/nio/ByteBuffer.html#put-byte-) as well as similar buffers such as FloatBuffer, IntBuffer and so on.
* [java.lang.StringBuffer](http://docs.oracle.com/javase/8/docs/api/java/lang/StringBuffer.html#append-boolean-)
* All implementations of [java.lang.Appendable](http://docs.oracle.com/javase/8/docs/api/java/lang/Appendable.html)
* [Apache Camel builders](https://github.com/apache/camel/tree/0e195428ee04531be27a0b659005e3aa8d159d23/camel-core/src/main/java/org/apache/camel/builder)
## Credits

View File

@ -29,6 +29,7 @@ Use Chain of Responsibility when
* [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)
* [javax.servlet.Filter#doFilter()](http://docs.oracle.com/javaee/7/api/javax/servlet/Filter.html#doFilter-javax.servlet.ServletRequest-javax.servlet.ServletResponse-javax.servlet.FilterChain-)
## Credits

View File

@ -41,6 +41,7 @@ Use the Command pattern when you want to
* [java.lang.Runnable](http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html)
* [Netflix Hystrix](https://github.com/Netflix/Hystrix/wiki)
* [javax.swing.Action](http://docs.oracle.com/javase/8/docs/api/javax/swing/Action.html)
## Credits

View File

@ -28,6 +28,14 @@ Use Decorator
* 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
## Real world examples
* [java.io.InputStream](http://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html), [java.io.OutputStream](http://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html),
[java.io.Reader](http://docs.oracle.com/javase/8/docs/api/java/io/Reader.html) and [java.io.Writer](http://docs.oracle.com/javase/8/docs/api/java/io/Writer.html)
* [java.util.Collections#synchronizedXXX()](http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedCollection-java.util.Collection-)
* [java.util.Collections#unmodifiableXXX()](http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#unmodifiableCollection-java.util.Collection-)
* [java.util.Collections#checkedXXX()](http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#checkedCollection-java.util.Collection-java.lang.Class-)
## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)

View File

@ -46,7 +46,6 @@
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.0</version>
</dependency>
</dependencies>
</project>

View File

@ -30,9 +30,13 @@ Use the Factory Method pattern when
## Known uses
* java.util.Calendar
* java.util.ResourceBundle
* java.text.NumberFormat#getInstance()
* [java.util.Calendar](http://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#getInstance--)
* [java.util.ResourceBundle](http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String-)
* [java.text.NumberFormat](http://docs.oracle.com/javase/8/docs/api/java/text/NumberFormat.html#getInstance--)
* [java.nio.charset.Charset](http://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html#forName-java.lang.String-)
* [java.net.URLStreamHandlerFactory](http://docs.oracle.com/javase/8/docs/api/java/net/URLStreamHandlerFactory.html#createURLStreamHandler-java.lang.String-)
* [java.util.EnumSet](https://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html#of-E-)
* [javax.xml.bind.JAXBContext](https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/JAXBContext.html#createMarshaller--)
## Credits

View File

@ -31,7 +31,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)
* [java.lang.Integer#valueOf(int)](http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#valueOf%28int%29) and similarly for Byte, Character and other wrapped types.
## Credits

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 145 KiB

View File

@ -1,319 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.1.9" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
realizations="true" associations="true" dependencies="false" nesting-relationships="true" router="FAN">
<class id="1" language="java" name="com.iluwatar.hexagonal.domain.LotteryTicket" project="hexagonal"
<class-diagram version="1.1.10" icons="true" automaticImage="PNG" always-add-relationships="false"
generalizations="true" realizations="true" associations="true" dependencies="false" nesting-relationships="true"
router="FAN">
<class id="1" language="java" name="com.iluwatar.hexagonal.notifications.StdOutNotifications" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/StdOutNotifications.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="167" width="235" x="731" y="122"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="2" language="java" name="com.iluwatar.hexagonal.banking.InMemoryBank" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/InMemoryBank.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="149" width="217" x="1006" y="122"/>
<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.hexagonal.domain.LotterySystem" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotterySystemImpl.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="167" width="421" x="1263" y="122"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="4" language="java" name="com.iluwatar.hexagonal.domain.LotteryTicket" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicket.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="169" width="270" x="2042" y="351"/>
<position height="167" width="278" x="1568" y="347"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<interface id="2" language="java" name="com.iluwatar.hexagonal.banking.WireTransfers" project="hexagonal"
<class id="5" language="java" name="com.iluwatar.hexagonal.database.InMemoryTicketRepository" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/database/InMemoryTicketRepository.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="149" width="265" x="1724" y="122"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<interface id="6" language="java" name="com.iluwatar.hexagonal.banking.WireTransfers" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/WireTransfers.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="115" width="215" x="1490" y="351"/>
<position height="113" width="217" x="1006" y="347"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<class id="3" language="java" name="com.iluwatar.hexagonal.administration.LotteryAdministrationImpl"
project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministrationImpl.java" binary="false"
<class id="7" language="java" name="com.iluwatar.hexagonal.domain.LotteryService" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleService.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="133" width="311" x="992" y="124"/>
<position height="113" width="421" x="2029" y="122"/>
<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.hexagonal.database.LotteryTicketRepository" project="hexagonal"
<interface id="8" language="java" name="com.iluwatar.hexagonal.database.LotteryTicketRepository" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/database/LotteryTicketRepository.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="133" width="257" x="1745" y="351"/>
<position height="131" width="265" x="1263" y="347"/>
<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.hexagonal.domain.LotteryConstants" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryConstants.java" binary="false"
<interface id="9" language="java" name="com.iluwatar.hexagonal.domain.LotterySystem" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotterySystem.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="169" width="227" x="205" y="124"/>
<position height="149" width="421" x="1886" y="347"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="6" language="java" name="com.iluwatar.hexagonal.domain.LotteryTicketId" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketId.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="115" width="140" x="508" y="124"/>
<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="7" language="java" name="com.iluwatar.hexagonal.domain.LotteryNumbers" project="hexagonal"
</interface>
<class id="10" language="java" name="com.iluwatar.hexagonal.domain.LotteryNumbers" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="277" width="206" x="2042" y="560"/>
<position height="275" width="209" x="1568" y="554"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="8" language="java" name="com.iluwatar.hexagonal.notifications.LotteryNotificationsImpl" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotificationsImpl.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="169" width="229" x="723" y="124"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="9" language="java" name="com.iluwatar.hexagonal.banking.WireTransfersImpl" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/WireTransfersImpl.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="151" width="215" x="1787" y="124"/>
<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="10" language="java" name="com.iluwatar.hexagonal.administration.LotteryAdministration"
<interface id="11" language="java" name="com.iluwatar.hexagonal.domain.LotteryAdministration"
project="hexagonal" file="/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministration.java"
binary="false" corner="BOTTOM_RIGHT">
<position height="115" width="311" x="426" y="351"/>
<position height="113" width="320" x="2808" y="347"/>
<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="11" language="java" name="com.iluwatar.hexagonal.domain.LotteryNumbers.RandomNumberGenerator"
<class id="12" language="java" name="com.iluwatar.hexagonal.domain.LotteryNumbers.RandomNumberGenerator"
project="hexagonal" file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryNumbers.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="115" width="188" x="2042" y="877"/>
<position height="113" width="189" x="1568" y="869"/>
<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="12" language="java" name="com.iluwatar.hexagonal.domain.LotteryTicketCheckResult" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketCheckResult.java" binary="false"
<class id="13" language="java" name="com.iluwatar.hexagonal.domain.LotteryAdministration" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="187" width="229" x="2352" y="124"/>
<position height="131" width="320" x="2490" y="122"/>
<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="13" language="java" name="com.iluwatar.hexagonal.domain.PlayerDetails" project="hexagonal"
<class id="14" language="java" name="com.iluwatar.hexagonal.domain.PlayerDetails" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/PlayerDetails.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="241" width="219" x="1106" y="560"/>
<position height="239" width="222" x="1019" y="554"/>
<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="14" language="java" name="com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository"
project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/database/LotteryTicketInMemoryRepository.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="151" width="257" x="2042" y="124"/>
<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="15" language="java" name="com.iluwatar.hexagonal.service.LotteryService" project="hexagonal"
<interface id="15" language="java" name="com.iluwatar.hexagonal.domain.LotteryService" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryService.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="97" width="404" x="1046" y="351"/>
<position height="95" width="421" x="2347" y="347"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</interface>
<enumeration id="16" language="java" name="com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult"
project="hexagonal" file="/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketCheckResult.java"
binary="false" corner="BOTTOM_RIGHT">
<position height="133" width="229" x="2352" y="351"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</enumeration>
<class id="17" language="java" name="com.iluwatar.hexagonal.App" project="hexagonal"
<class id="16" language="java" name="com.iluwatar.hexagonal.App" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java" binary="false" corner="BOTTOM_RIGHT">
<position height="133" width="217" x="169" y="351"/>
<position height="131" width="221" x="470" y="347"/>
<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="18" language="java" name="com.iluwatar.hexagonal.service.LotteryServiceImpl" project="hexagonal"
file="/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryServiceImpl.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="115" width="404" x="1343" y="124"/>
<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="19" language="java" name="com.iluwatar.hexagonal.notifications.LotteryNotifications"
<interface id="17" language="java" name="com.iluwatar.hexagonal.notifications.LotteryNotifications"
project="hexagonal" file="/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotifications.java"
binary="false" corner="BOTTOM_RIGHT">
<position height="151" width="229" x="777" y="351"/>
<position height="149" width="235" x="731" y="347"/>
<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>
<association id="20">
<association id="18">
<end type="SOURCE" refId="16" navigable="false">
<attribute id="19" name="PLAYERS"/>
<multiplicity id="20" minimum="0" maximum="2147483647"/>
</end>
<end type="TARGET" refId="14" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="21">
<end type="SOURCE" refId="3" navigable="false">
<attribute id="21" name="repository"/>
<multiplicity id="22" minimum="0" maximum="1"/>
<attribute id="22" name="wireTransfers"/>
<multiplicity id="23" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="6" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<realization id="24">
<end type="SOURCE" refId="5"/>
<end type="TARGET" refId="8"/>
</realization>
<nesting id="25">
<end type="SOURCE" refId="10"/>
<end type="TARGET" refId="12"/>
</nesting>
<association id="26">
<end type="SOURCE" refId="5" navigable="false">
<attribute id="27" name="tickets"/>
<multiplicity id="28" minimum="0" maximum="2147483647"/>
</end>
<end type="TARGET" refId="4" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="23">
<end type="SOURCE" refId="3" navigable="false">
<attribute id="24" name="notifications"/>
<multiplicity id="25" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="19" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="26">
<end type="SOURCE" refId="18" navigable="false">
<attribute id="27" name="notifications"/>
<multiplicity id="28" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="19" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="29">
<end type="SOURCE" refId="14" navigable="false">
<attribute id="30" name="tickets"/>
<multiplicity id="31" minimum="0" maximum="2147483647"/>
</end>
<end type="TARGET" refId="1" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<realization id="32">
<end type="SOURCE" refId="8"/>
<end type="TARGET" refId="19"/>
<realization id="29">
<end type="SOURCE" refId="1"/>
<end type="TARGET" refId="17"/>
</realization>
<realization id="33">
<end type="SOURCE" refId="18"/>
<realization id="30">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="9"/>
</realization>
<realization id="31">
<end type="SOURCE" refId="7"/>
<end type="TARGET" refId="15"/>
</realization>
<realization id="34">
<end type="SOURCE" refId="3"/>
<end type="TARGET" refId="10"/>
</realization>
<association id="35">
<end type="SOURCE" refId="18" navigable="false">
<attribute id="36" name="bank"/>
<multiplicity id="37" minimum="0" maximum="1"/>
<association id="32">
<end type="SOURCE" refId="4" navigable="false">
<attribute id="33" name="lotteryNumbers"/>
<multiplicity id="34" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="2" navigable="true"/>
<end type="TARGET" refId="10" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="38">
<end type="SOURCE" refId="18" navigable="false">
<attribute id="39" name="repository"/>
<multiplicity id="40" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="4" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="41">
<end type="SOURCE" refId="3" navigable="false">
<attribute id="42" name="bank"/>
<multiplicity id="43" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="2" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="44">
<end type="SOURCE" refId="12" navigable="false">
<attribute id="45" name="checkResult"/>
<multiplicity id="46" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="16" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<nesting id="47">
<end type="SOURCE" refId="12"/>
<end type="TARGET" refId="16"/>
</nesting>
<association id="48">
<end type="SOURCE" refId="17" navigable="false">
<attribute id="49" name="allPlayerDetails"/>
<multiplicity id="50" minimum="0" maximum="2147483647"/>
</end>
<end type="TARGET" refId="13" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="51">
<end type="SOURCE" refId="1" navigable="false">
<attribute id="52" name="playerDetails"/>
<multiplicity id="53" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="13" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="54">
<end type="SOURCE" refId="1" navigable="false">
<attribute id="55" name="lotteryNumbers"/>
<multiplicity id="56" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="7" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<realization id="57">
<end type="SOURCE" refId="14"/>
<end type="TARGET" refId="4"/>
</realization>
<nesting id="58">
<end type="SOURCE" refId="7"/>
<realization id="35">
<end type="SOURCE" refId="13"/>
<end type="TARGET" refId="11"/>
</nesting>
<realization id="59">
<end type="SOURCE" refId="9"/>
<end type="TARGET" refId="2"/>
</realization>
<association id="60">
<end type="SOURCE" refId="3" navigable="false">
<attribute id="61" name="service"/>
<multiplicity id="62" minimum="0" maximum="1"/>
<association id="36">
<end type="SOURCE" refId="13" navigable="false">
<attribute id="37" name="lotterySystem"/>
<multiplicity id="38" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="15" navigable="true"/>
<end type="TARGET" refId="9" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="39">
<end type="SOURCE" refId="7" navigable="false">
<attribute id="40" name="lotterySystem"/>
<multiplicity id="41" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="9" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="42">
<end type="SOURCE" refId="3" navigable="false">
<attribute id="43" name="repository"/>
<multiplicity id="44" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="8" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<realization id="45">
<end type="SOURCE" refId="2"/>
<end type="TARGET" refId="6"/>
</realization>
<association id="46">
<end type="SOURCE" refId="3" navigable="false">
<attribute id="47" name="notifications"/>
<multiplicity id="48" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="17" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="49">
<end type="SOURCE" refId="4" navigable="false">
<attribute id="50" name="playerDetails"/>
<multiplicity id="51" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="14" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"

View File

@ -39,5 +39,9 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -22,19 +22,12 @@
*/
package com.iluwatar.hexagonal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.iluwatar.hexagonal.administration.LotteryAdministration;
import com.iluwatar.hexagonal.administration.LotteryAdministrationImpl;
import com.iluwatar.hexagonal.banking.WireTransfersImpl;
import com.iluwatar.hexagonal.domain.LotteryConstants;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.PlayerDetails;
import com.iluwatar.hexagonal.service.LotteryService;
import com.iluwatar.hexagonal.service.LotteryServiceImpl;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.iluwatar.hexagonal.domain.LotteryAdministration;
import com.iluwatar.hexagonal.domain.LotteryService;
import com.iluwatar.hexagonal.module.LotteryTestingModule;
import com.iluwatar.hexagonal.sampledata.SampleData;
/**
*
@ -69,83 +62,22 @@ import com.iluwatar.hexagonal.service.LotteryServiceImpl;
*/
public class App {
private static final List<PlayerDetails> PLAYERS;
static {
PLAYERS = new ArrayList<>();
PLAYERS.add(PlayerDetails.create("john@google.com", "312-342", "+3242434242"));
PLAYERS.add(PlayerDetails.create("mary@google.com", "234-987", "+23452346"));
PLAYERS.add(PlayerDetails.create("steve@google.com", "833-836", "+63457543"));
PLAYERS.add(PlayerDetails.create("wayne@google.com", "319-826", "+24626"));
PLAYERS.add(PlayerDetails.create("johnie@google.com", "983-322", "+3635635"));
PLAYERS.add(PlayerDetails.create("andy@google.com", "934-734", "+0898245"));
PLAYERS.add(PlayerDetails.create("richard@google.com", "536-738", "+09845325"));
PLAYERS.add(PlayerDetails.create("kevin@google.com", "453-936", "+2423532"));
PLAYERS.add(PlayerDetails.create("arnold@google.com", "114-988", "+5646346524"));
PLAYERS.add(PlayerDetails.create("ian@google.com", "663-765", "+928394235"));
PLAYERS.add(PlayerDetails.create("robin@google.com", "334-763", "+35448"));
PLAYERS.add(PlayerDetails.create("ted@google.com", "735-964", "+98752345"));
PLAYERS.add(PlayerDetails.create("larry@google.com", "734-853", "+043842423"));
PLAYERS.add(PlayerDetails.create("calvin@google.com", "334-746", "+73294135"));
PLAYERS.add(PlayerDetails.create("jacob@google.com", "444-766", "+358042354"));
PLAYERS.add(PlayerDetails.create("edwin@google.com", "895-345", "+9752435"));
PLAYERS.add(PlayerDetails.create("mary@google.com", "760-009", "+34203542"));
PLAYERS.add(PlayerDetails.create("lolita@google.com", "425-907", "+9872342"));
PLAYERS.add(PlayerDetails.create("bruno@google.com", "023-638", "+673824122"));
PLAYERS.add(PlayerDetails.create("peter@google.com", "335-886", "+5432503945"));
PLAYERS.add(PlayerDetails.create("warren@google.com", "225-946", "+9872341324"));
PLAYERS.add(PlayerDetails.create("monica@google.com", "265-748", "+134124"));
PLAYERS.add(PlayerDetails.create("ollie@google.com", "190-045", "+34453452"));
PLAYERS.add(PlayerDetails.create("yngwie@google.com", "241-465", "+9897641231"));
PLAYERS.add(PlayerDetails.create("lars@google.com", "746-936", "+42345298345"));
PLAYERS.add(PlayerDetails.create("bobbie@google.com", "946-384", "+79831742"));
PLAYERS.add(PlayerDetails.create("tyron@google.com", "310-992", "+0498837412"));
PLAYERS.add(PlayerDetails.create("tyrell@google.com", "032-045", "+67834134"));
PLAYERS.add(PlayerDetails.create("nadja@google.com", "000-346", "+498723"));
PLAYERS.add(PlayerDetails.create("wendy@google.com", "994-989", "+987324454"));
PLAYERS.add(PlayerDetails.create("luke@google.com", "546-634", "+987642435"));
PLAYERS.add(PlayerDetails.create("bjorn@google.com", "342-874", "+7834325"));
PLAYERS.add(PlayerDetails.create("lisa@google.com", "024-653", "+980742154"));
PLAYERS.add(PlayerDetails.create("anton@google.com", "834-935", "+876423145"));
PLAYERS.add(PlayerDetails.create("bruce@google.com", "284-936", "+09843212345"));
PLAYERS.add(PlayerDetails.create("ray@google.com", "843-073", "+678324123"));
PLAYERS.add(PlayerDetails.create("ron@google.com", "637-738", "+09842354"));
PLAYERS.add(PlayerDetails.create("xavier@google.com", "143-947", "+375245"));
PLAYERS.add(PlayerDetails.create("harriet@google.com", "842-404", "+131243252"));
WireTransfersImpl wireTransfers = new WireTransfersImpl();
Random random = new Random();
for (int i = 0; i < PLAYERS.size(); i++) {
wireTransfers.setFunds(PLAYERS.get(i).getBankAccount(),
random.nextInt(LotteryConstants.PLAYER_MAX_SALDO));
}
}
/**
* Program entry point
*/
public static void main(String[] args) {
Injector injector = Guice.createInjector(new LotteryTestingModule());
// start new lottery round
LotteryAdministration administartion = new LotteryAdministrationImpl();
LotteryAdministration administartion = injector.getInstance(LotteryAdministration.class);
administartion.resetLottery();
// submit some lottery tickets
LotteryServiceImpl service = new LotteryServiceImpl();
submitTickets(service, 20);
LotteryService service = injector.getInstance(LotteryService.class);
SampleData.submitTickets(service, 20);
// perform lottery
administartion.performLottery();
}
private static void submitTickets(LotteryService lotteryService, int numTickets) {
for (int i = 0; i < numTickets; i++) {
LotteryTicket ticket = LotteryTicket.create(getRandomPlayerDetails(), LotteryNumbers.createRandom());
lotteryService.submitTicket(ticket);
}
}
private static PlayerDetails getRandomPlayerDetails() {
Random random = new Random();
int idx = random.nextInt(PLAYERS.size());
return PLAYERS.get(idx);
}
}

View File

@ -0,0 +1,84 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.administration;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.iluwatar.hexagonal.domain.LotteryAdministration;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryService;
import com.iluwatar.hexagonal.module.LotteryModule;
import com.iluwatar.hexagonal.sampledata.SampleData;
import java.util.Scanner;
/**
* Console interface for lottery administration
*/
public class ConsoleAdministration {
/**
* Program entry point
*/
public static void main(String[] args) {
Injector injector = Guice.createInjector(new LotteryModule());
LotteryAdministration administartion = injector.getInstance(LotteryAdministration.class);
LotteryService service = injector.getInstance(LotteryService.class);
SampleData.submitTickets(service, 20);
Scanner scanner = new Scanner(System.in);
boolean exit = false;
while (!exit) {
printMainMenu();
String cmd = readString(scanner);
if (cmd.equals("1")) {
administartion.getAllSubmittedTickets().forEach((k,v)->System.out.println("Key: " + k + " Value: " + v));
} else if (cmd.equals("2")) {
LotteryNumbers numbers = administartion.performLottery();
System.out.println("The winning numbers: " + numbers);
System.out.println("Time to reset the database for next round, eh?");
} else if (cmd.equals("3")) {
administartion.resetLottery();
System.out.println("The lottery ticket database was cleared.");
} else if (cmd.equals("4")) {
exit = true;
} else {
System.out.println("Unknown command: " + cmd);
}
}
}
private static void printMainMenu() {
System.out.println("");
System.out.println("### Lottery Administration Console ###");
System.out.println("(1) Show all submitted tickets");
System.out.println("(2) Perform lottery draw");
System.out.println("(3) Reset lottery ticket database");
System.out.println("(4) Exit");
}
private static String readString(Scanner scanner) {
System.out.print("> ");
String cmd = scanner.next();
return cmd;
}
}

View File

@ -32,7 +32,7 @@ import com.iluwatar.hexagonal.domain.LotteryConstants;
* Banking implementation
*
*/
public class WireTransfersImpl implements WireTransfers {
public class InMemoryBank implements WireTransfers {
private static Map<String, Integer> accounts = new HashMap<>();

View File

@ -34,7 +34,7 @@ import com.iluwatar.hexagonal.domain.LotteryTicketId;
* Mock database for lottery tickets.
*
*/
public class LotteryTicketInMemoryRepository implements LotteryTicketRepository {
public class InMemoryTicketRepository implements LotteryTicketRepository {
private static Map<LotteryTicketId, LotteryTicket> tickets = new HashMap<>();

View File

@ -20,67 +20,72 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.administration;
package com.iluwatar.hexagonal.domain;
import com.google.inject.Inject;
import com.iluwatar.hexagonal.banking.WireTransfers;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import com.iluwatar.hexagonal.notifications.LotteryNotifications;
import java.util.Map;
import com.iluwatar.hexagonal.banking.WireTransfers;
import com.iluwatar.hexagonal.banking.WireTransfersImpl;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository;
import com.iluwatar.hexagonal.domain.LotteryConstants;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult;
import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.iluwatar.hexagonal.notifications.LotteryNotifications;
import com.iluwatar.hexagonal.notifications.LotteryNotificationsImpl;
import com.iluwatar.hexagonal.service.LotteryService;
import com.iluwatar.hexagonal.service.LotteryServiceImpl;
/**
*
* Lottery administration implementation
*
*/
public class LotteryAdministrationImpl implements LotteryAdministration {
public class LotteryAdministration {
private final LotteryTicketRepository repository;
private final LotteryService service = new LotteryServiceImpl();
private final LotteryNotifications notifications = new LotteryNotificationsImpl();
private final WireTransfers bank = new WireTransfersImpl();
public LotteryAdministrationImpl() {
repository = new LotteryTicketInMemoryRepository();
private final LotteryNotifications notifications;
private final WireTransfers wireTransfers;
private final LotteryTicketChecker checker;
/**
* Constructor
*/
@Inject
public LotteryAdministration(LotteryTicketRepository repository, LotteryNotifications notifications,
WireTransfers wireTransfers) {
this.repository = repository;
this.notifications = notifications;
this.wireTransfers = wireTransfers;
this.checker = new LotteryTicketChecker(this.repository);
}
@Override
/**
* Get all the lottery tickets submitted for lottery
*/
public Map<LotteryTicketId, LotteryTicket> getAllSubmittedTickets() {
return repository.findAll();
}
@Override
/**
* Draw lottery numbers
*/
public LotteryNumbers performLottery() {
LotteryNumbers numbers = LotteryNumbers.createRandom();
Map<LotteryTicketId, LotteryTicket> tickets = getAllSubmittedTickets();
for (LotteryTicketId id: tickets.keySet()) {
LotteryTicketCheckResult result = service.checkTicketForPrize(id, numbers);
if (result.getResult().equals(CheckResult.WIN_PRIZE)) {
boolean transferred = bank.transferFunds(LotteryConstants.PRIZE_AMOUNT, LotteryConstants.SERVICE_BANK_ACCOUNT,
tickets.get(id).getPlayerDetails().getBankAccount());
for (LotteryTicketId id : tickets.keySet()) {
LotteryTicketCheckResult result = checker.checkTicketForPrize(id, numbers);
if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.WIN_PRIZE)) {
boolean transferred = wireTransfers.transferFunds(LotteryConstants.PRIZE_AMOUNT,
LotteryConstants.SERVICE_BANK_ACCOUNT, tickets.get(id).getPlayerDetails().getBankAccount());
if (transferred) {
notifications.notifyPrize(tickets.get(id).getPlayerDetails(), LotteryConstants.PRIZE_AMOUNT);
} else {
notifications.notifyPrizeError(tickets.get(id).getPlayerDetails(), LotteryConstants.PRIZE_AMOUNT);
}
} else if (result.getResult().equals(CheckResult.NO_PRIZE)) {
} else if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.NO_PRIZE)) {
notifications.notifyNoWin(tickets.get(id).getPlayerDetails());
}
}
return numbers;
}
@Override
/**
* Begin new lottery round
*/
public void resetLottery() {
repository.deleteAll();
}

View File

@ -93,6 +93,11 @@ public class LotteryNumbers {
}
}
@Override
public String toString() {
return "LotteryNumbers{" + "numbers=" + numbers + '}';
}
/**
*
* Helper class for generating random numbers.

View File

@ -20,47 +20,45 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.service;
package com.iluwatar.hexagonal.domain;
import com.google.inject.Inject;
import com.iluwatar.hexagonal.banking.WireTransfers;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import com.iluwatar.hexagonal.notifications.LotteryNotifications;
import java.util.Optional;
import com.iluwatar.hexagonal.banking.WireTransfers;
import com.iluwatar.hexagonal.banking.WireTransfersImpl;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository;
import com.iluwatar.hexagonal.domain.LotteryConstants;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult;
import com.iluwatar.hexagonal.notifications.LotteryNotifications;
import com.iluwatar.hexagonal.notifications.LotteryNotificationsImpl;
/**
*
* Implementation for lottery service
*
*/
public class LotteryServiceImpl implements LotteryService {
public class LotteryService {
private final LotteryTicketRepository repository;
private final WireTransfers bank = new WireTransfersImpl();
private final LotteryNotifications notifications = new LotteryNotificationsImpl();
private final LotteryNotifications notifications;
private final WireTransfers wireTransfers;
private final LotteryTicketChecker checker;
/**
* Constructor
*/
public LotteryServiceImpl() {
repository = new LotteryTicketInMemoryRepository();
@Inject
public LotteryService(LotteryTicketRepository repository, LotteryNotifications notifications,
WireTransfers wireTransfers) {
this.repository = repository;
this.notifications = notifications;
this.wireTransfers = wireTransfers;
this.checker = new LotteryTicketChecker(this.repository);
}
@Override
/**
* Submit lottery ticket to participate in the lottery
*/
public Optional<LotteryTicketId> submitTicket(LotteryTicket ticket) {
boolean result = bank.transferFunds(LotteryConstants.TICKET_PRIZE, ticket.getPlayerDetails().getBankAccount(),
LotteryConstants.SERVICE_BANK_ACCOUNT);
boolean result = wireTransfers.transferFunds(LotteryConstants.TICKET_PRIZE,
ticket.getPlayerDetails().getBankAccount(), LotteryConstants.SERVICE_BANK_ACCOUNT);
if (result == false) {
notifications.notifyTicketSubmitError(ticket.getPlayerDetails());
return Optional.empty();
@ -72,17 +70,10 @@ public class LotteryServiceImpl implements LotteryService {
return optional;
}
@Override
/**
* Check if lottery ticket has won
*/
public LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers) {
Optional<LotteryTicket> optional = repository.findById(id);
if (optional.isPresent()) {
if (optional.get().getNumbers().equals(winningNumbers)) {
return new LotteryTicketCheckResult(CheckResult.WIN_PRIZE, 1000);
} else {
return new LotteryTicketCheckResult(CheckResult.NO_PRIZE);
}
} else {
return new LotteryTicketCheckResult(CheckResult.TICKET_NOT_SUBMITTED);
}
return checker.checkTicketForPrize(id, winningNumbers);
}
}

View File

@ -61,6 +61,11 @@ public class LotteryTicket {
return lotteryNumbers;
}
@Override
public String toString() {
return playerDetails.toString() + " " + lotteryNumbers.toString();
}
@Override
public int hashCode() {
final int prime = 31;

View File

@ -0,0 +1,55 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.domain;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import java.util.Optional;
/**
* Lottery ticket checker
*/
public class LotteryTicketChecker {
private final LotteryTicketRepository repository;
public LotteryTicketChecker(LotteryTicketRepository repository) {
this.repository = repository;
}
/**
* Check if lottery ticket has won
*/
public LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers) {
Optional<LotteryTicket> optional = repository.findById(id);
if (optional.isPresent()) {
if (optional.get().getNumbers().equals(winningNumbers)) {
return new LotteryTicketCheckResult(LotteryTicketCheckResult.CheckResult.WIN_PRIZE, 1000);
} else {
return new LotteryTicketCheckResult(LotteryTicketCheckResult.CheckResult.NO_PRIZE);
}
} else {
return new LotteryTicketCheckResult(LotteryTicketCheckResult.CheckResult.TICKET_NOT_SUBMITTED);
}
}
}

View File

@ -22,20 +22,49 @@
*/
package com.iluwatar.hexagonal.domain;
import java.util.UUID;
/**
* Lottery ticked id
*/
public class LotteryTicketId {
private final UUID id;
private static volatile int numAllocated;
private final int id;
public LotteryTicketId() {
id = UUID.randomUUID();
this.id = numAllocated + 1;
numAllocated++;
}
public UUID getId() {
public LotteryTicketId(int id) {
this.id = id;
}
public int getId() {
return id;
}
@Override
public String toString() {
return String.format("%d", id);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LotteryTicketId that = (LotteryTicketId) o;
return id == that.id;
}
@Override
public int hashCode() {
return id;
}
}

View File

@ -70,6 +70,13 @@ public class PlayerDetails {
return phoneNumber;
}
@Override
public String toString() {
return "PlayerDetails{" + "emailAddress='" + emailAddress + '\''
+ ", bankAccountNumber='" + bankAccountNumber + '\''
+ ", phoneNumber='" + phoneNumber + '\'' + '}';
}
@Override
public int hashCode() {
final int prime = 31;

View File

@ -0,0 +1,43 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.module;
import com.google.inject.AbstractModule;
import com.iluwatar.hexagonal.banking.InMemoryBank;
import com.iluwatar.hexagonal.banking.WireTransfers;
import com.iluwatar.hexagonal.database.InMemoryTicketRepository;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import com.iluwatar.hexagonal.notifications.LotteryNotifications;
import com.iluwatar.hexagonal.notifications.StdOutNotifications;
/**
* Guice module for binding production dependencies
*/
public class LotteryModule extends AbstractModule {
@Override
protected void configure() {
bind(LotteryTicketRepository.class).to(InMemoryTicketRepository.class);
bind(LotteryNotifications.class).to(StdOutNotifications.class);
bind(WireTransfers.class).to(InMemoryBank.class);
}
}

View File

@ -20,29 +20,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.service;
package com.iluwatar.hexagonal.module;
import java.util.Optional;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.google.inject.AbstractModule;
import com.iluwatar.hexagonal.banking.InMemoryBank;
import com.iluwatar.hexagonal.banking.WireTransfers;
import com.iluwatar.hexagonal.database.InMemoryTicketRepository;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import com.iluwatar.hexagonal.notifications.LotteryNotifications;
import com.iluwatar.hexagonal.notifications.StdOutNotifications;
/**
*
* Interface for submitting and checking lottery tickets.
*
* Guice module for testing dependencies
*/
public interface LotteryService {
/**
* Submit lottery ticket to participate in the lottery
*/
Optional<LotteryTicketId> submitTicket(LotteryTicket ticket);
/**
* Check if lottery ticket has won
*/
LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers);
public class LotteryTestingModule extends AbstractModule {
@Override
protected void configure() {
bind(LotteryTicketRepository.class).to(InMemoryTicketRepository.class);
bind(LotteryNotifications.class).to(StdOutNotifications.class);
bind(WireTransfers.class).to(InMemoryBank.class);
}
}

View File

@ -24,7 +24,7 @@ package com.iluwatar.hexagonal.notifications;
import com.iluwatar.hexagonal.domain.PlayerDetails;
public class LotteryNotificationsImpl implements LotteryNotifications {
public class StdOutNotifications implements LotteryNotifications {
@Override
public void notifyTicketSubmitted(PlayerDetails details) {

View File

@ -0,0 +1,107 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.sampledata;
import com.iluwatar.hexagonal.banking.InMemoryBank;
import com.iluwatar.hexagonal.domain.LotteryConstants;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryService;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.PlayerDetails;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Utilities for creating sample lottery tickets
*/
public class SampleData {
private static final List<PlayerDetails> PLAYERS;
static {
PLAYERS = new ArrayList<>();
PLAYERS.add(PlayerDetails.create("john@google.com", "312-342", "+3242434242"));
PLAYERS.add(PlayerDetails.create("mary@google.com", "234-987", "+23452346"));
PLAYERS.add(PlayerDetails.create("steve@google.com", "833-836", "+63457543"));
PLAYERS.add(PlayerDetails.create("wayne@google.com", "319-826", "+24626"));
PLAYERS.add(PlayerDetails.create("johnie@google.com", "983-322", "+3635635"));
PLAYERS.add(PlayerDetails.create("andy@google.com", "934-734", "+0898245"));
PLAYERS.add(PlayerDetails.create("richard@google.com", "536-738", "+09845325"));
PLAYERS.add(PlayerDetails.create("kevin@google.com", "453-936", "+2423532"));
PLAYERS.add(PlayerDetails.create("arnold@google.com", "114-988", "+5646346524"));
PLAYERS.add(PlayerDetails.create("ian@google.com", "663-765", "+928394235"));
PLAYERS.add(PlayerDetails.create("robin@google.com", "334-763", "+35448"));
PLAYERS.add(PlayerDetails.create("ted@google.com", "735-964", "+98752345"));
PLAYERS.add(PlayerDetails.create("larry@google.com", "734-853", "+043842423"));
PLAYERS.add(PlayerDetails.create("calvin@google.com", "334-746", "+73294135"));
PLAYERS.add(PlayerDetails.create("jacob@google.com", "444-766", "+358042354"));
PLAYERS.add(PlayerDetails.create("edwin@google.com", "895-345", "+9752435"));
PLAYERS.add(PlayerDetails.create("mary@google.com", "760-009", "+34203542"));
PLAYERS.add(PlayerDetails.create("lolita@google.com", "425-907", "+9872342"));
PLAYERS.add(PlayerDetails.create("bruno@google.com", "023-638", "+673824122"));
PLAYERS.add(PlayerDetails.create("peter@google.com", "335-886", "+5432503945"));
PLAYERS.add(PlayerDetails.create("warren@google.com", "225-946", "+9872341324"));
PLAYERS.add(PlayerDetails.create("monica@google.com", "265-748", "+134124"));
PLAYERS.add(PlayerDetails.create("ollie@google.com", "190-045", "+34453452"));
PLAYERS.add(PlayerDetails.create("yngwie@google.com", "241-465", "+9897641231"));
PLAYERS.add(PlayerDetails.create("lars@google.com", "746-936", "+42345298345"));
PLAYERS.add(PlayerDetails.create("bobbie@google.com", "946-384", "+79831742"));
PLAYERS.add(PlayerDetails.create("tyron@google.com", "310-992", "+0498837412"));
PLAYERS.add(PlayerDetails.create("tyrell@google.com", "032-045", "+67834134"));
PLAYERS.add(PlayerDetails.create("nadja@google.com", "000-346", "+498723"));
PLAYERS.add(PlayerDetails.create("wendy@google.com", "994-989", "+987324454"));
PLAYERS.add(PlayerDetails.create("luke@google.com", "546-634", "+987642435"));
PLAYERS.add(PlayerDetails.create("bjorn@google.com", "342-874", "+7834325"));
PLAYERS.add(PlayerDetails.create("lisa@google.com", "024-653", "+980742154"));
PLAYERS.add(PlayerDetails.create("anton@google.com", "834-935", "+876423145"));
PLAYERS.add(PlayerDetails.create("bruce@google.com", "284-936", "+09843212345"));
PLAYERS.add(PlayerDetails.create("ray@google.com", "843-073", "+678324123"));
PLAYERS.add(PlayerDetails.create("ron@google.com", "637-738", "+09842354"));
PLAYERS.add(PlayerDetails.create("xavier@google.com", "143-947", "+375245"));
PLAYERS.add(PlayerDetails.create("harriet@google.com", "842-404", "+131243252"));
InMemoryBank wireTransfers = new InMemoryBank();
Random random = new Random();
for (int i = 0; i < PLAYERS.size(); i++) {
wireTransfers.setFunds(PLAYERS.get(i).getBankAccount(),
random.nextInt(LotteryConstants.PLAYER_MAX_SALDO));
}
}
/**
* Inserts lottery tickets into the database based on the sample data
*/
public static void submitTickets(LotteryService lotteryService, int numTickets) {
for (int i = 0; i < numTickets; i++) {
LotteryTicket ticket = LotteryTicket.create(getRandomPlayerDetails(), LotteryNumbers.createRandom());
lotteryService.submitTicket(ticket);
}
}
private static PlayerDetails getRandomPlayerDetails() {
Random random = new Random();
int idx = random.nextInt(PLAYERS.size());
return PLAYERS.get(idx);
}
}

View File

@ -0,0 +1,135 @@
/**
* The MIT License
* Copyright (c) 2014 Ilkka Seppälä
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.service;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.iluwatar.hexagonal.banking.WireTransfers;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryService;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.iluwatar.hexagonal.domain.PlayerDetails;
import com.iluwatar.hexagonal.module.LotteryModule;
import java.util.HashSet;
import java.util.Optional;
import java.util.Scanner;
import java.util.Set;
/**
* Console interface for lottery players
*/
public class ConsoleLottery {
/**
* Program entry point
*/
public static void main(String[] args) {
Injector injector = Guice.createInjector(new LotteryModule());
LotteryService service = injector.getInstance(LotteryService.class);
WireTransfers bank = injector.getInstance(WireTransfers.class);
Scanner scanner = new Scanner(System.in);
boolean exit = false;
while (!exit) {
printMainMenu();
String cmd = readString(scanner);
if (cmd.equals("1")) {
System.out.println("What is the account number?");
String account = readString(scanner);
System.out.println(String.format("The account %s has %d credits.", account, bank.getFunds(account)));
} else if (cmd.equals("2")) {
System.out.println("What is the account number?");
String account = readString(scanner);
System.out.println("How many credits do you want to deposit?");
String amount = readString(scanner);
bank.setFunds(account, Integer.parseInt(amount));
System.out.println(String.format("The account %s now has %d credits.", account, bank.getFunds(account)));
} else if (cmd.equals("3")) {
System.out.println("What is your email address?");
String email = readString(scanner);
System.out.println("What is your bank account number?");
String account = readString(scanner);
System.out.println("What is your phone number?");
String phone = readString(scanner);
PlayerDetails details = PlayerDetails.create(email, account, phone);
System.out.println("Give 4 comma separated lottery numbers?");
String numbers = readString(scanner);
String[] parts = numbers.split(",");
Set<Integer> chosen = new HashSet<>();
for (int i = 0; i < 4; i++) {
chosen.add(Integer.parseInt(parts[i]));
}
LotteryNumbers lotteryNumbers = LotteryNumbers.create(chosen);
LotteryTicket lotteryTicket = LotteryTicket.create(details, lotteryNumbers);
Optional<LotteryTicketId> id = service.submitTicket(lotteryTicket);
if (id.isPresent()) {
System.out.println("Submitted lottery ticket with id: " + id.get());
} else {
System.out.println("Failed submitting lottery ticket - please try again.");
}
} else if (cmd.equals("4")) {
System.out.println("What is the ID of the lottery ticket?");
String id = readString(scanner);
System.out.println("Give the 4 comma separated winning numbers?");
String numbers = readString(scanner);
String[] parts = numbers.split(",");
Set<Integer> winningNumbers = new HashSet<>();
for (int i = 0; i < 4; i++) {
winningNumbers.add(Integer.parseInt(parts[i]));
}
LotteryTicketCheckResult result = service.checkTicketForPrize(
new LotteryTicketId(Integer.parseInt(id)), LotteryNumbers.create(winningNumbers));
if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.WIN_PRIZE)) {
System.out.println("Congratulations! The lottery ticket has won!");
} else if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.NO_PRIZE)) {
System.out.println("Unfortunately the lottery ticket did not win.");
} else {
System.out.println("Such lottery ticket has not been submitted.");
}
} else if (cmd.equals("5")) {
exit = true;
} else {
System.out.println("Unknown command");
}
}
}
private static void printMainMenu() {
System.out.println("");
System.out.println("### Lottery Service Console ###");
System.out.println("(1) Query lottery account funds");
System.out.println("(2) Add funds to lottery account");
System.out.println("(3) Submit ticket");
System.out.println("(4) Check ticket");
System.out.println("(5) Exit");
}
private static String readString(Scanner scanner) {
System.out.print("> ");
String cmd = scanner.next();
return cmd;
}
}

View File

@ -34,7 +34,7 @@ import org.junit.Test;
*/
public class WireTransfersTest {
private final WireTransfers bank = new WireTransfersImpl();
private final WireTransfers bank = new InMemoryBank();
@Test
public void testInit() {

View File

@ -30,8 +30,6 @@ import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.iluwatar.hexagonal.test.LotteryTestUtils;
@ -43,7 +41,7 @@ import com.iluwatar.hexagonal.test.LotteryTestUtils;
*/
public class LotteryTicketRepositoryTest {
private final LotteryTicketRepository repository = new LotteryTicketInMemoryRepository();
private final LotteryTicketRepository repository = new InMemoryTicketRepository();
@Before
public void clear() {
@ -52,7 +50,7 @@ public class LotteryTicketRepositoryTest {
@Test
public void testCrudOperations() {
LotteryTicketRepository repository = new LotteryTicketInMemoryRepository();
LotteryTicketRepository repository = new InMemoryTicketRepository();
assertEquals(repository.findAll().size(), 0);
LotteryTicket ticket = LotteryTestUtils.createLotteryTicket();
Optional<LotteryTicketId> id = repository.save(ticket);

View File

@ -20,7 +20,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.lottery;
package com.iluwatar.hexagonal.domain;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@ -30,22 +30,15 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.iluwatar.hexagonal.module.LotteryTestingModule;
import org.junit.Before;
import org.junit.Test;
import com.iluwatar.hexagonal.administration.LotteryAdministration;
import com.iluwatar.hexagonal.administration.LotteryAdministrationImpl;
import com.iluwatar.hexagonal.banking.WireTransfers;
import com.iluwatar.hexagonal.banking.WireTransfersImpl;
import com.iluwatar.hexagonal.database.LotteryTicketRepository;
import com.iluwatar.hexagonal.database.LotteryTicketInMemoryRepository;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult;
import com.iluwatar.hexagonal.domain.LotteryTicketCheckResult.CheckResult;
import com.iluwatar.hexagonal.domain.LotteryTicketId;
import com.iluwatar.hexagonal.service.LotteryService;
import com.iluwatar.hexagonal.service.LotteryServiceImpl;
import com.iluwatar.hexagonal.test.LotteryTestUtils;
/**
@ -55,25 +48,30 @@ import com.iluwatar.hexagonal.test.LotteryTestUtils;
*/
public class LotteryTest {
private final LotteryAdministration admin = new LotteryAdministrationImpl();
private final LotteryService service = new LotteryServiceImpl();
private final LotteryTicketRepository repository = new LotteryTicketInMemoryRepository();
private final WireTransfers wireTransfers = new WireTransfersImpl();
private Injector injector;
@Inject
private LotteryAdministration administration;
@Inject
private LotteryService service;
@Inject
private WireTransfers wireTransfers;
public LotteryTest() {
this.injector = Guice.createInjector(new LotteryTestingModule());
}
@Before
public void clear() {
repository.deleteAll();
public void setup() {
injector.injectMembers(this);
// add funds to the test player's bank account
wireTransfers.setFunds("123-12312", 100);
}
@Test
public void testLottery() {
// setup bank account with funds
wireTransfers.setFunds("123-12312", 100);
// admin resets the lottery
admin.resetLottery();
assertEquals(admin.getAllSubmittedTickets().size(), 0);
administration.resetLottery();
assertEquals(administration.getAllSubmittedTickets().size(), 0);
// players submit the lottery tickets
Optional<LotteryTicketId> ticket1 = service.submitTicket(LotteryTestUtils.createLotteryTicket("cvt@bbb.com",
@ -85,19 +83,19 @@ public class LotteryTest {
Optional<LotteryTicketId> ticket3 = service.submitTicket(LotteryTestUtils.createLotteryTicket("arg@boo.com",
"123-12312", "+32421255", new HashSet<>(Arrays.asList(6, 8, 13, 19))));
assertTrue(ticket3.isPresent());
assertEquals(admin.getAllSubmittedTickets().size(), 3);
assertEquals(administration.getAllSubmittedTickets().size(), 3);
// perform lottery
LotteryNumbers winningNumbers = admin.performLottery();
LotteryNumbers winningNumbers = administration.performLottery();
// cheat a bit for testing sake, use winning numbers to submit another ticket
Optional<LotteryTicketId> ticket4 = service.submitTicket(LotteryTestUtils.createLotteryTicket("lucky@orb.com",
"123-12312", "+12421255", winningNumbers.getNumbers()));
assertTrue(ticket4.isPresent());
assertEquals(admin.getAllSubmittedTickets().size(), 4);
assertEquals(administration.getAllSubmittedTickets().size(), 4);
// check winners
Map<LotteryTicketId, LotteryTicket> tickets = admin.getAllSubmittedTickets();
Map<LotteryTicketId, LotteryTicket> tickets = administration.getAllSubmittedTickets();
for (LotteryTicketId id: tickets.keySet()) {
LotteryTicketCheckResult checkResult = service.checkTicketForPrize(id, winningNumbers);
assertTrue(checkResult.getResult() != CheckResult.TICKET_NOT_SUBMITTED);

View File

@ -20,34 +20,26 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.hexagonal.administration;
package com.iluwatar.hexagonal.domain;
import java.util.Map;
import org.junit.Test;
import com.iluwatar.hexagonal.domain.LotteryNumbers;
import com.iluwatar.hexagonal.domain.LotteryTicket;
import com.iluwatar.hexagonal.domain.LotteryTicketId;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
*
* Administrator interface for lottery service.
*
* Tests for lottery ticket id
*/
public interface LotteryAdministration {
/**
* Get all the lottery tickets submitted for lottery
*/
Map<LotteryTicketId, LotteryTicket> getAllSubmittedTickets();
/**
* Draw lottery numbers
*/
LotteryNumbers performLottery();
/**
* Begin new lottery round
*/
void resetLottery();
public class LotteryTicketIdTest {
@Test
public void testEquals() {
LotteryTicketId ticketId1 = new LotteryTicketId();
LotteryTicketId ticketId2 = new LotteryTicketId();
LotteryTicketId ticketId3 = new LotteryTicketId();
assertFalse(ticketId1.equals(ticketId2));
assertFalse(ticketId2.equals(ticketId3));
LotteryTicketId ticketId4 = new LotteryTicketId(ticketId1.getId());
assertTrue(ticketId1.equals(ticketId4));
}
}

View File

@ -26,6 +26,13 @@ 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
## Real world examples
* [java.util.Pattern](http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)
* [java.text.Normalizer](http://docs.oracle.com/javase/8/docs/api/java/text/Normalizer.html)
* All subclasses of [java.text.Format](http://docs.oracle.com/javase/8/docs/api/java/text/Format.html)
* [javax.el.ELResolver](http://docs.oracle.com/javaee/7/api/javax/el/ELResolver.html)
## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)

View File

@ -30,6 +30,7 @@ Use the Iterator pattern
## Real world examples
* [java.util.Iterator](http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html)
* [java.util.Enumeration](http://docs.oracle.com/javase/8/docs/api/java/util/Enumeration.html)
## Credits

View File

@ -25,6 +25,14 @@ Use the Mediator pattern when
* 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
## Real world examples
* All scheduleXXX() methods of [java.util.Timer](http://docs.oracle.com/javase/8/docs/api/java/util/Timer.html)
* [java.util.concurrent.Executor#execute()](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html#execute-java.lang.Runnable-)
* submit() and invokeXXX() methods of [java.util.concurrent.ExecutorService](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html)
* scheduleXXX() methods of [java.util.concurrent.ScheduledExecutorService](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html)
* [java.lang.reflect.Method#invoke()](http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#invoke-java.lang.Object-java.lang.Object...-)
## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)

View File

@ -36,6 +36,8 @@ Use the Observer pattern in any of the following situations
## Real world examples
* [java.util.Observer](http://docs.oracle.com/javase/8/docs/api/java/util/Observer.html)
* [java.util.EventListener](http://docs.oracle.com/javase/8/docs/api/java/util/EventListener.html)
* [javax.servlet.http.HttpSessionBindingListener](http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSessionBindingListener.html)
## Credits

13
pom.xml
View File

@ -17,16 +17,15 @@
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.13.0-SNAPSHOT</version>
<packaging>pom</packaging>
<inceptionYear>2014</inceptionYear>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hibernate.version>5.0.1.Final</hibernate.version>
@ -48,6 +47,7 @@
<apache-httpcomponents.version>4.5.2</apache-httpcomponents.version>
<htmlunit.version>2.22</htmlunit.version>
<urm.version>1.4.1</urm.version>
<guice.version>4.0</guice.version>
</properties>
<modules>
<module>abstract-factory</module>
@ -238,6 +238,11 @@
<version>${htmlunit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${guice.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -32,6 +32,9 @@ Use the Singleton pattern when
## Real world examples
* [java.lang.Runtime#getRuntime()](http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#getRuntime%28%29)
* [java.awt.Desktop#getDesktop()](http://docs.oracle.com/javase/8/docs/api/java/awt/Desktop.html#getDesktop--)
* [java.lang.System#getSecurityManager()](http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getSecurityManager--)
## Credits

View File

@ -26,6 +26,11 @@ Use the State pattern in either of the following cases
* an object's behavior depends on its state, and it must change its behavior at run-time depending on that state
* operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects.
## Real world examples
* [javax.faces.lifecycle.Lifecycle#execute()](http://docs.oracle.com/javaee/7/api/javax/faces/lifecycle/Lifecycle.html#execute-javax.faces.context.FacesContext-) controlled by [FacesServlet](http://docs.oracle.com/javaee/7/api/javax/faces/webapp/FacesServlet.html), the behavior is dependent on current phase of lifecycle.
* [JDiameter - Diameter State Machine](https://github.com/npathai/jdiameter/blob/master/core/jdiameter/api/src/main/java/org/jdiameter/api/app/State.java)
## Credits
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)

View File

@ -28,6 +28,9 @@ Use the Visitor pattern when
## Real world examples
* [Apache Wicket](https://github.com/apache/wicket) component tree, see [MarkupContainer](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java)
* [javax.lang.model.element.AnnotationValue](http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/AnnotationValue.html) and [AnnotationValueVisitor](http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/AnnotationValueVisitor.html)
* [javax.lang.model.element.Element](http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/Element.html) and [Element Visitor](http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/ElementVisitor.html)
* [java.nio.file.FileVisitor](http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileVisitor.html)
## Credits