From 121ed3cca896d5870225565e50142c23f2cd4f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 10 Sep 2016 07:56:37 +0300 Subject: [PATCH] Hexagonal pattern: Move lottery administration and service to the core. Introduce console interfaces for players and administartors. --- hexagonal/etc/hexagonal.ucls | 8 +-- .../main/java/com/iluwatar/hexagonal/App.java | 4 +- .../com/iluwatar/hexagonal/LotteryModule.java | 1 - .../administration/ConsoleAdministration.java | 7 ++ .../administration/LotteryAdministration.java | 67 ------------------- ...System.java => LotteryAdministration.java} | 51 +++----------- .../{service => domain}/LotteryService.java | 33 +++++++-- .../domain/LotteryTicketChecker.java | 33 +++++++++ .../hexagonal/service/ConsoleLottery.java | 7 ++ .../hexagonal/LotteryTestingModule.java | 1 - .../hexagonal/domain/LotteryTest.java | 28 ++++---- 11 files changed, 103 insertions(+), 137 deletions(-) create mode 100644 hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java delete mode 100644 hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministration.java rename hexagonal/src/main/java/com/iluwatar/hexagonal/domain/{LotterySystem.java => LotteryAdministration.java} (64%) rename hexagonal/src/main/java/com/iluwatar/hexagonal/{service => domain}/LotteryService.java (55%) create mode 100644 hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketChecker.java create mode 100644 hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java diff --git a/hexagonal/etc/hexagonal.ucls b/hexagonal/etc/hexagonal.ucls index f698c0dd2..0318576c2 100644 --- a/hexagonal/etc/hexagonal.ucls +++ b/hexagonal/etc/hexagonal.ucls @@ -62,7 +62,7 @@ - @@ -102,7 +102,7 @@ - @@ -122,7 +122,7 @@ - @@ -142,7 +142,7 @@ - diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java index a1bb26454..83ae15032 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java @@ -28,13 +28,13 @@ import java.util.Random; import com.google.inject.Guice; import com.google.inject.Injector; -import com.iluwatar.hexagonal.administration.LotteryAdministration; +import com.iluwatar.hexagonal.domain.LotteryAdministration; import com.iluwatar.hexagonal.banking.InMemoryBank; 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.domain.LotteryService; /** * diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/LotteryModule.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/LotteryModule.java index 992e66357..dbaf494c2 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/LotteryModule.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/LotteryModule.java @@ -29,7 +29,6 @@ import com.iluwatar.hexagonal.database.InMemoryTicketRepository; import com.iluwatar.hexagonal.database.LotteryTicketRepository; import com.iluwatar.hexagonal.notifications.LotteryNotifications; import com.iluwatar.hexagonal.notifications.StdOutNotifications; -import com.iluwatar.hexagonal.service.LotteryService; /** * Guice module for binding production dependencies diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java new file mode 100644 index 000000000..5238edd24 --- /dev/null +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java @@ -0,0 +1,7 @@ +package com.iluwatar.hexagonal.administration; + +/** + * Console interface for lottery administration + */ +public class ConsoleAdministration { +} diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministration.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministration.java deleted file mode 100644 index a59461a48..000000000 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/LotteryAdministration.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * 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.Inject; -import com.iluwatar.hexagonal.domain.LotteryNumbers; -import com.iluwatar.hexagonal.domain.LotterySystem; -import com.iluwatar.hexagonal.domain.LotteryTicket; -import com.iluwatar.hexagonal.domain.LotteryTicketId; - -import java.util.Map; - -/** - * - * Lottery administration implementation - * - */ -public class LotteryAdministration { - - private final LotterySystem lotterySystem; - - @Inject - public LotteryAdministration(LotterySystem lotterySystem) { - this.lotterySystem = lotterySystem; - } - - /** - * Get all the lottery tickets submitted for lottery - */ - public Map getAllSubmittedTickets() { - return lotterySystem.getAllSubmittedTickets(); - } - - /** - * Draw lottery numbers - */ - public LotteryNumbers performLottery() { - return lotterySystem.performLottery(); - } - - /** - * Begin new lottery round - */ - public void resetLottery() { - lotterySystem.resetLottery(); - } -} diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotterySystem.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java similarity index 64% rename from hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotterySystem.java rename to hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java index ed58c82db..7117397d3 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotterySystem.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java @@ -28,26 +28,26 @@ import com.iluwatar.hexagonal.database.LotteryTicketRepository; import com.iluwatar.hexagonal.notifications.LotteryNotifications; import java.util.Map; -import java.util.Optional; /** - * Lottery system + * + * Lottery administration implementation + * */ -public class LotterySystem { +public class LotteryAdministration { private final LotteryTicketRepository repository; private final LotteryNotifications notifications; private final WireTransfers wireTransfers; + private final LotteryTicketChecker checker; - /** - * Constructor - */ @Inject - public LotterySystem(LotteryTicketRepository repository, LotteryNotifications notifications, - WireTransfers wireTransfers) { + public LotteryAdministration(LotteryTicketRepository repository, LotteryNotifications notifications, + WireTransfers wireTransfers) { this.repository = repository; this.notifications = notifications; this.wireTransfers = wireTransfers; + this.checker = new LotteryTicketChecker(this.repository); } /** @@ -64,7 +64,7 @@ public class LotterySystem { LotteryNumbers numbers = LotteryNumbers.createRandom(); Map tickets = getAllSubmittedTickets(); for (LotteryTicketId id : tickets.keySet()) { - LotteryTicketCheckResult result = checkTicketForPrize(id, numbers); + 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()); @@ -86,37 +86,4 @@ public class LotterySystem { public void resetLottery() { repository.deleteAll(); } - - /** - * Submit lottery ticket to participate in the lottery - */ - public Optional submitTicket(LotteryTicket ticket) { - boolean result = wireTransfers.transferFunds(LotteryConstants.TICKET_PRIZE, - ticket.getPlayerDetails().getBankAccount(), LotteryConstants.SERVICE_BANK_ACCOUNT); - if (result == false) { - notifications.notifyTicketSubmitError(ticket.getPlayerDetails()); - return Optional.empty(); - } - Optional optional = repository.save(ticket); - if (optional.isPresent()) { - notifications.notifyTicketSubmitted(ticket.getPlayerDetails()); - } - return optional; - } - - /** - * Check if lottery ticket has won - */ - public LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers) { - Optional 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); - } - } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryService.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java similarity index 55% rename from hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryService.java rename to hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java index 80d306b04..76cd47d1d 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/LotteryService.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java @@ -20,10 +20,12 @@ * 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.domain.*; +import com.iluwatar.hexagonal.banking.WireTransfers; +import com.iluwatar.hexagonal.database.LotteryTicketRepository; +import com.iluwatar.hexagonal.notifications.LotteryNotifications; import java.util.Optional; @@ -34,27 +36,44 @@ import java.util.Optional; */ public class LotteryService { - private final LotterySystem lotterySystem; + private final LotteryTicketRepository repository; + private final LotteryNotifications notifications; + private final WireTransfers wireTransfers; + private final LotteryTicketChecker checker; /** * Constructor */ @Inject - public LotteryService(LotterySystem lotterySystem) { - this.lotterySystem = lotterySystem; + public LotteryService(LotteryTicketRepository repository, LotteryNotifications notifications, + WireTransfers wireTransfers) { + this.repository = repository; + this.notifications = notifications; + this.wireTransfers = wireTransfers; + this.checker = new LotteryTicketChecker(this.repository); } /** * Submit lottery ticket to participate in the lottery */ public Optional submitTicket(LotteryTicket ticket) { - return lotterySystem.submitTicket(ticket); + boolean result = wireTransfers.transferFunds(LotteryConstants.TICKET_PRIZE, + ticket.getPlayerDetails().getBankAccount(), LotteryConstants.SERVICE_BANK_ACCOUNT); + if (result == false) { + notifications.notifyTicketSubmitError(ticket.getPlayerDetails()); + return Optional.empty(); + } + Optional optional = repository.save(ticket); + if (optional.isPresent()) { + notifications.notifyTicketSubmitted(ticket.getPlayerDetails()); + } + return optional; } /** * Check if lottery ticket has won */ public LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers) { - return lotterySystem.checkTicketForPrize(id, winningNumbers); + return checker.checkTicketForPrize(id, winningNumbers); } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketChecker.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketChecker.java new file mode 100644 index 000000000..10042528b --- /dev/null +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketChecker.java @@ -0,0 +1,33 @@ +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 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); + } + } +} diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java new file mode 100644 index 000000000..e48410982 --- /dev/null +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java @@ -0,0 +1,7 @@ +package com.iluwatar.hexagonal.service; + +/** + * Console interface for lottery players + */ +public class ConsoleLottery { +} diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/LotteryTestingModule.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/LotteryTestingModule.java index 252e3e66d..22bfa8f01 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/LotteryTestingModule.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/LotteryTestingModule.java @@ -29,7 +29,6 @@ import com.iluwatar.hexagonal.database.InMemoryTicketRepository; import com.iluwatar.hexagonal.database.LotteryTicketRepository; import com.iluwatar.hexagonal.notifications.LotteryNotifications; import com.iluwatar.hexagonal.notifications.StdOutNotifications; -import com.iluwatar.hexagonal.service.LotteryService; /** * Guice module for testing dependencies diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java index 732f98305..ed6f8d180 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTest.java @@ -50,7 +50,9 @@ public class LotteryTest { private Injector injector; @Inject - private LotterySystem lotterySystem; + private LotteryAdministration administration; + @Inject + private LotteryService service; @Inject private WireTransfers wireTransfers; @@ -68,34 +70,34 @@ public class LotteryTest { @Test public void testLottery() { // admin resets the lottery - lotterySystem.resetLottery(); - assertEquals(lotterySystem.getAllSubmittedTickets().size(), 0); + administration.resetLottery(); + assertEquals(administration.getAllSubmittedTickets().size(), 0); // players submit the lottery tickets - Optional ticket1 = lotterySystem.submitTicket(LotteryTestUtils.createLotteryTicket("cvt@bbb.com", + Optional ticket1 = service.submitTicket(LotteryTestUtils.createLotteryTicket("cvt@bbb.com", "123-12312", "+32425255", new HashSet<>(Arrays.asList(1, 2, 3, 4)))); assertTrue(ticket1.isPresent()); - Optional ticket2 = lotterySystem.submitTicket(LotteryTestUtils.createLotteryTicket("ant@bac.com", + Optional ticket2 = service.submitTicket(LotteryTestUtils.createLotteryTicket("ant@bac.com", "123-12312", "+32423455", new HashSet<>(Arrays.asList(11, 12, 13, 14)))); assertTrue(ticket2.isPresent()); - Optional ticket3 = lotterySystem.submitTicket(LotteryTestUtils.createLotteryTicket("arg@boo.com", + Optional ticket3 = service.submitTicket(LotteryTestUtils.createLotteryTicket("arg@boo.com", "123-12312", "+32421255", new HashSet<>(Arrays.asList(6, 8, 13, 19)))); assertTrue(ticket3.isPresent()); - assertEquals(lotterySystem.getAllSubmittedTickets().size(), 3); + assertEquals(administration.getAllSubmittedTickets().size(), 3); // perform lottery - LotteryNumbers winningNumbers = lotterySystem.performLottery(); + LotteryNumbers winningNumbers = administration.performLottery(); // cheat a bit for testing sake, use winning numbers to submit another ticket - Optional ticket4 = lotterySystem.submitTicket(LotteryTestUtils.createLotteryTicket("lucky@orb.com", + Optional ticket4 = service.submitTicket(LotteryTestUtils.createLotteryTicket("lucky@orb.com", "123-12312", "+12421255", winningNumbers.getNumbers())); assertTrue(ticket4.isPresent()); - assertEquals(lotterySystem.getAllSubmittedTickets().size(), 4); + assertEquals(administration.getAllSubmittedTickets().size(), 4); // check winners - Map tickets = lotterySystem.getAllSubmittedTickets(); + Map tickets = administration.getAllSubmittedTickets(); for (LotteryTicketId id: tickets.keySet()) { - LotteryTicketCheckResult checkResult = lotterySystem.checkTicketForPrize(id, winningNumbers); + LotteryTicketCheckResult checkResult = service.checkTicketForPrize(id, winningNumbers); assertTrue(checkResult.getResult() != CheckResult.TICKET_NOT_SUBMITTED); if (checkResult.getResult().equals(CheckResult.WIN_PRIZE)) { assertTrue(checkResult.getPrizeAmount() > 0); @@ -105,7 +107,7 @@ public class LotteryTest { } // check another ticket that has not been submitted - LotteryTicketCheckResult checkResult = lotterySystem.checkTicketForPrize(new LotteryTicketId(), winningNumbers); + LotteryTicketCheckResult checkResult = service.checkTicketForPrize(new LotteryTicketId(), winningNumbers); assertTrue(checkResult.getResult() == CheckResult.TICKET_NOT_SUBMITTED); assertEquals(checkResult.getPrizeAmount(), 0); }