From e685512ed59a46f02e3b7670b8ee6731fc3279e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 11 Sep 2016 23:19:02 +0300 Subject: [PATCH 1/9] Hexagonal pattern: Added Mongo based banking adapter and bound it in Guice production module --- .../iluwatar/hexagonal/banking/MongoBank.java | 134 ++++++++++++++++++ .../hexagonal/module/LotteryModule.java | 4 +- ...ansfersTest.java => InMemoryBankTest.java} | 2 +- .../hexagonal/banking/MongoBankTest.java | 68 +++++++++ .../database/MongoTicketRepositoryTest.java | 6 +- 5 files changed, 208 insertions(+), 6 deletions(-) create mode 100644 hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java rename hexagonal/src/test/java/com/iluwatar/hexagonal/banking/{WireTransfersTest.java => InMemoryBankTest.java} (98%) create mode 100644 hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java new file mode 100644 index 000000000..3da65e156 --- /dev/null +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java @@ -0,0 +1,134 @@ +/** + * 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.banking; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.UpdateOptions; +import org.bson.Document; + +import java.util.ArrayList; + +/** + * Mongo based banking adapter + */ +public class MongoBank implements WireTransfers { + + private static final String DEFAULT_HOST = "localhost"; + private static final int DEFAULT_PORT = 27017; + private static final String DEFAULT_DB = "lotteryDB"; + private static final String DEFAULT_ACCOUNTS_COLLECTION = "accounts"; + + private MongoClient mongoClient; + private MongoDatabase database; + private MongoCollection accountsCollection; + + /** + * Constructor + */ + public MongoBank() { + connect(); + } + + /** + * Constructor accepting parameters + */ + public MongoBank(String host, int port, String dbName, String accountsCollectionName) { + connect(host, port, dbName, accountsCollectionName); + } + + /** + * Connect to database with default parameters + */ + public void connect() { + connect(DEFAULT_HOST, DEFAULT_PORT, DEFAULT_DB, DEFAULT_ACCOUNTS_COLLECTION); + } + + /** + * Connect to database with given parameters + */ + public void connect(String host, int port, String dbName, String accountsCollectionName) { + if (mongoClient != null) { + mongoClient.close(); + } + mongoClient = new MongoClient(host , port); + database = mongoClient.getDatabase(dbName); + accountsCollection = database.getCollection(accountsCollectionName); + } + + /** + * @return mongo client + */ + public MongoClient getMongoClient() { + return mongoClient; + } + + /** + * + * @return mongo database + */ + public MongoDatabase getMongoDatabase() { + return database; + } + + /** + * + * @return accounts collection + */ + public MongoCollection getAccountsCollection() { + return accountsCollection; + } + + + @Override + public void setFunds(String bankAccount, int amount) { + Document search = new Document("_id", bankAccount); + Document update = new Document("_id", bankAccount).append("funds", amount); + accountsCollection.updateOne(search, new Document("$set", update), new UpdateOptions().upsert(true)); + } + + @Override + public int getFunds(String bankAccount) { + Document search = new Document("_id", bankAccount); + ArrayList results = accountsCollection.find(search).limit(1).into(new ArrayList()); + if (results.size() > 0) { + return results.get(0).getInteger("funds"); + } else { + return 0; + } + } + + @Override + public boolean transferFunds(int amount, String sourceBackAccount, String destinationBankAccount) { + int sourceFunds = getFunds(sourceBackAccount); + if (sourceFunds < amount) { + return false; + } else { + int destFunds = getFunds(destinationBankAccount); + setFunds(sourceBackAccount, sourceFunds - amount); + setFunds(destinationBankAccount, destFunds + amount); + return true; + } + } +} diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java index 0a0177f25..c9bc301fc 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java @@ -23,7 +23,7 @@ package com.iluwatar.hexagonal.module; import com.google.inject.AbstractModule; -import com.iluwatar.hexagonal.banking.InMemoryBank; +import com.iluwatar.hexagonal.banking.MongoBank; import com.iluwatar.hexagonal.banking.WireTransfers; import com.iluwatar.hexagonal.database.LotteryTicketRepository; import com.iluwatar.hexagonal.database.MongoTicketRepository; @@ -38,6 +38,6 @@ public class LotteryModule extends AbstractModule { protected void configure() { bind(LotteryTicketRepository.class).to(MongoTicketRepository.class); bind(LotteryNotifications.class).to(StdOutNotifications.class); - bind(WireTransfers.class).to(InMemoryBank.class); + bind(WireTransfers.class).to(MongoBank.class); } } diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/InMemoryBankTest.java similarity index 98% rename from hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java rename to hexagonal/src/test/java/com/iluwatar/hexagonal/banking/InMemoryBankTest.java index 25fbf460c..c5efda240 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/WireTransfersTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/InMemoryBankTest.java @@ -32,7 +32,7 @@ import org.junit.Test; * Tests for banking * */ -public class WireTransfersTest { +public class InMemoryBankTest { private final WireTransfers bank = new InMemoryBank(); diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java new file mode 100644 index 000000000..ad142f028 --- /dev/null +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java @@ -0,0 +1,68 @@ +/** + * 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.banking; + +import com.mongodb.MongoClient; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Tests for Mongo banking adapter + */ +@Ignore +public class MongoBankTest { + + private static final String TEST_HOST = "localhost"; + private static final int TEST_PORT = 27017; + private static final String TEST_DB = "lotteryDBTest"; + private static final String TEST_ACCOUNTS_COLLECTION = "testAccounts"; + + private MongoBank mongoBank; + + @Before + public void init() { + MongoClient mongoClient = new MongoClient(TEST_HOST, TEST_PORT); + mongoClient.dropDatabase(TEST_DB); + mongoClient.close(); + mongoBank = new MongoBank(TEST_HOST, TEST_PORT, TEST_DB, TEST_ACCOUNTS_COLLECTION); + } + + @Test + public void testSetup() { + assertEquals(0, mongoBank.getAccountsCollection().count()); + } + + @Test + public void testFundTransfers() { + assertEquals(0, mongoBank.getFunds("000-000")); + mongoBank.setFunds("000-000", 10); + assertEquals(10, mongoBank.getFunds("000-000")); + assertEquals(0, mongoBank.getFunds("111-111")); + mongoBank.transferFunds(9, "000-000", "111-111"); + assertEquals(1, mongoBank.getFunds("000-000")); + assertEquals(9, mongoBank.getFunds("111-111")); + } +} diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java index 09a2772bd..45fa1cc67 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java @@ -44,9 +44,9 @@ public class MongoTicketRepositoryTest { private static final String TEST_HOST = "localhost"; private static final int TEST_PORT = 27017; - private static final String TEST_DB = "lotteryDB"; - private static final String TEST_TICKETS_COLLECTION = "lotteryTickets"; - private static final String TEST_COUNTERS_COLLECTION = "counters"; + private static final String TEST_DB = "lotteryTestDB"; + private static final String TEST_TICKETS_COLLECTION = "lotteryTestTickets"; + private static final String TEST_COUNTERS_COLLECTION = "testCounters"; private MongoTicketRepository repository; From 27e8cb7f2d28bcc09c3cd0babe8ed901e1bd3804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 14 Sep 2016 19:25:26 +0300 Subject: [PATCH 2/9] Hexagonal pattern: Add separate class for Mongo connection properties --- .../iluwatar/hexagonal/banking/MongoBank.java | 14 ++-- .../database/MongoTicketRepository.java | 14 ++-- .../mongo/MongoConnectionProperties.java | 80 +++++++++++++++++++ .../hexagonal/banking/MongoBankTest.java | 8 +- .../database/MongoTicketRepositoryTest.java | 8 +- 5 files changed, 102 insertions(+), 22 deletions(-) create mode 100644 hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionProperties.java diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java index 3da65e156..2a18d8986 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java @@ -22,6 +22,7 @@ */ package com.iluwatar.hexagonal.banking; +import com.iluwatar.hexagonal.mongo.MongoConnectionProperties; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; @@ -35,8 +36,6 @@ import java.util.ArrayList; */ public class MongoBank implements WireTransfers { - private static final String DEFAULT_HOST = "localhost"; - private static final int DEFAULT_PORT = 27017; private static final String DEFAULT_DB = "lotteryDB"; private static final String DEFAULT_ACCOUNTS_COLLECTION = "accounts"; @@ -54,25 +53,26 @@ public class MongoBank implements WireTransfers { /** * Constructor accepting parameters */ - public MongoBank(String host, int port, String dbName, String accountsCollectionName) { - connect(host, port, dbName, accountsCollectionName); + public MongoBank(String dbName, String accountsCollectionName) { + connect(dbName, accountsCollectionName); } /** * Connect to database with default parameters */ public void connect() { - connect(DEFAULT_HOST, DEFAULT_PORT, DEFAULT_DB, DEFAULT_ACCOUNTS_COLLECTION); + connect(DEFAULT_DB, DEFAULT_ACCOUNTS_COLLECTION); } /** * Connect to database with given parameters */ - public void connect(String host, int port, String dbName, String accountsCollectionName) { + public void connect(String dbName, String accountsCollectionName) { if (mongoClient != null) { mongoClient.close(); } - mongoClient = new MongoClient(host , port); + MongoConnectionProperties properties = new MongoConnectionProperties().load(); + mongoClient = new MongoClient(properties.getHost(), properties.getPort()); database = mongoClient.getDatabase(dbName); accountsCollection = database.getCollection(accountsCollectionName); } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java index ff0439af8..73ff40b78 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java @@ -26,6 +26,7 @@ import com.iluwatar.hexagonal.domain.LotteryNumbers; import com.iluwatar.hexagonal.domain.LotteryTicket; import com.iluwatar.hexagonal.domain.LotteryTicketId; import com.iluwatar.hexagonal.domain.PlayerDetails; +import com.iluwatar.hexagonal.mongo.MongoConnectionProperties; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; @@ -43,8 +44,6 @@ import java.util.Optional; */ public class MongoTicketRepository implements LotteryTicketRepository { - private static final String DEFAULT_HOST = "localhost"; - private static final int DEFAULT_PORT = 27017; private static final String DEFAULT_DB = "lotteryDB"; private static final String DEFAULT_TICKETS_COLLECTION = "lotteryTickets"; private static final String DEFAULT_COUNTERS_COLLECTION = "counters"; @@ -64,27 +63,28 @@ public class MongoTicketRepository implements LotteryTicketRepository { /** * Constructor accepting parameters */ - public MongoTicketRepository(String host, int port, String dbName, String ticketsCollectionName, + public MongoTicketRepository(String dbName, String ticketsCollectionName, String countersCollectionName) { - connect(host, port, dbName, ticketsCollectionName, countersCollectionName); + connect(dbName, ticketsCollectionName, countersCollectionName); } /** * Connect to database with default parameters */ public void connect() { - connect(DEFAULT_HOST, DEFAULT_PORT, DEFAULT_DB, DEFAULT_TICKETS_COLLECTION, DEFAULT_COUNTERS_COLLECTION); + connect(DEFAULT_DB, DEFAULT_TICKETS_COLLECTION, DEFAULT_COUNTERS_COLLECTION); } /** * Connect to database with given parameters */ - public void connect(String host, int port, String dbName, String ticketsCollectionName, + public void connect(String dbName, String ticketsCollectionName, String countersCollectionName) { if (mongoClient != null) { mongoClient.close(); } - mongoClient = new MongoClient(host , port); + MongoConnectionProperties properties = new MongoConnectionProperties().load(); + mongoClient = new MongoClient(properties.getHost(), properties.getPort()); database = mongoClient.getDatabase(dbName); ticketsCollection = database.getCollection(ticketsCollectionName); countersCollection = database.getCollection(countersCollectionName); diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionProperties.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionProperties.java new file mode 100644 index 000000000..20b1876f6 --- /dev/null +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionProperties.java @@ -0,0 +1,80 @@ +/** + * 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.mongo; + +import java.io.FileInputStream; +import java.util.Properties; + +/** + * Mongo connection properties + */ +public class MongoConnectionProperties { + + private static final String DEFAULT_HOST = "localhost"; + private static final int DEFAULT_PORT = 27017; + + private String host; + private int port; + + /** + * Constructor + */ + public MongoConnectionProperties() { + this.host = DEFAULT_HOST; + this.port = DEFAULT_PORT; + } + + /** + * @return host name + */ + public String getHost() { + return host; + } + + /** + * @return port number + */ + public int getPort() { + return port; + } + + /** + * Try to load connection properties from file. + * Fall back to default connection properties. + */ + public MongoConnectionProperties load() { + String path = System.getProperty("hexagonal.properties.path"); + Properties properties = new Properties(); + if (path != null) { + try (FileInputStream fin = new FileInputStream(path)) { + properties.load(fin); + this.host = properties.getProperty("host"); + this.port = Integer.parseInt(properties.getProperty("port")); + } catch (Exception e) { + // error occurred, use default properties + e.printStackTrace(); + } + } + return this; + } +} diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java index ad142f028..26041b174 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java @@ -22,6 +22,7 @@ */ package com.iluwatar.hexagonal.banking; +import com.iluwatar.hexagonal.mongo.MongoConnectionProperties; import com.mongodb.MongoClient; import org.junit.Before; import org.junit.Ignore; @@ -35,8 +36,6 @@ import static org.junit.Assert.assertEquals; @Ignore public class MongoBankTest { - private static final String TEST_HOST = "localhost"; - private static final int TEST_PORT = 27017; private static final String TEST_DB = "lotteryDBTest"; private static final String TEST_ACCOUNTS_COLLECTION = "testAccounts"; @@ -44,10 +43,11 @@ public class MongoBankTest { @Before public void init() { - MongoClient mongoClient = new MongoClient(TEST_HOST, TEST_PORT); + MongoConnectionProperties properties = new MongoConnectionProperties().load(); + MongoClient mongoClient = new MongoClient(properties.getHost(), properties.getPort()); mongoClient.dropDatabase(TEST_DB); mongoClient.close(); - mongoBank = new MongoBank(TEST_HOST, TEST_PORT, TEST_DB, TEST_ACCOUNTS_COLLECTION); + mongoBank = new MongoBank(TEST_DB, TEST_ACCOUNTS_COLLECTION); } @Test diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java index 45fa1cc67..a29b535f6 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java @@ -26,6 +26,7 @@ import com.iluwatar.hexagonal.domain.LotteryNumbers; import com.iluwatar.hexagonal.domain.LotteryTicket; import com.iluwatar.hexagonal.domain.LotteryTicketId; import com.iluwatar.hexagonal.domain.PlayerDetails; +import com.iluwatar.hexagonal.mongo.MongoConnectionProperties; import com.mongodb.MongoClient; import org.junit.Before; import org.junit.Ignore; @@ -42,8 +43,6 @@ import static org.junit.Assert.assertTrue; @Ignore public class MongoTicketRepositoryTest { - private static final String TEST_HOST = "localhost"; - private static final int TEST_PORT = 27017; private static final String TEST_DB = "lotteryTestDB"; private static final String TEST_TICKETS_COLLECTION = "lotteryTestTickets"; private static final String TEST_COUNTERS_COLLECTION = "testCounters"; @@ -52,10 +51,11 @@ public class MongoTicketRepositoryTest { @Before public void init() { - MongoClient mongoClient = new MongoClient(TEST_HOST, TEST_PORT); + MongoConnectionProperties properties = new MongoConnectionProperties().load(); + MongoClient mongoClient = new MongoClient(properties.getHost(), properties.getPort()); mongoClient.dropDatabase(TEST_DB); mongoClient.close(); - repository = new MongoTicketRepository(TEST_HOST, TEST_PORT, TEST_DB, TEST_TICKETS_COLLECTION, + repository = new MongoTicketRepository(TEST_DB, TEST_TICKETS_COLLECTION, TEST_COUNTERS_COLLECTION); } From 3cf2b34d2a1f20a2606d515ad145bf0fb018b44f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 14 Sep 2016 22:01:41 +0300 Subject: [PATCH 3/9] Hexagonal pattern: Improve connection properties handling --- .../administration/ConsoleAdministration.java | 2 + .../iluwatar/hexagonal/banking/MongoBank.java | 5 +-- .../database/MongoTicketRepository.java | 5 +-- ...a => MongoConnectionPropertiesLoader.java} | 40 +++++-------------- .../hexagonal/service/ConsoleLottery.java | 2 + .../hexagonal/banking/MongoBankTest.java | 7 ++-- .../database/MongoTicketRepositoryTest.java | 7 ++-- 7 files changed, 25 insertions(+), 43 deletions(-) rename hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/{MongoConnectionProperties.java => MongoConnectionPropertiesLoader.java} (75%) diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java index 6a846280c..ea2f33699 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/administration/ConsoleAdministration.java @@ -28,6 +28,7 @@ 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.mongo.MongoConnectionPropertiesLoader; import com.iluwatar.hexagonal.sampledata.SampleData; import java.util.Scanner; @@ -41,6 +42,7 @@ public class ConsoleAdministration { * Program entry point */ public static void main(String[] args) { + MongoConnectionPropertiesLoader.load(); Injector injector = Guice.createInjector(new LotteryModule()); LotteryAdministration administartion = injector.getInstance(LotteryAdministration.class); LotteryService service = injector.getInstance(LotteryService.class); diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java index 2a18d8986..23a0e376a 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/banking/MongoBank.java @@ -22,7 +22,6 @@ */ package com.iluwatar.hexagonal.banking; -import com.iluwatar.hexagonal.mongo.MongoConnectionProperties; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; @@ -71,8 +70,8 @@ public class MongoBank implements WireTransfers { if (mongoClient != null) { mongoClient.close(); } - MongoConnectionProperties properties = new MongoConnectionProperties().load(); - mongoClient = new MongoClient(properties.getHost(), properties.getPort()); + mongoClient = new MongoClient(System.getProperty("mongo-host"), + Integer.parseInt(System.getProperty("mongo-port"))); database = mongoClient.getDatabase(dbName); accountsCollection = database.getCollection(accountsCollectionName); } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java index 73ff40b78..4cfa83649 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java @@ -26,7 +26,6 @@ import com.iluwatar.hexagonal.domain.LotteryNumbers; import com.iluwatar.hexagonal.domain.LotteryTicket; import com.iluwatar.hexagonal.domain.LotteryTicketId; import com.iluwatar.hexagonal.domain.PlayerDetails; -import com.iluwatar.hexagonal.mongo.MongoConnectionProperties; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; @@ -83,8 +82,8 @@ public class MongoTicketRepository implements LotteryTicketRepository { if (mongoClient != null) { mongoClient.close(); } - MongoConnectionProperties properties = new MongoConnectionProperties().load(); - mongoClient = new MongoClient(properties.getHost(), properties.getPort()); + mongoClient = new MongoClient(System.getProperty("mongo-host"), + Integer.parseInt(System.getProperty("mongo-port"))); database = mongoClient.getDatabase(dbName); ticketsCollection = database.getCollection(ticketsCollectionName); countersCollection = database.getCollection(countersCollectionName); diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionProperties.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionPropertiesLoader.java similarity index 75% rename from hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionProperties.java rename to hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionPropertiesLoader.java index 20b1876f6..a9bb39803 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionProperties.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/mongo/MongoConnectionPropertiesLoader.java @@ -26,55 +26,33 @@ import java.io.FileInputStream; import java.util.Properties; /** - * Mongo connection properties + * Mongo connection properties loader */ -public class MongoConnectionProperties { +public class MongoConnectionPropertiesLoader { private static final String DEFAULT_HOST = "localhost"; private static final int DEFAULT_PORT = 27017; - private String host; - private int port; - - /** - * Constructor - */ - public MongoConnectionProperties() { - this.host = DEFAULT_HOST; - this.port = DEFAULT_PORT; - } - - /** - * @return host name - */ - public String getHost() { - return host; - } - - /** - * @return port number - */ - public int getPort() { - return port; - } - /** * Try to load connection properties from file. * Fall back to default connection properties. */ - public MongoConnectionProperties load() { + public static void load() { + String host = DEFAULT_HOST; + int port = DEFAULT_PORT; String path = System.getProperty("hexagonal.properties.path"); Properties properties = new Properties(); if (path != null) { try (FileInputStream fin = new FileInputStream(path)) { properties.load(fin); - this.host = properties.getProperty("host"); - this.port = Integer.parseInt(properties.getProperty("port")); + host = properties.getProperty("mongo-host"); + port = Integer.parseInt(properties.getProperty("mongo-port")); } catch (Exception e) { // error occurred, use default properties e.printStackTrace(); } } - return this; + System.setProperty("mongo-host", host); + System.setProperty("mongo-port", String.format("%d", port)); } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java index afacc35cc..b0d660023 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java @@ -32,6 +32,7 @@ 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 com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; import java.util.HashSet; import java.util.Optional; @@ -48,6 +49,7 @@ public class ConsoleLottery { * Program entry point */ public static void main(String[] args) { + MongoConnectionPropertiesLoader.load(); Injector injector = Guice.createInjector(new LotteryModule()); LotteryService service = injector.getInstance(LotteryService.class); WireTransfers bank = injector.getInstance(WireTransfers.class); diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java index 26041b174..ce5c9ff1a 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/banking/MongoBankTest.java @@ -22,7 +22,7 @@ */ package com.iluwatar.hexagonal.banking; -import com.iluwatar.hexagonal.mongo.MongoConnectionProperties; +import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; import com.mongodb.MongoClient; import org.junit.Before; import org.junit.Ignore; @@ -43,8 +43,9 @@ public class MongoBankTest { @Before public void init() { - MongoConnectionProperties properties = new MongoConnectionProperties().load(); - MongoClient mongoClient = new MongoClient(properties.getHost(), properties.getPort()); + MongoConnectionPropertiesLoader.load(); + MongoClient mongoClient = new MongoClient(System.getProperty("mongo-host"), + Integer.parseInt(System.getProperty("mongo-port"))); mongoClient.dropDatabase(TEST_DB); mongoClient.close(); mongoBank = new MongoBank(TEST_DB, TEST_ACCOUNTS_COLLECTION); diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java index a29b535f6..bbd95b38d 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java @@ -26,7 +26,7 @@ import com.iluwatar.hexagonal.domain.LotteryNumbers; import com.iluwatar.hexagonal.domain.LotteryTicket; import com.iluwatar.hexagonal.domain.LotteryTicketId; import com.iluwatar.hexagonal.domain.PlayerDetails; -import com.iluwatar.hexagonal.mongo.MongoConnectionProperties; +import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; import com.mongodb.MongoClient; import org.junit.Before; import org.junit.Ignore; @@ -51,8 +51,9 @@ public class MongoTicketRepositoryTest { @Before public void init() { - MongoConnectionProperties properties = new MongoConnectionProperties().load(); - MongoClient mongoClient = new MongoClient(properties.getHost(), properties.getPort()); + MongoConnectionPropertiesLoader.load(); + MongoClient mongoClient = new MongoClient(System.getProperty("mongo-host"), + Integer.parseInt(System.getProperty("mongo-port"))); mongoClient.dropDatabase(TEST_DB); mongoClient.close(); repository = new MongoTicketRepository(TEST_DB, TEST_TICKETS_COLLECTION, From c4c5e78e50f6ccfe73e5fafaf4019cfb3dc68fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Wed, 14 Sep 2016 22:18:42 +0300 Subject: [PATCH 4/9] Hexagonal pattern: Improve error handling in console lottery --- .../hexagonal/service/ConsoleLottery.java | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java index b0d660023..eb791ca55 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java @@ -79,17 +79,21 @@ public class ConsoleLottery { 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 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(new LotteryTicketId(), details, lotteryNumbers); - Optional id = service.submitTicket(lotteryTicket); - if (id.isPresent()) { - System.out.println("Submitted lottery ticket with id: " + id.get()); - } else { + try { + String[] parts = numbers.split(","); + Set 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(new LotteryTicketId(), details, lotteryNumbers); + Optional 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."); + } + } catch (Exception e) { System.out.println("Failed submitting lottery ticket - please try again."); } } else if (cmd.equals("4")) { @@ -97,19 +101,23 @@ public class ConsoleLottery { String id = readString(scanner); System.out.println("Give the 4 comma separated winning numbers?"); String numbers = readString(scanner); - String[] parts = numbers.split(","); - Set 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."); + try { + String[] parts = numbers.split(","); + Set 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."); + } + } catch (Exception e) { + System.out.println("Failed checking the lottery ticket - please try again."); } } else if (cmd.equals("5")) { exit = true; From df32a7b893fb0120708bfde3d7c0122264033f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 15 Sep 2016 21:45:09 +0300 Subject: [PATCH 5/9] Hexagonal pattern: Introduced lottery events port with two adapters --- hexagonal/etc/hexagonal.ucls | 4 +- hexagonal/etc/hexagonal.urm.puml | 2 +- .../main/java/com/iluwatar/hexagonal/App.java | 2 +- .../domain/LotteryAdministration.java | 12 +- .../hexagonal/domain/LotteryService.java | 10 +- .../LotteryEventLog.java} | 26 +-- .../hexagonal/eventlog/MongoEventLog.java | 154 ++++++++++++++++++ .../StdOutEventLog.java} | 17 +- .../hexagonal/module/LotteryModule.java | 6 +- .../module/LotteryTestingModule.java | 6 +- .../hexagonal/eventlog/MongoEventLogTest.java | 84 ++++++++++ 11 files changed, 282 insertions(+), 41 deletions(-) rename hexagonal/src/main/java/com/iluwatar/hexagonal/{notifications/LotteryNotifications.java => eventlog/LotteryEventLog.java} (66%) create mode 100644 hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java rename hexagonal/src/main/java/com/iluwatar/hexagonal/{notifications/StdOutNotifications.java => eventlog/StdOutEventLog.java} (83%) create mode 100644 hexagonal/src/test/java/com/iluwatar/hexagonal/eventlog/MongoEventLogTest.java diff --git a/hexagonal/etc/hexagonal.ucls b/hexagonal/etc/hexagonal.ucls index 0318576c2..d3b46b23d 100644 --- a/hexagonal/etc/hexagonal.ucls +++ b/hexagonal/etc/hexagonal.ucls @@ -2,7 +2,7 @@ - @@ -161,7 +161,7 @@ - diff --git a/hexagonal/etc/hexagonal.urm.puml b/hexagonal/etc/hexagonal.urm.puml index 4102c5863..c4b0d0a73 100644 --- a/hexagonal/etc/hexagonal.urm.puml +++ b/hexagonal/etc/hexagonal.urm.puml @@ -116,7 +116,7 @@ package com.iluwatar.hexagonal.database { + save(LotteryTicket) : Optional {abstract} } } -package com.iluwatar.hexagonal.notifications { +package com.iluwatar.hexagonal.eventlog { interface LotteryNotifications { + notifyNoWin(PlayerDetails) {abstract} + notifyPrize(PlayerDetails, int) {abstract} diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java index a7d31446b..7ec974c3b 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java @@ -56,7 +56,7 @@ import com.iluwatar.hexagonal.sampledata.SampleData; * * The secondary ports that application core uses are {@link WireTransfers} * which is a banking service, {@link LotteryNotifications} that delivers - * notifications as lottery events occur and {@link LotteryTicketRepository} + * eventlog as lottery events occur and {@link LotteryTicketRepository} * that is the storage for the lottery tickets. * */ diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java index f73390863..3e01b6e03 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java @@ -25,7 +25,7 @@ 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 com.iluwatar.hexagonal.eventlog.LotteryEventLog; import java.util.Map; @@ -37,7 +37,7 @@ import java.util.Map; public class LotteryAdministration { private final LotteryTicketRepository repository; - private final LotteryNotifications notifications; + private final LotteryEventLog notifications; private final WireTransfers wireTransfers; private final LotteryTicketChecker checker; @@ -45,7 +45,7 @@ public class LotteryAdministration { * Constructor */ @Inject - public LotteryAdministration(LotteryTicketRepository repository, LotteryNotifications notifications, + public LotteryAdministration(LotteryTicketRepository repository, LotteryEventLog notifications, WireTransfers wireTransfers) { this.repository = repository; this.notifications = notifications; @@ -72,12 +72,12 @@ public class LotteryAdministration { 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); + notifications.ticketWon(tickets.get(id).getPlayerDetails(), LotteryConstants.PRIZE_AMOUNT); } else { - notifications.notifyPrizeError(tickets.get(id).getPlayerDetails(), LotteryConstants.PRIZE_AMOUNT); + notifications.prizeError(tickets.get(id).getPlayerDetails(), LotteryConstants.PRIZE_AMOUNT); } } else if (result.getResult().equals(LotteryTicketCheckResult.CheckResult.NO_PRIZE)) { - notifications.notifyNoWin(tickets.get(id).getPlayerDetails()); + notifications.ticketDidNotWin(tickets.get(id).getPlayerDetails()); } } return numbers; diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java index 76cd47d1d..a9dff7fd0 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java @@ -25,7 +25,7 @@ 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 com.iluwatar.hexagonal.eventlog.LotteryEventLog; import java.util.Optional; @@ -37,7 +37,7 @@ import java.util.Optional; public class LotteryService { private final LotteryTicketRepository repository; - private final LotteryNotifications notifications; + private final LotteryEventLog notifications; private final WireTransfers wireTransfers; private final LotteryTicketChecker checker; @@ -45,7 +45,7 @@ public class LotteryService { * Constructor */ @Inject - public LotteryService(LotteryTicketRepository repository, LotteryNotifications notifications, + public LotteryService(LotteryTicketRepository repository, LotteryEventLog notifications, WireTransfers wireTransfers) { this.repository = repository; this.notifications = notifications; @@ -60,12 +60,12 @@ public class LotteryService { boolean result = wireTransfers.transferFunds(LotteryConstants.TICKET_PRIZE, ticket.getPlayerDetails().getBankAccount(), LotteryConstants.SERVICE_BANK_ACCOUNT); if (result == false) { - notifications.notifyTicketSubmitError(ticket.getPlayerDetails()); + notifications.ticketSubmitError(ticket.getPlayerDetails()); return Optional.empty(); } Optional optional = repository.save(ticket); if (optional.isPresent()) { - notifications.notifyTicketSubmitted(ticket.getPlayerDetails()); + notifications.ticketSubmitted(ticket.getPlayerDetails()); } return optional; } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotifications.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/LotteryEventLog.java similarity index 66% rename from hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotifications.java rename to hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/LotteryEventLog.java index d7a0cc870..e47640e27 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/LotteryNotifications.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/LotteryEventLog.java @@ -20,40 +20,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.hexagonal.notifications; +package com.iluwatar.hexagonal.eventlog; import com.iluwatar.hexagonal.domain.PlayerDetails; /** * - * Provides notifications for lottery events. + * Event log for lottery events * */ -public interface LotteryNotifications { +public interface LotteryEventLog { /** - * Notify lottery ticket was submitted + * lottery ticket submitted */ - void notifyTicketSubmitted(PlayerDetails details); + void ticketSubmitted(PlayerDetails details); /** - * Notify there was an error submitting lottery ticket + * error submitting lottery ticket */ - void notifyTicketSubmitError(PlayerDetails details); + void ticketSubmitError(PlayerDetails details); /** - * Notify lottery ticket did not win + * lottery ticket did not win */ - void notifyNoWin(PlayerDetails details); + void ticketDidNotWin(PlayerDetails details); /** - * Notify that prize has been paid + * lottery ticket won */ - void notifyPrize(PlayerDetails details, int prizeAmount); + void ticketWon(PlayerDetails details, int prizeAmount); /** - * Notify that there was an error paying the prize + * error paying the prize */ - void notifyPrizeError(PlayerDetails details, int prizeAmount); + void prizeError(PlayerDetails details, int prizeAmount); } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java new file mode 100644 index 000000000..7f9b4da5e --- /dev/null +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/MongoEventLog.java @@ -0,0 +1,154 @@ +/** + * 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.eventlog; + +import com.iluwatar.hexagonal.domain.PlayerDetails; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import org.bson.Document; + +/** + * Mongo based event log + */ +public class MongoEventLog implements LotteryEventLog { + + private static final String DEFAULT_DB = "lotteryDB"; + private static final String DEFAULT_EVENTS_COLLECTION = "events"; + + private MongoClient mongoClient; + private MongoDatabase database; + private MongoCollection eventsCollection; + + private StdOutEventLog stdOutEventLog = new StdOutEventLog(); + + /** + * Constructor + */ + public MongoEventLog() { + connect(); + } + + /** + * Constructor accepting parameters + */ + public MongoEventLog(String dbName, String eventsCollectionName) { + connect(dbName, eventsCollectionName); + } + + /** + * Connect to database with default parameters + */ + public void connect() { + connect(DEFAULT_DB, DEFAULT_EVENTS_COLLECTION); + } + + /** + * Connect to database with given parameters + */ + public void connect(String dbName, String eventsCollectionName) { + if (mongoClient != null) { + mongoClient.close(); + } + mongoClient = new MongoClient(System.getProperty("mongo-host"), + Integer.parseInt(System.getProperty("mongo-port"))); + database = mongoClient.getDatabase(dbName); + eventsCollection = database.getCollection(eventsCollectionName); + } + + /** + * @return mongo client + */ + public MongoClient getMongoClient() { + return mongoClient; + } + + /** + * + * @return mongo database + */ + public MongoDatabase getMongoDatabase() { + return database; + } + + /** + * + * @return accounts collection + */ + public MongoCollection getEventsCollection() { + return eventsCollection; + } + + + @Override + public void ticketSubmitted(PlayerDetails details) { + Document document = new Document("email", details.getEmail()); + document.put("phone", details.getPhoneNumber()); + document.put("bank", details.getBankAccount()); + document.put("message", String.format("Lottery ticket was submitted and bank account was charged for 3 credits.")); + eventsCollection.insertOne(document); + stdOutEventLog.ticketSubmitted(details); + } + + @Override + public void ticketSubmitError(PlayerDetails details) { + Document document = new Document("email", details.getEmail()); + document.put("phone", details.getPhoneNumber()); + document.put("bank", details.getBankAccount()); + document.put("message", String.format("Lottery ticket could not be submitted because lack of funds.")); + eventsCollection.insertOne(document); + stdOutEventLog.ticketSubmitError(details); + } + + @Override + public void ticketDidNotWin(PlayerDetails details) { + Document document = new Document("email", details.getEmail()); + document.put("phone", details.getPhoneNumber()); + document.put("bank", details.getBankAccount()); + document.put("message", String.format("Lottery ticket was checked and unfortunately did not win this time.")); + eventsCollection.insertOne(document); + stdOutEventLog.ticketDidNotWin(details); + } + + @Override + public void ticketWon(PlayerDetails details, int prizeAmount) { + Document document = new Document("email", details.getEmail()); + document.put("phone", details.getPhoneNumber()); + document.put("bank", details.getBankAccount()); + document.put("message", String.format("Lottery ticket won! The bank account was deposited with %d credits.", + prizeAmount)); + eventsCollection.insertOne(document); + stdOutEventLog.ticketWon(details, prizeAmount); + } + + @Override + public void prizeError(PlayerDetails details, int prizeAmount) { + Document document = new Document("email", details.getEmail()); + document.put("phone", details.getPhoneNumber()); + document.put("bank", details.getBankAccount()); + document.put("message", String.format("Lottery ticket won! Unfortunately the bank credit transfer of %d failed.", + prizeAmount)); + eventsCollection.insertOne(document); + stdOutEventLog.prizeError(details, prizeAmount); + } +} diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/StdOutNotifications.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/StdOutEventLog.java similarity index 83% rename from hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/StdOutNotifications.java rename to hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/StdOutEventLog.java index f6bd3b546..4150dd401 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/notifications/StdOutNotifications.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/eventlog/StdOutEventLog.java @@ -20,40 +20,43 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package com.iluwatar.hexagonal.notifications; +package com.iluwatar.hexagonal.eventlog; import com.iluwatar.hexagonal.domain.PlayerDetails; -public class StdOutNotifications implements LotteryNotifications { +/** + * Standard output event log + */ +public class StdOutEventLog implements LotteryEventLog { @Override - public void notifyTicketSubmitted(PlayerDetails details) { + public void ticketSubmitted(PlayerDetails details) { System.out.println(String.format("Lottery ticket for %s was submitted. Bank account %s was charged for 3 credits.", details.getEmail(), details.getBankAccount())); } @Override - public void notifyNoWin(PlayerDetails details) { + public void ticketDidNotWin(PlayerDetails details) { System.out.println(String.format("Lottery ticket for %s was checked and unfortunately did not win this time.", details.getEmail())); } @Override - public void notifyPrize(PlayerDetails details, int prizeAmount) { + public void ticketWon(PlayerDetails details, int prizeAmount) { System.out .println(String.format("Lottery ticket for %s has won! The bank account %s was deposited with %d credits.", details.getEmail(), details.getBankAccount(), prizeAmount)); } @Override - public void notifyPrizeError(PlayerDetails details, int prizeAmount) { + public void prizeError(PlayerDetails details, int prizeAmount) { System.out .println(String.format("Lottery ticket for %s has won! Unfortunately the bank credit transfer of %d failed.", details.getEmail(), prizeAmount)); } @Override - public void notifyTicketSubmitError(PlayerDetails details) { + public void ticketSubmitError(PlayerDetails details) { System.out.println( String.format("Lottery ticket for %s could not be submitted because the credit transfer of 3 credits failed.", details.getEmail())); diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java index c9bc301fc..7e784548d 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryModule.java @@ -27,8 +27,8 @@ import com.iluwatar.hexagonal.banking.MongoBank; import com.iluwatar.hexagonal.banking.WireTransfers; import com.iluwatar.hexagonal.database.LotteryTicketRepository; import com.iluwatar.hexagonal.database.MongoTicketRepository; -import com.iluwatar.hexagonal.notifications.LotteryNotifications; -import com.iluwatar.hexagonal.notifications.StdOutNotifications; +import com.iluwatar.hexagonal.eventlog.LotteryEventLog; +import com.iluwatar.hexagonal.eventlog.MongoEventLog; /** * Guice module for binding production dependencies @@ -37,7 +37,7 @@ public class LotteryModule extends AbstractModule { @Override protected void configure() { bind(LotteryTicketRepository.class).to(MongoTicketRepository.class); - bind(LotteryNotifications.class).to(StdOutNotifications.class); + bind(LotteryEventLog.class).to(MongoEventLog.class); bind(WireTransfers.class).to(MongoBank.class); } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryTestingModule.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryTestingModule.java index c934ed43c..2a1ad1155 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryTestingModule.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/module/LotteryTestingModule.java @@ -27,8 +27,8 @@ 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; +import com.iluwatar.hexagonal.eventlog.LotteryEventLog; +import com.iluwatar.hexagonal.eventlog.StdOutEventLog; /** * Guice module for testing dependencies @@ -37,7 +37,7 @@ public class LotteryTestingModule extends AbstractModule { @Override protected void configure() { bind(LotteryTicketRepository.class).to(InMemoryTicketRepository.class); - bind(LotteryNotifications.class).to(StdOutNotifications.class); + bind(LotteryEventLog.class).to(StdOutEventLog.class); bind(WireTransfers.class).to(InMemoryBank.class); } } diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/eventlog/MongoEventLogTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/eventlog/MongoEventLogTest.java new file mode 100644 index 000000000..9b9f14c78 --- /dev/null +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/eventlog/MongoEventLogTest.java @@ -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.eventlog; + +import com.iluwatar.hexagonal.domain.PlayerDetails; +import com.iluwatar.hexagonal.mongo.MongoConnectionPropertiesLoader; +import com.mongodb.MongoClient; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Tests for Mongo event log + */ +@Ignore +public class MongoEventLogTest { + + private static final String TEST_DB = "lotteryDBTest"; + private static final String TEST_EVENTS_COLLECTION = "testEvents"; + + private MongoEventLog mongoEventLog; + + @Before + public void init() { + MongoConnectionPropertiesLoader.load(); + MongoClient mongoClient = new MongoClient(System.getProperty("mongo-host"), + Integer.parseInt(System.getProperty("mongo-port"))); + mongoClient.dropDatabase(TEST_DB); + mongoClient.close(); + mongoEventLog = new MongoEventLog(TEST_DB, TEST_EVENTS_COLLECTION); + } + + @Test + public void testSetup() { + assertEquals(0, mongoEventLog.getEventsCollection().count()); + } + + @Test + public void testFundTransfers() { + PlayerDetails playerDetails = PlayerDetails.create("john@wayne.com", "000-000", "03432534543"); + mongoEventLog.prizeError(playerDetails, 1000); + assertEquals(1, mongoEventLog.getEventsCollection().count()); + mongoEventLog.prizeError(playerDetails, 1000); + assertEquals(2, mongoEventLog.getEventsCollection().count()); + mongoEventLog.ticketDidNotWin(playerDetails); + assertEquals(3, mongoEventLog.getEventsCollection().count()); + mongoEventLog.ticketDidNotWin(playerDetails); + assertEquals(4, mongoEventLog.getEventsCollection().count()); + mongoEventLog.ticketSubmitError(playerDetails); + assertEquals(5, mongoEventLog.getEventsCollection().count()); + mongoEventLog.ticketSubmitError(playerDetails); + assertEquals(6, mongoEventLog.getEventsCollection().count()); + mongoEventLog.ticketSubmitted(playerDetails); + assertEquals(7, mongoEventLog.getEventsCollection().count()); + mongoEventLog.ticketSubmitted(playerDetails); + assertEquals(8, mongoEventLog.getEventsCollection().count()); + mongoEventLog.ticketWon(playerDetails, 1000); + assertEquals(9, mongoEventLog.getEventsCollection().count()); + mongoEventLog.ticketWon(playerDetails, 1000); + assertEquals(10, mongoEventLog.getEventsCollection().count()); + } +} From 914d1353a18fbbec8c7036a131f64638da7ebeb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Thu, 15 Sep 2016 21:56:15 +0300 Subject: [PATCH 6/9] Hexagonal pattern: Update test application description --- .../src/main/java/com/iluwatar/hexagonal/App.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java index 7ec974c3b..97190937c 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/App.java @@ -49,13 +49,13 @@ import com.iluwatar.hexagonal.sampledata.SampleData; * The application core is separate from the services that drive it and * from the services it uses.

* - * The primary ports for the application are {@link LotteryAdministration} - * through which the lottery round is initiated and run and - * {@link LotteryService} that allows players to submit lottery tickets for - * the draw.

+ * The primary ports for the application are console interfaces + * {@link ConsoleAdministration} through which the lottery round is + * initiated and run and {@link ConsoleLottery} that allows players to + * submit lottery tickets for the draw.

* * The secondary ports that application core uses are {@link WireTransfers} - * which is a banking service, {@link LotteryNotifications} that delivers + * which is a banking service, {@link LotteryEventLog} that delivers * eventlog as lottery events occur and {@link LotteryTicketRepository} * that is the storage for the lottery tickets. * From 6aa58e8ae658cfc66e4421e9b8c92bb017b46906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 17 Sep 2016 09:07:06 +0300 Subject: [PATCH 7/9] Hexagonal pattern: Remove unnecessary factories --- .../database/MongoTicketRepository.java | 4 +- .../domain/LotteryAdministration.java | 4 +- .../hexagonal/domain/LotteryConstants.java | 3 + .../hexagonal/domain/LotteryService.java | 4 +- .../hexagonal/domain/LotteryTicket.java | 9 +-- .../hexagonal/domain/PlayerDetails.java | 11 +-- .../hexagonal/sampledata/SampleData.java | 80 +++++++++---------- .../hexagonal/service/ConsoleLottery.java | 4 +- .../database/MongoTicketRepositoryTest.java | 4 +- .../hexagonal/domain/LotteryTicketTest.java | 12 +-- .../hexagonal/domain/PlayerDetailsTest.java | 6 +- .../hexagonal/eventlog/MongoEventLogTest.java | 2 +- .../hexagonal/test/LotteryTestUtils.java | 4 +- 13 files changed, 66 insertions(+), 81 deletions(-) diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java index 4cfa83649..13a937a1b 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/database/MongoTicketRepository.java @@ -180,7 +180,7 @@ public class MongoTicketRepository implements LotteryTicketRepository { } private LotteryTicket docToTicket(Document doc) { - PlayerDetails playerDetails = PlayerDetails.create(doc.getString("email"), doc.getString("bank"), + PlayerDetails playerDetails = new PlayerDetails(doc.getString("email"), doc.getString("bank"), doc.getString("phone")); int[] numArray = Arrays.asList(doc.getString("numbers").split(",")).stream().mapToInt(Integer::parseInt).toArray(); HashSet numbers = new HashSet<>(); @@ -188,6 +188,6 @@ public class MongoTicketRepository implements LotteryTicketRepository { numbers.add(num); } LotteryNumbers lotteryNumbers = LotteryNumbers.create(numbers); - return LotteryTicket.create(new LotteryTicketId(doc.getInteger("ticketId")), playerDetails, lotteryNumbers); + return new LotteryTicket(new LotteryTicketId(doc.getInteger("ticketId")), playerDetails, lotteryNumbers); } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java index 3e01b6e03..d544c84a1 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java @@ -39,7 +39,6 @@ public class LotteryAdministration { private final LotteryTicketRepository repository; private final LotteryEventLog notifications; private final WireTransfers wireTransfers; - private final LotteryTicketChecker checker; /** * Constructor @@ -50,7 +49,6 @@ public class LotteryAdministration { this.repository = repository; this.notifications = notifications; this.wireTransfers = wireTransfers; - this.checker = new LotteryTicketChecker(this.repository); } /** @@ -67,7 +65,7 @@ public class LotteryAdministration { LotteryNumbers numbers = LotteryNumbers.createRandom(); Map tickets = getAllSubmittedTickets(); for (LotteryTicketId id : tickets.keySet()) { - LotteryTicketCheckResult result = checker.checkTicketForPrize(id, numbers); + LotteryTicketCheckResult result = new LotteryTicketChecker(repository).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()); diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryConstants.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryConstants.java index fb4c8025f..28fd4e2f4 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryConstants.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryConstants.java @@ -29,6 +29,9 @@ package com.iluwatar.hexagonal.domain; */ public class LotteryConstants { + private LotteryConstants() { + } + public static final int PRIZE_AMOUNT = 100000; public static final String SERVICE_BANK_ACCOUNT = "123-123"; public static final int TICKET_PRIZE = 3; diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java index a9dff7fd0..6a032462d 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java @@ -39,7 +39,6 @@ public class LotteryService { private final LotteryTicketRepository repository; private final LotteryEventLog notifications; private final WireTransfers wireTransfers; - private final LotteryTicketChecker checker; /** * Constructor @@ -50,7 +49,6 @@ public class LotteryService { this.repository = repository; this.notifications = notifications; this.wireTransfers = wireTransfers; - this.checker = new LotteryTicketChecker(this.repository); } /** @@ -74,6 +72,6 @@ public class LotteryService { * Check if lottery ticket has won */ public LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers) { - return checker.checkTicketForPrize(id, winningNumbers); + return new LotteryTicketChecker(repository).checkTicketForPrize(id, winningNumbers); } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicket.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicket.java index 3e9ebdae4..9fa318e4c 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicket.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicket.java @@ -36,19 +36,12 @@ public class LotteryTicket { /** * Constructor. */ - private LotteryTicket(LotteryTicketId id, PlayerDetails details, LotteryNumbers numbers) { + public LotteryTicket(LotteryTicketId id, PlayerDetails details, LotteryNumbers numbers) { this.id = id; playerDetails = details; lotteryNumbers = numbers; } - /** - * Factory for creating lottery tickets; - */ - public static LotteryTicket create(LotteryTicketId id, PlayerDetails details, LotteryNumbers numbers) { - return new LotteryTicket(id, details, numbers); - } - /** * @return player details */ diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/PlayerDetails.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/PlayerDetails.java index 1061ad553..7af115a7c 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/PlayerDetails.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/PlayerDetails.java @@ -36,19 +36,12 @@ public class PlayerDetails { /** * Constructor. */ - private PlayerDetails(String email, String bankAccount, String phone) { + public PlayerDetails(String email, String bankAccount, String phone) { emailAddress = email; bankAccountNumber = bankAccount; phoneNumber = phone; } - - /** - * Factory for creating new objects. - */ - public static PlayerDetails create(String email, String bankAccount, String phone) { - return new PlayerDetails(email, bankAccount, phone); - } - + /** * @return email */ diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/sampledata/SampleData.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/sampledata/SampleData.java index b9c779c34..13458d02a 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/sampledata/SampleData.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/sampledata/SampleData.java @@ -43,45 +43,45 @@ public class SampleData { 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")); + PLAYERS.add(new PlayerDetails("john@google.com", "312-342", "+3242434242")); + PLAYERS.add(new PlayerDetails("mary@google.com", "234-987", "+23452346")); + PLAYERS.add(new PlayerDetails("steve@google.com", "833-836", "+63457543")); + PLAYERS.add(new PlayerDetails("wayne@google.com", "319-826", "+24626")); + PLAYERS.add(new PlayerDetails("johnie@google.com", "983-322", "+3635635")); + PLAYERS.add(new PlayerDetails("andy@google.com", "934-734", "+0898245")); + PLAYERS.add(new PlayerDetails("richard@google.com", "536-738", "+09845325")); + PLAYERS.add(new PlayerDetails("kevin@google.com", "453-936", "+2423532")); + PLAYERS.add(new PlayerDetails("arnold@google.com", "114-988", "+5646346524")); + PLAYERS.add(new PlayerDetails("ian@google.com", "663-765", "+928394235")); + PLAYERS.add(new PlayerDetails("robin@google.com", "334-763", "+35448")); + PLAYERS.add(new PlayerDetails("ted@google.com", "735-964", "+98752345")); + PLAYERS.add(new PlayerDetails("larry@google.com", "734-853", "+043842423")); + PLAYERS.add(new PlayerDetails("calvin@google.com", "334-746", "+73294135")); + PLAYERS.add(new PlayerDetails("jacob@google.com", "444-766", "+358042354")); + PLAYERS.add(new PlayerDetails("edwin@google.com", "895-345", "+9752435")); + PLAYERS.add(new PlayerDetails("mary@google.com", "760-009", "+34203542")); + PLAYERS.add(new PlayerDetails("lolita@google.com", "425-907", "+9872342")); + PLAYERS.add(new PlayerDetails("bruno@google.com", "023-638", "+673824122")); + PLAYERS.add(new PlayerDetails("peter@google.com", "335-886", "+5432503945")); + PLAYERS.add(new PlayerDetails("warren@google.com", "225-946", "+9872341324")); + PLAYERS.add(new PlayerDetails("monica@google.com", "265-748", "+134124")); + PLAYERS.add(new PlayerDetails("ollie@google.com", "190-045", "+34453452")); + PLAYERS.add(new PlayerDetails("yngwie@google.com", "241-465", "+9897641231")); + PLAYERS.add(new PlayerDetails("lars@google.com", "746-936", "+42345298345")); + PLAYERS.add(new PlayerDetails("bobbie@google.com", "946-384", "+79831742")); + PLAYERS.add(new PlayerDetails("tyron@google.com", "310-992", "+0498837412")); + PLAYERS.add(new PlayerDetails("tyrell@google.com", "032-045", "+67834134")); + PLAYERS.add(new PlayerDetails("nadja@google.com", "000-346", "+498723")); + PLAYERS.add(new PlayerDetails("wendy@google.com", "994-989", "+987324454")); + PLAYERS.add(new PlayerDetails("luke@google.com", "546-634", "+987642435")); + PLAYERS.add(new PlayerDetails("bjorn@google.com", "342-874", "+7834325")); + PLAYERS.add(new PlayerDetails("lisa@google.com", "024-653", "+980742154")); + PLAYERS.add(new PlayerDetails("anton@google.com", "834-935", "+876423145")); + PLAYERS.add(new PlayerDetails("bruce@google.com", "284-936", "+09843212345")); + PLAYERS.add(new PlayerDetails("ray@google.com", "843-073", "+678324123")); + PLAYERS.add(new PlayerDetails("ron@google.com", "637-738", "+09842354")); + PLAYERS.add(new PlayerDetails("xavier@google.com", "143-947", "+375245")); + PLAYERS.add(new PlayerDetails("harriet@google.com", "842-404", "+131243252")); InMemoryBank wireTransfers = new InMemoryBank(); Random random = new Random(); for (int i = 0; i < PLAYERS.size(); i++) { @@ -95,7 +95,7 @@ public class SampleData { */ public static void submitTickets(LotteryService lotteryService, int numTickets) { for (int i = 0; i < numTickets; i++) { - LotteryTicket ticket = LotteryTicket.create(new LotteryTicketId(), + LotteryTicket ticket = new LotteryTicket(new LotteryTicketId(), getRandomPlayerDetails(), LotteryNumbers.createRandom()); lotteryService.submitTicket(ticket); } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java index eb791ca55..cc13d389d 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/service/ConsoleLottery.java @@ -76,7 +76,7 @@ public class ConsoleLottery { String account = readString(scanner); System.out.println("What is your phone number?"); String phone = readString(scanner); - PlayerDetails details = PlayerDetails.create(email, account, phone); + PlayerDetails details = new PlayerDetails(email, account, phone); System.out.println("Give 4 comma separated lottery numbers?"); String numbers = readString(scanner); try { @@ -86,7 +86,7 @@ public class ConsoleLottery { chosen.add(Integer.parseInt(parts[i])); } LotteryNumbers lotteryNumbers = LotteryNumbers.create(chosen); - LotteryTicket lotteryTicket = LotteryTicket.create(new LotteryTicketId(), details, lotteryNumbers); + LotteryTicket lotteryTicket = new LotteryTicket(new LotteryTicketId(), details, lotteryNumbers); Optional id = service.submitTicket(lotteryTicket); if (id.isPresent()) { System.out.println("Submitted lottery ticket with id: " + id.get()); diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java index bbd95b38d..e30468f99 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/database/MongoTicketRepositoryTest.java @@ -76,9 +76,9 @@ public class MongoTicketRepositoryTest { @Test public void testCrudOperations() { // create new lottery ticket and save it - PlayerDetails details = PlayerDetails.create("foo@bar.com", "123-123", "07001234"); + PlayerDetails details = new PlayerDetails("foo@bar.com", "123-123", "07001234"); LotteryNumbers random = LotteryNumbers.createRandom(); - LotteryTicket original = LotteryTicket.create(new LotteryTicketId(), details, random); + LotteryTicket original = new LotteryTicket(new LotteryTicketId(), details, random); Optional saved = repository.save(original); assertEquals(1, repository.getTicketsCollection().count()); assertTrue(saved.isPresent()); diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketTest.java index 4840dc897..ce1e6b4b0 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/LotteryTicketTest.java @@ -34,16 +34,16 @@ public class LotteryTicketTest { @Test public void testEquals() { - PlayerDetails details1 = PlayerDetails.create("bob@foo.bar", "1212-121212", "+34332322"); + PlayerDetails details1 = new PlayerDetails("bob@foo.bar", "1212-121212", "+34332322"); LotteryNumbers numbers1 = LotteryNumbers.create(new HashSet(Arrays.asList(1, 2, 3, 4))); - LotteryTicket ticket1 = LotteryTicket.create(new LotteryTicketId(), details1, numbers1); - PlayerDetails details2 = PlayerDetails.create("bob@foo.bar", "1212-121212", "+34332322"); + LotteryTicket ticket1 = new LotteryTicket(new LotteryTicketId(), details1, numbers1); + PlayerDetails details2 = new PlayerDetails("bob@foo.bar", "1212-121212", "+34332322"); LotteryNumbers numbers2 = LotteryNumbers.create(new HashSet(Arrays.asList(1, 2, 3, 4))); - LotteryTicket ticket2 = LotteryTicket.create(new LotteryTicketId(), details2, numbers2); + LotteryTicket ticket2 = new LotteryTicket(new LotteryTicketId(), details2, numbers2); assertEquals(ticket1, ticket2); - PlayerDetails details3 = PlayerDetails.create("elsa@foo.bar", "1223-121212", "+49332322"); + PlayerDetails details3 = new PlayerDetails("elsa@foo.bar", "1223-121212", "+49332322"); LotteryNumbers numbers3 = LotteryNumbers.create(new HashSet(Arrays.asList(1, 2, 3, 8))); - LotteryTicket ticket3 = LotteryTicket.create(new LotteryTicketId(), details3, numbers3); + LotteryTicket ticket3 = new LotteryTicket(new LotteryTicketId(), details3, numbers3); assertFalse(ticket1.equals(ticket3)); } } diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/PlayerDetailsTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/PlayerDetailsTest.java index 813b035a2..53aa2d9d5 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/PlayerDetailsTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/domain/PlayerDetailsTest.java @@ -36,10 +36,10 @@ public class PlayerDetailsTest { @Test public void testEquals() { - PlayerDetails details1 = PlayerDetails.create("tom@foo.bar", "11212-123434", "+12323425"); - PlayerDetails details2 = PlayerDetails.create("tom@foo.bar", "11212-123434", "+12323425"); + PlayerDetails details1 = new PlayerDetails("tom@foo.bar", "11212-123434", "+12323425"); + PlayerDetails details2 = new PlayerDetails("tom@foo.bar", "11212-123434", "+12323425"); assertEquals(details1, details2); - PlayerDetails details3 = PlayerDetails.create("john@foo.bar", "16412-123439", "+34323432"); + PlayerDetails details3 = new PlayerDetails("john@foo.bar", "16412-123439", "+34323432"); assertFalse(details1.equals(details3)); } } diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/eventlog/MongoEventLogTest.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/eventlog/MongoEventLogTest.java index 9b9f14c78..d02694826 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/eventlog/MongoEventLogTest.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/eventlog/MongoEventLogTest.java @@ -59,7 +59,7 @@ public class MongoEventLogTest { @Test public void testFundTransfers() { - PlayerDetails playerDetails = PlayerDetails.create("john@wayne.com", "000-000", "03432534543"); + PlayerDetails playerDetails = new PlayerDetails("john@wayne.com", "000-000", "03432534543"); mongoEventLog.prizeError(playerDetails, 1000); assertEquals(1, mongoEventLog.getEventsCollection().count()); mongoEventLog.prizeError(playerDetails, 1000); diff --git a/hexagonal/src/test/java/com/iluwatar/hexagonal/test/LotteryTestUtils.java b/hexagonal/src/test/java/com/iluwatar/hexagonal/test/LotteryTestUtils.java index 02304296f..ae15cd3d7 100644 --- a/hexagonal/src/test/java/com/iluwatar/hexagonal/test/LotteryTestUtils.java +++ b/hexagonal/src/test/java/com/iluwatar/hexagonal/test/LotteryTestUtils.java @@ -50,8 +50,8 @@ public class LotteryTestUtils { */ public static LotteryTicket createLotteryTicket(String email, String account, String phone, Set givenNumbers) { - PlayerDetails details = PlayerDetails.create(email, account, phone); + PlayerDetails details = new PlayerDetails(email, account, phone); LotteryNumbers numbers = LotteryNumbers.create(givenNumbers); - return LotteryTicket.create(new LotteryTicketId(), details, numbers); + return new LotteryTicket(new LotteryTicketId(), details, numbers); } } From b030cd4ebafcdcb017cbec979ec58b0de663ceba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 17 Sep 2016 09:20:33 +0300 Subject: [PATCH 8/9] Hexagonal pattern: Introduce lottery utils class --- .../hexagonal/domain/LotteryAdministration.java | 2 +- .../iluwatar/hexagonal/domain/LotteryService.java | 2 +- ...LotteryTicketChecker.java => LotteryUtils.java} | 14 ++++++-------- 3 files changed, 8 insertions(+), 10 deletions(-) rename hexagonal/src/main/java/com/iluwatar/hexagonal/domain/{LotteryTicketChecker.java => LotteryUtils.java} (83%) diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java index d544c84a1..bc264a9ef 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryAdministration.java @@ -65,7 +65,7 @@ public class LotteryAdministration { LotteryNumbers numbers = LotteryNumbers.createRandom(); Map tickets = getAllSubmittedTickets(); for (LotteryTicketId id : tickets.keySet()) { - LotteryTicketCheckResult result = new LotteryTicketChecker(repository).checkTicketForPrize(id, numbers); + LotteryTicketCheckResult result = LotteryUtils.checkTicketForPrize(repository, 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()); diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java index 6a032462d..dceac26e4 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryService.java @@ -72,6 +72,6 @@ public class LotteryService { * Check if lottery ticket has won */ public LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers) { - return new LotteryTicketChecker(repository).checkTicketForPrize(id, winningNumbers); + return LotteryUtils.checkTicketForPrize(repository, id, winningNumbers); } } diff --git a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketChecker.java b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryUtils.java similarity index 83% rename from hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketChecker.java rename to hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryUtils.java index ce193386b..dc34c7f7d 100644 --- a/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryTicketChecker.java +++ b/hexagonal/src/main/java/com/iluwatar/hexagonal/domain/LotteryUtils.java @@ -27,20 +27,18 @@ import com.iluwatar.hexagonal.database.LotteryTicketRepository; import java.util.Optional; /** - * Lottery ticket checker + * Lottery utilities */ -public class LotteryTicketChecker { +public class LotteryUtils { - private final LotteryTicketRepository repository; - - public LotteryTicketChecker(LotteryTicketRepository repository) { - this.repository = repository; + private LotteryUtils() { } /** - * Check if lottery ticket has won + * Checks if lottery ticket has won */ - public LotteryTicketCheckResult checkTicketForPrize(LotteryTicketId id, LotteryNumbers winningNumbers) { + public static LotteryTicketCheckResult checkTicketForPrize(LotteryTicketRepository repository, LotteryTicketId id, + LotteryNumbers winningNumbers) { Optional optional = repository.findById(id); if (optional.isPresent()) { if (optional.get().getNumbers().equals(winningNumbers)) { From 6026eedd51b9753250051b620312bbedd2ccd6ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sun, 18 Sep 2016 17:51:09 +0300 Subject: [PATCH 9/9] UML generation: Mark the urm-maven-plugin execution to be ignored in Eclipse and recreate all .puml files --- .../etc/abstract-document.urm.puml | 36 +-- .../etc/abstract-factory.urm.puml | 94 +++---- adapter/etc/adapter.urm.puml | 22 +- .../etc/aggregator-service.urm.puml | 42 +-- .../etc/inventory-microservice.urm.puml | 8 +- api-gateway/etc/api-gateway-service.urm.puml | 28 +- .../etc/async-method-invocation.urm.puml | 26 +- bridge/etc/bridge.urm.puml | 64 ++--- builder/etc/builder.urm.puml | 90 +++--- .../etc/business-delegate.urm.puml | 22 +- caching/etc/caching.urm.puml | 50 ++-- callback/etc/callback.urm.puml | 26 +- chain/etc/chain.urm.puml | 40 +-- command/etc/command.urm.puml | 68 ++--- composite/etc/composite.urm.puml | 30 +- dao/etc/dao.urm.puml | 90 +++--- decorator/etc/decorator.urm.puml | 10 +- delegation/etc/delegation.urm.puml | 20 +- .../etc/dependency-injection.urm.puml | 56 ++-- double-dispatch/etc/double-dispatch.urm.puml | 28 +- .../etc/event-aggregator.urm.puml | 54 ++-- .../etc/event-driven-architecture.urm.puml | 30 +- execute-around/etc/execute-around.urm.puml | 6 +- facade/etc/facade.urm.puml | 18 +- factory-kit/etc/factory-kit.urm.puml | 36 +-- factory-method/etc/factory-method.urm.puml | 6 +- feature-toggle/etc/feature-toggle.urm.puml | 16 +- fluentinterface/etc/fluentinterface.urm.puml | 16 +- flux/etc/flux.urm.puml | 88 +++--- flyweight/etc/flyweight.urm.puml | 46 +-- .../etc/front-controller.urm.puml | 46 +-- .../etc/half-sync-half-async.urm.puml | 26 +- hexagonal/etc/hexagonal.urm.puml | 265 ++++++++++++------ .../etc/intercepting-filter.urm.puml | 72 ++--- interpreter/etc/interpreter.urm.puml | 54 ++-- iterator/etc/iterator.urm.puml | 22 +- layers/etc/layers.urm.puml | 172 ++++++------ lazy-loading/etc/lazy-loading.urm.puml | 20 +- mediator/etc/mediator.urm.puml | 38 +-- memento/etc/memento.urm.puml | 24 +- .../etc/model-view-controller.urm.puml | 34 +-- .../etc/model-view-presenter.urm.puml | 78 +++--- monostate/etc/monostate.urm.puml | 16 +- mute-idiom/etc/mute-idiom.urm.puml | 6 +- mutex/etc/mutex.urm.puml | 12 +- naked-objects/etc/naked-objects-dom.urm.puml | 47 +--- .../etc/naked-objects-fixture.urm.puml | 10 +- .../etc/naked-objects-integtests.urm.puml | 26 +- null-object/etc/null-object.urm.puml | 36 +-- object-pool/etc/object-pool.urm.puml | 16 +- observer/etc/observer.urm.puml | 36 +-- poison-pill/etc/poison-pill.urm.puml | 46 +-- pom.xml | 19 ++ .../etc/private-class-data.urm.puml | 26 +- .../etc/producer-consumer.urm.puml | 34 +-- promise/etc/promise.urm.puml | 36 +-- property/etc/property.urm.puml | 32 +-- prototype/etc/prototype.urm.puml | 76 ++--- proxy/etc/proxy.urm.puml | 12 +- reactor/etc/reactor.urm.puml | 140 ++++----- .../etc/reader-writer-lock.urm.puml | 36 +-- repository/etc/repository.urm.puml | 50 ++-- ...rce-acquisition-is-initialization.urm.puml | 8 +- semaphore/etc/semaphore.urm.puml | 42 +-- servant/etc/servant.urm.puml | 40 +-- service-layer/etc/service-layer.urm.puml | 76 ++--- service-locator/etc/service-locator.urm.puml | 30 +- singleton/etc/singleton.urm.puml | 22 +- specification/etc/specification.urm.puml | 66 ++--- state/etc/state.urm.puml | 32 +-- step-builder/etc/step-builder.urm.puml | 36 +-- strategy/etc/strategy.urm.puml | 26 +- template-method/etc/template-method.urm.puml | 26 +- thread-pool/etc/thread-pool.urm.puml | 30 +- tolerant-reader/etc/tolerant-reader.urm.puml | 18 +- twin/etc/twin.urm.puml | 18 +- value-object/etc/value-object.urm.puml | 8 +- visitor/etc/visitor.urm.puml | 78 +++--- 78 files changed, 1676 insertions(+), 1609 deletions(-) diff --git a/abstract-document/etc/abstract-document.urm.puml b/abstract-document/etc/abstract-document.urm.puml index c738b50ce..fa15eb3c7 100644 --- a/abstract-document/etc/abstract-document.urm.puml +++ b/abstract-document/etc/abstract-document.urm.puml @@ -3,31 +3,30 @@ package com.iluwatar.abstractdocument.domain { class Part { + Part(properties : Map) } - class Car { - + Car(properties : Map) - } - interface HasModel { + interface HasPrice { + PROPERTY : String {static} - + getModel() : Optional + + getPrice() : Optional } interface HasParts { + PROPERTY : String {static} + getParts() : Stream } + class Car { + + Car(properties : Map) + } interface HasType { + PROPERTY : String {static} + getType() : Optional } - interface HasPrice { + interface HasModel { + PROPERTY : String {static} - + getPrice() : Optional + + getModel() : Optional } } package com.iluwatar.abstractdocument { - interface Document { - + children(String, Function, T>) : Stream {abstract} - + get(String) : Object {abstract} - + put(String, Object) {abstract} + class App { + + App() + + main(args : String[]) {static} } abstract class AbstractDocument { - properties : Map @@ -37,9 +36,10 @@ package com.iluwatar.abstractdocument { + put(key : String, value : Object) + toString() : String } - class App { - + App() - + main(args : String[]) {static} + interface Document { + + children(String, Function, T>) : Stream {abstract} + + get(String) : Object {abstract} + + put(String, Object) {abstract} } } AbstractDocument --+ Map @@ -47,13 +47,13 @@ Part ..|> HasType Part ..|> HasModel Part ..|> HasPrice Part --|> AbstractDocument +AbstractDocument ..|> Document +HasPrice --|> Document +HasParts --|> Document Car ..|> HasModel Car ..|> HasPrice Car ..|> HasParts Car --|> AbstractDocument -HasModel --|> Document -HasParts --|> Document -AbstractDocument ..|> Document HasType --|> Document -HasPrice --|> Document +HasModel --|> Document @enduml \ No newline at end of file diff --git a/abstract-factory/etc/abstract-factory.urm.puml b/abstract-factory/etc/abstract-factory.urm.puml index 88402c6d7..9648a6a96 100644 --- a/abstract-factory/etc/abstract-factory.urm.puml +++ b/abstract-factory/etc/abstract-factory.urm.puml @@ -1,22 +1,5 @@ @startuml package com.iluwatar.abstractfactory { - interface Castle { - + getDescription() : String {abstract} - } - class OrcKingdomFactory { - + OrcKingdomFactory() - + createArmy() : Army - + createCastle() : Castle - + createKing() : King - } - class ElfKing { - ~ DESCRIPTION : String {static} - + ElfKing() - + getDescription() : String - } - interface King { - + getDescription() : String {abstract} - } class App { - army : Army - castle : Castle @@ -34,35 +17,12 @@ package com.iluwatar.abstractfactory { - setCastle(castle : Castle) - setKing(king : King) } - class OrcKing { - ~ DESCRIPTION : String {static} - + OrcKing() - + getDescription() : String - } - class ElfKingdomFactory { - + ElfKingdomFactory() + class OrcKingdomFactory { + + OrcKingdomFactory() + createArmy() : Army + createCastle() : Castle + createKing() : King } - interface Army { - + getDescription() : String {abstract} - } - class OrcArmy { - ~ DESCRIPTION : String {static} - + OrcArmy() - + getDescription() : String - } - interface KingdomFactory { - + createArmy() : Army {abstract} - + createCastle() : Castle {abstract} - + createKing() : King {abstract} - } - class ElfArmy { - ~ DESCRIPTION : String {static} - + ElfArmy() - + getDescription() : String - } class ElfCastle { ~ DESCRIPTION : String {static} + ElfCastle() @@ -73,16 +33,56 @@ package com.iluwatar.abstractfactory { + OrcCastle() + getDescription() : String } + interface KingdomFactory { + + createArmy() : Army {abstract} + + createCastle() : Castle {abstract} + + createKing() : King {abstract} + } + class ElfKing { + ~ DESCRIPTION : String {static} + + ElfKing() + + getDescription() : String + } + class ElfArmy { + ~ DESCRIPTION : String {static} + + ElfArmy() + + getDescription() : String + } + interface Castle { + + getDescription() : String {abstract} + } + interface Army { + + getDescription() : String {abstract} + } + class OrcKing { + ~ DESCRIPTION : String {static} + + OrcKing() + + getDescription() : String + } + class OrcArmy { + ~ DESCRIPTION : String {static} + + OrcArmy() + + getDescription() : String + } + interface King { + + getDescription() : String {abstract} + } + class ElfKingdomFactory { + + ElfKingdomFactory() + + createArmy() : Army + + createCastle() : Castle + + createKing() : King + } } App --> "-castle" Castle App --> "-king" King App --> "-army" Army OrcKingdomFactory ..|> KingdomFactory -ElfKing ..|> King -OrcKing ..|> King -ElfKingdomFactory ..|> KingdomFactory -OrcArmy ..|> Army -ElfArmy ..|> Army ElfCastle ..|> Castle OrcCastle ..|> Castle +ElfKing ..|> King +ElfArmy ..|> Army +OrcKing ..|> King +OrcArmy ..|> Army +ElfKingdomFactory ..|> KingdomFactory @enduml \ No newline at end of file diff --git a/adapter/etc/adapter.urm.puml b/adapter/etc/adapter.urm.puml index 2cee13dc4..a7c962a3b 100644 --- a/adapter/etc/adapter.urm.puml +++ b/adapter/etc/adapter.urm.puml @@ -1,13 +1,19 @@ @startuml package com.iluwatar.adapter { - class App { - + App() - + main(args : String[]) {static} - } interface BattleShip { + fire() {abstract} + move() {abstract} } + class BattleFishingBoat { + - boat : FishingBoat + + BattleFishingBoat() + + fire() + + move() + } + class App { + + App() + + main(args : String[]) {static} + } class Captain { - battleship : BattleShip + Captain() @@ -16,12 +22,6 @@ package com.iluwatar.adapter { + move() + setBattleship(battleship : BattleShip) } - class BattleFishingBoat { - - boat : FishingBoat - + BattleFishingBoat() - + fire() - + move() - } class FishingBoat { + FishingBoat() + fish() @@ -30,6 +30,6 @@ package com.iluwatar.adapter { } BattleFishingBoat --> "-boat" FishingBoat Captain --> "-battleship" BattleShip -Captain ..|> BattleShip BattleFishingBoat ..|> BattleShip +Captain ..|> BattleShip @enduml \ No newline at end of file diff --git a/aggregator-microservices/etc/aggregator-service.urm.puml b/aggregator-microservices/etc/aggregator-service.urm.puml index 5c2e1167a..2a6600531 100644 --- a/aggregator-microservices/etc/aggregator-service.urm.puml +++ b/aggregator-microservices/etc/aggregator-service.urm.puml @@ -1,5 +1,25 @@ @startuml package com.iluwatar.aggregator.microservices { + class ProductInventoryClientImpl { + + ProductInventoryClientImpl() + + getProductInventories() : int + } + class App { + + App() + + main(args : String[]) {static} + } + interface ProductInventoryClient { + + getProductInventories() : int {abstract} + } + class Product { + - productInventories : int + - title : String + + Product() + + getProductInventories() : int + + getTitle() : String + + setProductInventories(productInventories : int) + + setTitle(title : String) + } class Aggregator { - informationClient : ProductInformationClient - inventoryClient : ProductInventoryClient @@ -13,29 +33,9 @@ package com.iluwatar.aggregator.microservices { interface ProductInformationClient { + getProductTitle() : String {abstract} } - class Product { - - productInventories : int - - title : String - + Product() - + getProductInventories() : int - + getTitle() : String - + setProductInventories(productInventories : int) - + setTitle(title : String) - } - class ProductInventoryClientImpl { - + ProductInventoryClientImpl() - + getProductInventories() : int - } - class App { - + App() - + main(args : String[]) {static} - } - interface ProductInventoryClient { - + getProductInventories() : int {abstract} - } } Aggregator --> "-inventoryClient" ProductInventoryClient Aggregator --> "-informationClient" ProductInformationClient -ProductInformationClientImpl ..|> ProductInformationClient ProductInventoryClientImpl ..|> ProductInventoryClient +ProductInformationClientImpl ..|> ProductInformationClient @enduml \ No newline at end of file diff --git a/aggregator-microservices/etc/inventory-microservice.urm.puml b/aggregator-microservices/etc/inventory-microservice.urm.puml index 90f327e07..a07a36306 100644 --- a/aggregator-microservices/etc/inventory-microservice.urm.puml +++ b/aggregator-microservices/etc/inventory-microservice.urm.puml @@ -1,12 +1,12 @@ @startuml package com.iluwatar.inventory.microservice { - class InventoryApplication { - + InventoryApplication() - + main(args : String[]) {static} - } class InventoryController { + InventoryController() + getProductInventories() : int } + class InventoryApplication { + + InventoryApplication() + + main(args : String[]) {static} + } } @enduml \ No newline at end of file diff --git a/api-gateway/etc/api-gateway-service.urm.puml b/api-gateway/etc/api-gateway-service.urm.puml index 3313f7059..409e7ee91 100644 --- a/api-gateway/etc/api-gateway-service.urm.puml +++ b/api-gateway/etc/api-gateway-service.urm.puml @@ -1,7 +1,16 @@ @startuml package com.iluwatar.api.gateway { - interface ImageClient { - + getImagePath() : String {abstract} + class App { + + App() + + main(args : String[]) {static} + } + class PriceClientImpl { + + PriceClientImpl() + + getPrice() : String + } + class ImageClientImpl { + + ImageClientImpl() + + getImagePath() : String } class MobileProduct { - price : String @@ -9,6 +18,9 @@ package com.iluwatar.api.gateway { + getPrice() : String + setPrice(price : String) } + interface ImageClient { + + getImagePath() : String {abstract} + } class ApiGateway { - imageClient : ImageClient - priceClient : PriceClient @@ -28,18 +40,6 @@ package com.iluwatar.api.gateway { interface PriceClient { + getPrice() : String {abstract} } - class PriceClientImpl { - + PriceClientImpl() - + getPrice() : String - } - class ImageClientImpl { - + ImageClientImpl() - + getImagePath() : String - } - class App { - + App() - + main(args : String[]) {static} - } } ApiGateway --> "-imageClient" ImageClient ApiGateway --> "-priceClient" PriceClient diff --git a/async-method-invocation/etc/async-method-invocation.urm.puml b/async-method-invocation/etc/async-method-invocation.urm.puml index 9a90d307e..b96e843d3 100644 --- a/async-method-invocation/etc/async-method-invocation.urm.puml +++ b/async-method-invocation/etc/async-method-invocation.urm.puml @@ -1,13 +1,22 @@ @startuml package com.iluwatar.async.method.invocation { - interface AsyncCallback { - + onComplete(T, Optional) {abstract} + class App { + + App() + - callback(name : String) : AsyncCallback {static} + - lazyval(value : T, delayMillis : long) : Callable {static} + - log(msg : String) {static} + + main(args : String[]) {static} } interface AsyncResult { + await() {abstract} + getValue() : T {abstract} + isCompleted() : boolean {abstract} } + interface AsyncExecutor { + + endProcess(AsyncResult) : T {abstract} + + startProcess(Callable) : AsyncResult {abstract} + + startProcess(Callable, AsyncCallback) : AsyncResult {abstract} + } class ThreadAsyncExecutor { - idx : AtomicInteger + ThreadAsyncExecutor() @@ -15,12 +24,8 @@ package com.iluwatar.async.method.invocation { + startProcess(task : Callable) : AsyncResult + startProcess(task : Callable, callback : AsyncCallback) : AsyncResult } - class App { - + App() - - callback(name : String) : AsyncCallback {static} - - lazyval(value : T, delayMillis : long) : Callable {static} - - log(msg : String) {static} - + main(args : String[]) {static} + interface AsyncCallback { + + onComplete(T, Optional) {abstract} } -class CompletableResult { ~ COMPLETED : int {static} @@ -38,11 +43,6 @@ package com.iluwatar.async.method.invocation { ~ setException(exception : Exception) ~ setValue(value : T) } - interface AsyncExecutor { - + endProcess(AsyncResult) : T {abstract} - + startProcess(Callable) : AsyncResult {abstract} - + startProcess(Callable, AsyncCallback) : AsyncResult {abstract} - } } CompletableResult ..+ ThreadAsyncExecutor ThreadAsyncExecutor ..|> AsyncExecutor diff --git a/bridge/etc/bridge.urm.puml b/bridge/etc/bridge.urm.puml index d9d7a4145..84e250a06 100644 --- a/bridge/etc/bridge.urm.puml +++ b/bridge/etc/bridge.urm.puml @@ -8,26 +8,6 @@ package com.iluwatar.bridge { + unwield() + wield() } - abstract class MagicWeapon { - # imp : MagicWeaponImpl - + MagicWeapon(imp : MagicWeaponImpl) - + getImp() : MagicWeaponImpl - + swing() {abstract} - + unwield() {abstract} - + wield() {abstract} - } - abstract class SoulEatingMagicWeaponImpl { - + SoulEatingMagicWeaponImpl() - + eatSoulImp() {abstract} - } - class BlindingMagicWeapon { - + BlindingMagicWeapon(imp : BlindingMagicWeaponImpl) - + blind() - + getImp() : BlindingMagicWeaponImpl - + swing() - + unwield() - + wield() - } class Stormbringer { + Stormbringer() + eatSoulImp() @@ -35,9 +15,9 @@ package com.iluwatar.bridge { + unwieldImp() + wieldImp() } - abstract class BlindingMagicWeaponImpl { - + BlindingMagicWeaponImpl() - + blindImp() {abstract} + abstract class FlyingMagicWeaponImpl { + + FlyingMagicWeaponImpl() + + flyImp() {abstract} } class SoulEatingMagicWeapon { + SoulEatingMagicWeapon(imp : SoulEatingMagicWeaponImpl) @@ -53,6 +33,10 @@ package com.iluwatar.bridge { + unwieldImp() {abstract} + wieldImp() {abstract} } + abstract class SoulEatingMagicWeaponImpl { + + SoulEatingMagicWeaponImpl() + + eatSoulImp() {abstract} + } class Excalibur { + Excalibur() + blindImp() @@ -60,10 +44,6 @@ package com.iluwatar.bridge { + unwieldImp() + wieldImp() } - abstract class FlyingMagicWeaponImpl { - + FlyingMagicWeaponImpl() - + flyImp() {abstract} - } class Mjollnir { + Mjollnir() + flyImp() @@ -75,15 +55,35 @@ package com.iluwatar.bridge { + App() + main(args : String[]) {static} } + abstract class MagicWeapon { + # imp : MagicWeaponImpl + + MagicWeapon(imp : MagicWeaponImpl) + + getImp() : MagicWeaponImpl + + swing() {abstract} + + unwield() {abstract} + + wield() {abstract} + } + abstract class BlindingMagicWeaponImpl { + + BlindingMagicWeaponImpl() + + blindImp() {abstract} + } + class BlindingMagicWeapon { + + BlindingMagicWeapon(imp : BlindingMagicWeaponImpl) + + blind() + + getImp() : BlindingMagicWeaponImpl + + swing() + + unwield() + + wield() + } } MagicWeapon --> "-imp" MagicWeaponImpl FlyingMagicWeapon --|> MagicWeapon -SoulEatingMagicWeaponImpl --|> MagicWeaponImpl -BlindingMagicWeapon --|> MagicWeapon Stormbringer --|> SoulEatingMagicWeaponImpl -BlindingMagicWeaponImpl --|> MagicWeaponImpl -SoulEatingMagicWeapon --|> MagicWeapon -Excalibur --|> BlindingMagicWeaponImpl FlyingMagicWeaponImpl --|> MagicWeaponImpl +SoulEatingMagicWeapon --|> MagicWeapon +SoulEatingMagicWeaponImpl --|> MagicWeaponImpl +Excalibur --|> BlindingMagicWeaponImpl Mjollnir --|> FlyingMagicWeaponImpl +BlindingMagicWeaponImpl --|> MagicWeaponImpl +BlindingMagicWeapon --|> MagicWeapon @enduml \ No newline at end of file diff --git a/builder/etc/builder.urm.puml b/builder/etc/builder.urm.puml index 262476329..0c98f3b4b 100644 --- a/builder/etc/builder.urm.puml +++ b/builder/etc/builder.urm.puml @@ -1,5 +1,23 @@ @startuml package com.iluwatar.builder { + class Builder { + - armor : Armor + - hairColor : HairColor + - hairType : HairType + - name : String + - profession : Profession + - weapon : Weapon + + Builder(profession : Profession, name : String) + + build() : Hero + + withArmor(armor : Armor) : Builder + + withHairColor(hairColor : HairColor) : Builder + + withHairType(hairType : HairType) : Builder + + withWeapon(weapon : Weapon) : Builder + } + class App { + + App() + + main(args : String[]) {static} + } class Hero { - armor : Armor - hairColor : HairColor @@ -16,33 +34,25 @@ package com.iluwatar.builder { + getWeapon() : Weapon + toString() : String } - class App { - + App() - + main(args : String[]) {static} - } - class Builder { - - armor : Armor - - hairColor : HairColor - - hairType : HairType - - name : String - - profession : Profession - - weapon : Weapon - + Builder(profession : Profession, name : String) - + build() : Hero - + withArmor(armor : Armor) : Builder - + withHairColor(hairColor : HairColor) : Builder - + withHairType(hairType : HairType) : Builder - + withWeapon(weapon : Weapon) : Builder - } - enum Armor { - + CHAIN_MAIL {static} - + CLOTHES {static} - + LEATHER {static} - + PLATE_MAIL {static} - - title : String + enum Weapon { + + AXE {static} + + BOW {static} + + DAGGER {static} + + SWORD {static} + + WARHAMMER {static} + toString() : String - + valueOf(name : String) : Armor {static} - + values() : Armor[] {static} + + valueOf(name : String) : Weapon {static} + + values() : Weapon[] {static} + } + enum HairColor { + + BLACK {static} + + BLOND {static} + + BROWN {static} + + RED {static} + + WHITE {static} + + toString() : String + + valueOf(name : String) : HairColor {static} + + values() : HairColor[] {static} } enum Profession { + MAGE {static} @@ -53,15 +63,15 @@ package com.iluwatar.builder { + valueOf(name : String) : Profession {static} + values() : Profession[] {static} } - enum Weapon { - + AXE {static} - + BOW {static} - + DAGGER {static} - + SWORD {static} - + WARHAMMER {static} + enum Armor { + + CHAIN_MAIL {static} + + CLOTHES {static} + + LEATHER {static} + + PLATE_MAIL {static} + - title : String + toString() : String - + valueOf(name : String) : Weapon {static} - + values() : Weapon[] {static} + + valueOf(name : String) : Armor {static} + + values() : Armor[] {static} } enum HairType { + BALD {static} @@ -74,19 +84,9 @@ package com.iluwatar.builder { + valueOf(name : String) : HairType {static} + values() : HairType[] {static} } - enum HairColor { - + BLACK {static} - + BLOND {static} - + BROWN {static} - + RED {static} - + WHITE {static} - + toString() : String - + valueOf(name : String) : HairColor {static} - + values() : HairColor[] {static} - } } -Builder ..+ Hero Hero --> "-profession" Profession +Builder ..+ Hero Hero --> "-armor" Armor App --+ Hero Builder --> "-weapon" Weapon diff --git a/business-delegate/etc/business-delegate.urm.puml b/business-delegate/etc/business-delegate.urm.puml index a8f31700b..a58136c8c 100644 --- a/business-delegate/etc/business-delegate.urm.puml +++ b/business-delegate/etc/business-delegate.urm.puml @@ -1,5 +1,9 @@ @startuml package com.iluwatar.business.delegate { + class EjbService { + + EjbService() + + doProcessing() + } class BusinessLookup { - ejbService : EjbService - jmsService : JmsService @@ -8,15 +12,18 @@ package com.iluwatar.business.delegate { + setEjbService(ejbService : EjbService) + setJmsService(jmsService : JmsService) } + class App { + + App() + + main(args : String[]) {static} + } + interface BusinessService { + + doProcessing() {abstract} + } class Client { - businessDelegate : BusinessDelegate + Client(businessDelegate : BusinessDelegate) + doTask() } - class EjbService { - + EjbService() - + doProcessing() - } class BusinessDelegate { - businessService : BusinessService - lookupService : BusinessLookup @@ -26,17 +33,10 @@ package com.iluwatar.business.delegate { + setLookupService(businessLookup : BusinessLookup) + setServiceType(serviceType : ServiceType) } - interface BusinessService { - + doProcessing() {abstract} - } class JmsService { + JmsService() + doProcessing() } - class App { - + App() - + main(args : String[]) {static} - } enum ServiceType { + EJB {static} + JMS {static} diff --git a/caching/etc/caching.urm.puml b/caching/etc/caching.urm.puml index 273c9911c..b8f4fb49b 100644 --- a/caching/etc/caching.urm.puml +++ b/caching/etc/caching.urm.puml @@ -1,17 +1,18 @@ @startuml package com.iluwatar.caching { - class UserAccount { - - additionalInfo : String - - userId : String - - userName : String - + UserAccount(userId : String, userName : String, additionalInfo : String) - + getAdditionalInfo() : String - + getUserId() : String - + getUserName() : String - + setAdditionalInfo(additionalInfo : String) - + setUserId(userId : String) - + setUserName(userName : String) - + toString() : String + class App { + + App() + + main(args : String[]) {static} + + useReadAndWriteThroughStrategy() + + useReadThroughAndWriteAroundStrategy() + + useReadThroughAndWriteBehindStrategy() + } + ~class Node { + ~ next : Node + ~ previous : Node + ~ userAccount : UserAccount + ~ userId : String + + Node(this$0 : String, userId : UserAccount) } class CacheStore { ~ cache : LruCache {static} @@ -36,12 +37,18 @@ package com.iluwatar.caching { + printCacheContent() : String {static} + save(userAccount : UserAccount) {static} } - ~class Node { - ~ next : Node - ~ previous : Node - ~ userAccount : UserAccount - ~ userId : String - + Node(this$0 : LruCache, userId : String, userAccount : UserAccount) + class UserAccount { + - additionalInfo : String + - userId : String + - userName : String + + UserAccount(userId : String, userName : String, additionalInfo : String) + + getAdditionalInfo() : String + + getUserId() : String + + getUserName() : String + + setAdditionalInfo(additionalInfo : String) + + setUserId(userId : String) + + setUserName(userName : String) + + toString() : String } class LruCache { ~ cache : Map @@ -74,13 +81,6 @@ package com.iluwatar.caching { + upsertDb(userAccount : UserAccount) {static} + writeToDb(userAccount : UserAccount) {static} } - class App { - + App() - + main(args : String[]) {static} - + useReadAndWriteThroughStrategy() - + useReadThroughAndWriteAroundStrategy() - + useReadThroughAndWriteBehindStrategy() - } enum CachingPolicy { + AROUND {static} + BEHIND {static} diff --git a/callback/etc/callback.urm.puml b/callback/etc/callback.urm.puml index 8b27ee8a8..b9e1ca694 100644 --- a/callback/etc/callback.urm.puml +++ b/callback/etc/callback.urm.puml @@ -1,24 +1,24 @@ @startuml package com.iluwatar.callback { - class LambdasApp { - + LambdasApp() - + main(args : String[]) {static} - } - class SimpleTask { - + SimpleTask() - + execute() - } - class App { - + App() - + main(args : String[]) {static} + interface Callback { + + call() {abstract} } abstract class Task { + Task() + execute() {abstract} + executeWith(callback : Callback) } - interface Callback { - + call() {abstract} + class App { + + App() + + main(args : String[]) {static} + } + class SimpleTask { + + SimpleTask() + + execute() + } + class LambdasApp { + + LambdasApp() + + main(args : String[]) {static} } } SimpleTask --|> Task diff --git a/chain/etc/chain.urm.puml b/chain/etc/chain.urm.puml index c75cbc8d1..21365765d 100644 --- a/chain/etc/chain.urm.puml +++ b/chain/etc/chain.urm.puml @@ -1,13 +1,20 @@ @startuml package com.iluwatar.chain { + class OrcSoldier { + + OrcSoldier(handler : RequestHandler) + + handleRequest(req : Request) + + toString() : String + } class OrcCommander { + OrcCommander(handler : RequestHandler) + handleRequest(req : Request) + toString() : String } - class App { - + App() - + main(args : String[]) {static} + class OrcKing { + ~ chain : RequestHandler + + OrcKing() + - buildChain() + + makeRequest(req : Request) } class Request { - handled : boolean @@ -20,21 +27,9 @@ package com.iluwatar.chain { + markHandled() + toString() : String } - class OrcOfficer { - + OrcOfficer(handler : RequestHandler) - + handleRequest(req : Request) - + toString() : String - } - class OrcKing { - ~ chain : RequestHandler - + OrcKing() - - buildChain() - + makeRequest(req : Request) - } - class OrcSoldier { - + OrcSoldier(handler : RequestHandler) - + handleRequest(req : Request) - + toString() : String + class App { + + App() + + main(args : String[]) {static} } abstract class RequestHandler { - next : RequestHandler @@ -43,6 +38,11 @@ package com.iluwatar.chain { # printHandling(req : Request) + toString() : String {abstract} } + class OrcOfficer { + + OrcOfficer(handler : RequestHandler) + + handleRequest(req : Request) + + toString() : String + } enum RequestType { + COLLECT_TAX {static} + DEFEND_CASTLE {static} @@ -52,9 +52,9 @@ package com.iluwatar.chain { } } RequestHandler --> "-next" RequestHandler -OrcKing --> "-chain" RequestHandler Request --> "-requestType" RequestType +OrcKing --> "-chain" RequestHandler +OrcSoldier --|> RequestHandler OrcCommander --|> RequestHandler OrcOfficer --|> RequestHandler -OrcSoldier --|> RequestHandler @enduml \ No newline at end of file diff --git a/command/etc/command.urm.puml b/command/etc/command.urm.puml index 015fb30be..27bff7330 100644 --- a/command/etc/command.urm.puml +++ b/command/etc/command.urm.puml @@ -1,29 +1,5 @@ @startuml package com.iluwatar.command { - abstract class Target { - - size : Size - - visibility : Visibility - + Target() - + getSize() : Size - + getVisibility() : Visibility - + printStatus() - + setSize(size : Size) - + setVisibility(visibility : Visibility) - + toString() : String {abstract} - } - class Goblin { - + Goblin() - + toString() : String - } - class ShrinkSpell { - - oldSize : Size - - target : Target - + ShrinkSpell() - + execute(target : Target) - + redo() - + toString() : String - + undo() - } class InvisibilitySpell { - target : Target + InvisibilitySpell() @@ -32,15 +8,6 @@ package com.iluwatar.command { + toString() : String + undo() } - class Wizard { - - redoStack : Deque - - undoStack : Deque - + Wizard() - + castSpell(command : Command, target : Target) - + redoLastSpell() - + toString() : String - + undoLastSpell() - } class App { + App() + main(args : String[]) {static} @@ -52,6 +19,39 @@ package com.iluwatar.command { + toString() : String {abstract} + undo() {abstract} } + class Goblin { + + Goblin() + + toString() : String + } + abstract class Target { + - size : Size + - visibility : Visibility + + Target() + + getSize() : Size + + getVisibility() : Visibility + + printStatus() + + setSize(size : Size) + + setVisibility(visibility : Visibility) + + toString() : String {abstract} + } + class Wizard { + - redoStack : Deque + - undoStack : Deque + + Wizard() + + castSpell(command : Command, target : Target) + + redoLastSpell() + + toString() : String + + undoLastSpell() + } + class ShrinkSpell { + - oldSize : Size + - target : Target + + ShrinkSpell() + + execute(target : Target) + + redo() + + toString() : String + + undo() + } enum Size { + LARGE {static} + NORMAL {static} @@ -78,7 +78,7 @@ ShrinkSpell --> "-oldSize" Size InvisibilitySpell --> "-target" Target ShrinkSpell --> "-target" Target Target --> "-visibility" Visibility +InvisibilitySpell --|> Command Goblin --|> Target ShrinkSpell --|> Command -InvisibilitySpell --|> Command @enduml \ No newline at end of file diff --git a/composite/etc/composite.urm.puml b/composite/etc/composite.urm.puml index 6f6e93c98..82e9b65eb 100644 --- a/composite/etc/composite.urm.puml +++ b/composite/etc/composite.urm.puml @@ -1,5 +1,19 @@ @startuml package com.iluwatar.composite { + class Word { + + Word(letters : List) + # printThisAfter() + # printThisBefore() + } + class App { + + App() + + main(args : String[]) {static} + } + class Messenger { + + Messenger() + ~ messageFromElves() : LetterComposite + ~ messageFromOrcs() : LetterComposite + } class Letter { - c : char + Letter(c : char) @@ -11,20 +25,6 @@ package com.iluwatar.composite { # printThisAfter() # printThisBefore() } - class Word { - + Word(letters : List) - # printThisAfter() - # printThisBefore() - } - class Messenger { - + Messenger() - ~ messageFromElves() : LetterComposite - ~ messageFromOrcs() : LetterComposite - } - class App { - + App() - + main(args : String[]) {static} - } abstract class LetterComposite { - children : List + LetterComposite() @@ -36,7 +36,7 @@ package com.iluwatar.composite { } } LetterComposite --> "-children" LetterComposite +Word --|> LetterComposite Letter --|> LetterComposite Sentence --|> LetterComposite -Word --|> LetterComposite @enduml \ No newline at end of file diff --git a/dao/etc/dao.urm.puml b/dao/etc/dao.urm.puml index f751b967c..90a9c9725 100644 --- a/dao/etc/dao.urm.puml +++ b/dao/etc/dao.urm.puml @@ -1,5 +1,49 @@ @startuml package com.iluwatar.dao { + class InMemoryCustomerDao { + - idToCustomer : Map + + InMemoryCustomerDao() + + add(customer : Customer) : boolean + + delete(customer : Customer) : boolean + + getAll() : Stream + + getById(id : int) : Optional + + update(customer : Customer) : boolean + } + interface CustomerSchemaSql { + + CREATE_SCHEMA_SQL : String {static} + + DELETE_SCHEMA_SQL : String {static} + } + interface CustomerDao { + + add(Customer) : boolean {abstract} + + delete(Customer) : boolean {abstract} + + getAll() : Stream {abstract} + + getById(int) : Optional {abstract} + + update(Customer) : boolean {abstract} + } + class App { + - DB_URL : String {static} + - log : Logger {static} + + App() + - addCustomers(customerDao : CustomerDao) {static} + - createDataSource() : DataSource {static} + - createSchema(dataSource : DataSource) {static} + - deleteSchema(dataSource : DataSource) {static} + + generateSampleCustomers() : List {static} + + main(args : String[]) {static} + - performOperationsUsing(customerDao : CustomerDao) {static} + } + class DbCustomerDao { + - dataSource : DataSource + + DbCustomerDao(dataSource : DataSource) + + add(customer : Customer) : boolean + - createCustomer(resultSet : ResultSet) : Customer + + delete(customer : Customer) : boolean + + getAll() : Stream + + getById(id : int) : Optional + - getConnection() : Connection + - mutedClose(connection : Connection) + + update(customer : Customer) : boolean + } class Customer { - firstName : String - id : int @@ -15,51 +59,7 @@ package com.iluwatar.dao { + setLastName(lastName : String) + toString() : String } - interface CustomerDao { - + add(Customer) : boolean {abstract} - + delete(Customer) : boolean {abstract} - + getAll() : Stream {abstract} - + getById(int) : Optional {abstract} - + update(Customer) : boolean {abstract} - } - class DbCustomerDao { - - dataSource : DataSource - + DbCustomerDao(dataSource : DataSource) - + add(customer : Customer) : boolean - - createCustomer(resultSet : ResultSet) : Customer - + delete(customer : Customer) : boolean - + getAll() : Stream - + getById(id : int) : Optional - - getConnection() : Connection - - mutedClose(connection : Connection) - + update(customer : Customer) : boolean - } - class InMemoryCustomerDao { - - idToCustomer : Map - + InMemoryCustomerDao() - + add(customer : Customer) : boolean - + delete(customer : Customer) : boolean - + getAll() : Stream - + getById(id : int) : Optional - + update(customer : Customer) : boolean - } - interface CustomerSchemaSql { - + CREATE_SCHEMA_SQL : String {static} - + DELETE_SCHEMA_SQL : String {static} - } - class App { - - DB_URL : String {static} - - log : Logger {static} - + App() - - addCustomers(customerDao : CustomerDao) {static} - - createDataSource() : DataSource {static} - - createSchema(dataSource : DataSource) {static} - - deleteSchema(dataSource : DataSource) {static} - + generateSampleCustomers() : List {static} - + main(args : String[]) {static} - - performOperationsUsing(customerDao : CustomerDao) {static} - } } -DbCustomerDao ..|> CustomerDao InMemoryCustomerDao ..|> CustomerDao +DbCustomerDao ..|> CustomerDao @enduml \ No newline at end of file diff --git a/decorator/etc/decorator.urm.puml b/decorator/etc/decorator.urm.puml index 6c44e6cc9..4862ddfeb 100644 --- a/decorator/etc/decorator.urm.puml +++ b/decorator/etc/decorator.urm.puml @@ -1,5 +1,10 @@ @startuml package com.iluwatar.decorator { + interface Hostile { + + attack() {abstract} + + fleeBattle() {abstract} + + getAttackPower() : int {abstract} + } class App { + App() + main(args : String[]) {static} @@ -10,11 +15,6 @@ package com.iluwatar.decorator { + fleeBattle() + getAttackPower() : int } - interface Hostile { - + attack() {abstract} - + fleeBattle() {abstract} - + getAttackPower() : int {abstract} - } class SmartHostile { - decorated : Hostile + SmartHostile(decorated : Hostile) diff --git a/delegation/etc/delegation.urm.puml b/delegation/etc/delegation.urm.puml index c143a6ba0..378587019 100644 --- a/delegation/etc/delegation.urm.puml +++ b/delegation/etc/delegation.urm.puml @@ -1,19 +1,24 @@ @startuml package com.iluwatar.delegation.simple.printers { - class EpsonPrinter { - + EpsonPrinter() - + print(message : String) - } class HpPrinter { + HpPrinter() + print(message : String) } + class EpsonPrinter { + + EpsonPrinter() + + print(message : String) + } class CanonPrinter { + CanonPrinter() + print(message : String) } } package com.iluwatar.delegation.simple { + class App { + + MESSAGE_TO_PRINT : String {static} + + App() + + main(args : String[]) {static} + } class PrinterController { - printer : Printer + PrinterController(printer : Printer) @@ -22,15 +27,10 @@ package com.iluwatar.delegation.simple { interface Printer { + print(String) {abstract} } - class App { - + MESSAGE_TO_PRINT : String {static} - + App() - + main(args : String[]) {static} - } } PrinterController --> "-printer" Printer +HpPrinter ..|> Printer PrinterController ..|> Printer EpsonPrinter ..|> Printer -HpPrinter ..|> Printer CanonPrinter ..|> Printer @enduml \ No newline at end of file diff --git a/dependency-injection/etc/dependency-injection.urm.puml b/dependency-injection/etc/dependency-injection.urm.puml index c22c658ad..bf4d10599 100644 --- a/dependency-injection/etc/dependency-injection.urm.puml +++ b/dependency-injection/etc/dependency-injection.urm.puml @@ -1,48 +1,48 @@ @startuml package com.iluwatar.dependency.injection { - interface Wizard { - + smoke() {abstract} - } - class GuiceWizard { - - tobacco : Tobacco - + GuiceWizard(tobacco : Tobacco) - + smoke() - } - class OldTobyTobacco { - + OldTobyTobacco() - } - abstract class Tobacco { - + Tobacco() - + smoke(wizard : Wizard) - } - class App { - + App() - + main(args : String[]) {static} - } - class RivendellTobacco { - + RivendellTobacco() - } class AdvancedWizard { - tobacco : Tobacco + AdvancedWizard(tobacco : Tobacco) + smoke() } - class SecondBreakfastTobacco { - + SecondBreakfastTobacco() + interface Wizard { + + smoke() {abstract} + } + class RivendellTobacco { + + RivendellTobacco() } class SimpleWizard { - tobacco : OldTobyTobacco + SimpleWizard() + smoke() } + class OldTobyTobacco { + + OldTobyTobacco() + } + class SecondBreakfastTobacco { + + SecondBreakfastTobacco() + } + class App { + + App() + + main(args : String[]) {static} + } + abstract class Tobacco { + + Tobacco() + + smoke(wizard : Wizard) + } + class GuiceWizard { + - tobacco : Tobacco + + GuiceWizard(tobacco : Tobacco) + + smoke() + } } SimpleWizard --> "-tobacco" OldTobyTobacco AdvancedWizard --> "-tobacco" Tobacco GuiceWizard --> "-tobacco" Tobacco -GuiceWizard ..|> Wizard -OldTobyTobacco --|> Tobacco -RivendellTobacco --|> Tobacco AdvancedWizard ..|> Wizard -SecondBreakfastTobacco --|> Tobacco +RivendellTobacco --|> Tobacco SimpleWizard ..|> Wizard +OldTobyTobacco --|> Tobacco +SecondBreakfastTobacco --|> Tobacco +GuiceWizard ..|> Wizard @enduml \ No newline at end of file diff --git a/double-dispatch/etc/double-dispatch.urm.puml b/double-dispatch/etc/double-dispatch.urm.puml index 725f009c0..78d361326 100644 --- a/double-dispatch/etc/double-dispatch.urm.puml +++ b/double-dispatch/etc/double-dispatch.urm.puml @@ -1,17 +1,5 @@ @startuml package com.iluwatar.doubledispatch { - class App { - + App() - + main(args : String[]) {static} - } - class FlamingAsteroid { - + FlamingAsteroid(left : int, top : int, right : int, bottom : int) - + collision(gameObject : GameObject) - } - class SpaceStationIss { - + SpaceStationIss(left : int, top : int, right : int, bottom : int) - + collision(gameObject : GameObject) - } abstract class GameObject { - damaged : boolean - onFire : boolean @@ -27,6 +15,14 @@ package com.iluwatar.doubledispatch { + setOnFire(onFire : boolean) + toString() : String } + class SpaceStationIss { + + SpaceStationIss(left : int, top : int, right : int, bottom : int) + + collision(gameObject : GameObject) + } + class FlamingAsteroid { + + FlamingAsteroid(left : int, top : int, right : int, bottom : int) + + collision(gameObject : GameObject) + } class SpaceStationMir { + SpaceStationMir(left : int, top : int, right : int, bottom : int) + collision(gameObject : GameObject) @@ -56,10 +52,14 @@ package com.iluwatar.doubledispatch { ~ intersectsWith(r : Rectangle) : boolean + toString() : String } + class App { + + App() + + main(args : String[]) {static} + } } -FlamingAsteroid --|> Meteoroid -SpaceStationIss --|> SpaceStationMir GameObject --|> Rectangle +SpaceStationIss --|> SpaceStationMir +FlamingAsteroid --|> Meteoroid SpaceStationMir --|> GameObject Meteoroid --|> GameObject @enduml \ No newline at end of file diff --git a/event-aggregator/etc/event-aggregator.urm.puml b/event-aggregator/etc/event-aggregator.urm.puml index 18b7621c9..3ccfea536 100644 --- a/event-aggregator/etc/event-aggregator.urm.puml +++ b/event-aggregator/etc/event-aggregator.urm.puml @@ -1,34 +1,10 @@ @startuml package com.iluwatar.event.aggregator { - class KingsHand { - + KingsHand() - + KingsHand(obs : EventObserver) - + onEvent(e : Event) - + timePasses(day : Weekday) - } - class KingJoffrey { - + KingJoffrey() - + onEvent(e : Event) - } - class Scout { - + Scout() - + Scout(obs : EventObserver) - + timePasses(day : Weekday) - } class LordVarys { + LordVarys() + LordVarys(obs : EventObserver) + timePasses(day : Weekday) } - class App { - + App() - + main(args : String[]) {static} - } - class LordBaelish { - + LordBaelish() - + LordBaelish(obs : EventObserver) - + timePasses(day : Weekday) - } abstract class EventEmitter { - observers : List + EventEmitter() @@ -37,9 +13,33 @@ package com.iluwatar.event.aggregator { + registerObserver(obs : EventObserver) + timePasses(Weekday) {abstract} } + class KingJoffrey { + + KingJoffrey() + + onEvent(e : Event) + } + class LordBaelish { + + LordBaelish() + + LordBaelish(obs : EventObserver) + + timePasses(day : Weekday) + } interface EventObserver { + onEvent(Event) {abstract} } + class KingsHand { + + KingsHand() + + KingsHand(obs : EventObserver) + + onEvent(e : Event) + + timePasses(day : Weekday) + } + class Scout { + + Scout() + + Scout(obs : EventObserver) + + timePasses(day : Weekday) + } + class App { + + App() + + main(args : String[]) {static} + } enum Weekday { + FRIDAY {static} + MONDAY {static} @@ -64,10 +64,10 @@ package com.iluwatar.event.aggregator { } } EventEmitter --> "-observers" EventObserver +LordVarys --|> EventEmitter +KingJoffrey ..|> EventObserver +LordBaelish --|> EventEmitter KingsHand ..|> EventObserver KingsHand --|> EventEmitter -KingJoffrey ..|> EventObserver Scout --|> EventEmitter -LordVarys --|> EventEmitter -LordBaelish --|> EventEmitter @enduml \ No newline at end of file diff --git a/event-driven-architecture/etc/event-driven-architecture.urm.puml b/event-driven-architecture/etc/event-driven-architecture.urm.puml index 55039190f..8314913a6 100644 --- a/event-driven-architecture/etc/event-driven-architecture.urm.puml +++ b/event-driven-architecture/etc/event-driven-architecture.urm.puml @@ -1,31 +1,34 @@ @startuml package com.iluwatar.eda.handler { - class UserUpdatedEventHandler { - + UserUpdatedEventHandler() - + onEvent(event : UserUpdatedEvent) - } class UserCreatedEventHandler { + UserCreatedEventHandler() + onEvent(event : UserCreatedEvent) } + class UserUpdatedEventHandler { + + UserUpdatedEventHandler() + + onEvent(event : UserUpdatedEvent) + } } package com.iluwatar.eda.event { abstract class AbstractEvent { + AbstractEvent() + getType() : Class } - class UserUpdatedEvent { - - user : User - + UserUpdatedEvent(user : User) - + getUser() : User - } class UserCreatedEvent { - user : User + UserCreatedEvent(user : User) + getUser() : User } + class UserUpdatedEvent { + - user : User + + UserUpdatedEvent(user : User) + + getUser() : User + } } package com.iluwatar.eda.framework { + interface Handler { + + onEvent(E extends Event) {abstract} + } class EventDispatcher { - handlers : Map, Handler> + EventDispatcher() @@ -35,9 +38,6 @@ package com.iluwatar.eda.framework { interface Event { + getType() : Class {abstract} } - interface Handler { - + onEvent(E extends Event) {abstract} - } } package com.iluwatar.eda.model { class User { @@ -52,11 +52,11 @@ package com.iluwatar.eda { + main(args : String[]) {static} } } -UserCreatedEvent --> "-user" User UserUpdatedEvent --> "-user" User +UserCreatedEvent --> "-user" User AbstractEvent ..|> Event -UserUpdatedEventHandler ..|> Handler +UserCreatedEvent --|> AbstractEvent UserCreatedEventHandler ..|> Handler UserUpdatedEvent --|> AbstractEvent -UserCreatedEvent --|> AbstractEvent +UserUpdatedEventHandler ..|> Handler @enduml \ No newline at end of file diff --git a/execute-around/etc/execute-around.urm.puml b/execute-around/etc/execute-around.urm.puml index 66d23ce7a..4fdc4bffb 100644 --- a/execute-around/etc/execute-around.urm.puml +++ b/execute-around/etc/execute-around.urm.puml @@ -1,8 +1,5 @@ @startuml package com.iluwatar.execute.around { - interface FileWriterAction { - + writeFile(FileWriter) {abstract} - } class SimpleFileWriter { + SimpleFileWriter(filename : String, action : FileWriterAction) } @@ -10,5 +7,8 @@ package com.iluwatar.execute.around { + App() + main(args : String[]) {static} } + interface FileWriterAction { + + writeFile(FileWriter) {abstract} + } } @enduml \ No newline at end of file diff --git a/facade/etc/facade.urm.puml b/facade/etc/facade.urm.puml index f72bc2b62..8c53cb728 100644 --- a/facade/etc/facade.urm.puml +++ b/facade/etc/facade.urm.puml @@ -1,7 +1,7 @@ @startuml package com.iluwatar.facade { - class DwarvenTunnelDigger { - + DwarvenTunnelDigger() + class DwarvenGoldDigger { + + DwarvenGoldDigger() + name() : String + work() } @@ -13,15 +13,11 @@ package com.iluwatar.facade { - makeActions(workers : Collection, actions : Action[]) {static} + startNewDay() } - class DwarvenGoldDigger { - + DwarvenGoldDigger() + class DwarvenTunnelDigger { + + DwarvenTunnelDigger() + name() : String + work() } - class App { - + App() - + main(args : String[]) {static} - } abstract class DwarvenMineWorker { + DwarvenMineWorker() - action(action : Action) @@ -33,6 +29,10 @@ package com.iluwatar.facade { + wakeUp() + work() {abstract} } + class App { + + App() + + main(args : String[]) {static} + } class DwarvenCartOperator { + DwarvenCartOperator() + name() : String @@ -51,7 +51,7 @@ package com.iluwatar.facade { DwarvenGoldmineFacade --+ DwarvenMineWorker DwarvenGoldmineFacade --> "-workers" DwarvenMineWorker Action ..+ DwarvenMineWorker -DwarvenTunnelDigger --|> DwarvenMineWorker DwarvenGoldDigger --|> DwarvenMineWorker +DwarvenTunnelDigger --|> DwarvenMineWorker DwarvenCartOperator --|> DwarvenMineWorker @enduml \ No newline at end of file diff --git a/factory-kit/etc/factory-kit.urm.puml b/factory-kit/etc/factory-kit.urm.puml index faf5727eb..fdee9a01c 100644 --- a/factory-kit/etc/factory-kit.urm.puml +++ b/factory-kit/etc/factory-kit.urm.puml @@ -1,33 +1,33 @@ @startuml package com.iluwatar.factorykit { - interface Builder { - + add(WeaponType, Supplier) {abstract} - } class Spear { + Spear() + toString() : String } - class Bow { - + Bow() + class App { + + App() + + main(args : String[]) {static} + } + interface Weapon { + } + interface WeaponFactory { + + create(WeaponType) : Weapon {abstract} + + factory(consumer : Consumer) : WeaponFactory {static} + } + class Axe { + + Axe() + toString() : String } class Sword { + Sword() + toString() : String } - interface Weapon { - } - class App { - + App() - + main(args : String[]) {static} - } - class Axe { - + Axe() + class Bow { + + Bow() + toString() : String } - interface WeaponFactory { - + create(WeaponType) : Weapon {abstract} - + factory(consumer : Consumer) : WeaponFactory {static} + interface Builder { + + add(WeaponType, Supplier) {abstract} } enum WeaponType { + AXE {static} @@ -39,7 +39,7 @@ package com.iluwatar.factorykit { } } Spear ..|> Weapon -Bow ..|> Weapon -Sword ..|> Weapon Axe ..|> Weapon +Sword ..|> Weapon +Bow ..|> Weapon @enduml \ No newline at end of file diff --git a/factory-method/etc/factory-method.urm.puml b/factory-method/etc/factory-method.urm.puml index ebc9d2ff7..d61984a85 100644 --- a/factory-method/etc/factory-method.urm.puml +++ b/factory-method/etc/factory-method.urm.puml @@ -17,9 +17,6 @@ package com.iluwatar.factory.method { interface Blacksmith { + manufactureWeapon(WeaponType) : Weapon {abstract} } - interface Weapon { - + getWeaponType() : WeaponType {abstract} - } class ElfWeapon { - weaponType : WeaponType + ElfWeapon(weaponType : WeaponType) @@ -32,6 +29,9 @@ package com.iluwatar.factory.method { + main(args : String[]) {static} - manufactureWeapons() } + interface Weapon { + + getWeaponType() : WeaponType {abstract} + } enum WeaponType { + AXE {static} + SHORT_SWORD {static} diff --git a/feature-toggle/etc/feature-toggle.urm.puml b/feature-toggle/etc/feature-toggle.urm.puml index 762d49cb3..6c935f3e6 100644 --- a/feature-toggle/etc/feature-toggle.urm.puml +++ b/feature-toggle/etc/feature-toggle.urm.puml @@ -20,17 +20,17 @@ package com.iluwatar.featuretoggle.user { + isPaid(user : User) : boolean {static} } } -package com.iluwatar.featuretoggle.pattern.propertiesversion { - class PropertiesFeatureToggleVersion { - - isEnhanced : boolean - + PropertiesFeatureToggleVersion(properties : Properties) +package com.iluwatar.featuretoggle.pattern.tieredversion { + class TieredFeatureToggleVersion { + + TieredFeatureToggleVersion() + getWelcomeMessage(user : User) : String + isEnhanced() : boolean } } -package com.iluwatar.featuretoggle.pattern.tieredversion { - class TieredFeatureToggleVersion { - + TieredFeatureToggleVersion() +package com.iluwatar.featuretoggle.pattern.propertiesversion { + class PropertiesFeatureToggleVersion { + - isEnhanced : boolean + + PropertiesFeatureToggleVersion(properties : Properties) + getWelcomeMessage(user : User) : String + isEnhanced() : boolean } @@ -42,6 +42,6 @@ package com.iluwatar.featuretoggle { } } UserGroup --> "-freeGroup" User -TieredFeatureToggleVersion ..|> Service PropertiesFeatureToggleVersion ..|> Service +TieredFeatureToggleVersion ..|> Service @enduml \ No newline at end of file diff --git a/fluentinterface/etc/fluentinterface.urm.puml b/fluentinterface/etc/fluentinterface.urm.puml index 436fcb2e8..0283e20b5 100644 --- a/fluentinterface/etc/fluentinterface.urm.puml +++ b/fluentinterface/etc/fluentinterface.urm.puml @@ -31,6 +31,14 @@ package com.iluwatar.fluentinterface.app { } } package com.iluwatar.fluentinterface.fluentiterable.lazy { + abstract class DecoratingIterator { + # fromIterator : Iterator + - next : E + + DecoratingIterator(fromIterator : Iterator) + + computeNext() : E {abstract} + + hasNext() : boolean + + next() : E + } class LazyFluentIterable { - iterable : Iterable # LazyFluentIterable() @@ -45,14 +53,6 @@ package com.iluwatar.fluentinterface.fluentiterable.lazy { + last(count : int) : FluentIterable + map(function : Function) : FluentIterable } - abstract class DecoratingIterator { - # fromIterator : Iterator - - next : E - + DecoratingIterator(fromIterator : Iterator) - + computeNext() : E {abstract} - + hasNext() : boolean - + next() : E - } } package com.iluwatar.fluentinterface.fluentiterable { interface FluentIterable { diff --git a/flux/etc/flux.urm.puml b/flux/etc/flux.urm.puml index e4bece2fc..a4e0b0622 100644 --- a/flux/etc/flux.urm.puml +++ b/flux/etc/flux.urm.puml @@ -1,10 +1,8 @@ @startuml package com.iluwatar.flux.view { - class ContentView { - - content : Content - + ContentView() - + render() - + storeChanged(store : Store) + interface View { + + render() {abstract} + + storeChanged(Store) {abstract} } class MenuView { - selected : MenuItem @@ -13,27 +11,35 @@ package com.iluwatar.flux.view { + render() + storeChanged(store : Store) } - interface View { - + render() {abstract} - + storeChanged(Store) {abstract} + class ContentView { + - content : Content + + ContentView() + + render() + + storeChanged(store : Store) } } package com.iluwatar.flux.action { - class ContentAction { - - content : Content - + ContentAction(content : Content) - + getContent() : Content - } class MenuAction { - menuItem : MenuItem + MenuAction(menuItem : MenuItem) + getMenuItem() : MenuItem } + class ContentAction { + - content : Content + + ContentAction(content : Content) + + getContent() : Content + } abstract class Action { - type : ActionType + Action(type : ActionType) + getType() : ActionType } + enum ActionType { + + CONTENT_CHANGED {static} + + MENU_ITEM_SELECTED {static} + + valueOf(name : String) : ActionType {static} + + values() : ActionType[] {static} + } enum MenuItem { + COMPANY {static} + HOME {static} @@ -51,12 +57,6 @@ package com.iluwatar.flux.action { + valueOf(name : String) : Content {static} + values() : Content[] {static} } - enum ActionType { - + CONTENT_CHANGED {static} - + MENU_ITEM_SELECTED {static} - + valueOf(name : String) : ActionType {static} - + values() : ActionType[] {static} - } } package com.iluwatar.flux.app { class App { @@ -64,27 +64,6 @@ package com.iluwatar.flux.app { + main(args : String[]) {static} } } -package com.iluwatar.flux.store { - abstract class Store { - - views : List - + Store() - # notifyChange() - + onAction(Action) {abstract} - + registerView(view : View) - } - class ContentStore { - - content : Content - + ContentStore() - + getContent() : Content - + onAction(action : Action) - } - class MenuStore { - - selected : MenuItem - + MenuStore() - + getSelected() : MenuItem - + onAction(action : Action) - } -} package com.iluwatar.flux.dispatcher { class Dispatcher { - instance : Dispatcher {static} @@ -96,6 +75,27 @@ package com.iluwatar.flux.dispatcher { + registerStore(store : Store) } } +package com.iluwatar.flux.store { + class ContentStore { + - content : Content + + ContentStore() + + getContent() : Content + + onAction(action : Action) + } + class MenuStore { + - selected : MenuItem + + MenuStore() + + getSelected() : MenuItem + + onAction(action : Action) + } + abstract class Store { + - views : List + + Store() + # notifyChange() + + onAction(Action) {abstract} + + registerView(view : View) + } +} MenuAction --> "-menuItem" MenuItem Action --> "-type" ActionType MenuStore --> "-selected" MenuItem @@ -104,12 +104,12 @@ ContentView --> "-content" Content Dispatcher --> "-stores" Store MenuView --> "-selected" MenuItem Store --> "-views" View -ContentStore --> "-content" Content ContentAction --> "-content" Content -ContentAction --|> Action +ContentStore --> "-content" Content ContentStore --|> Store -ContentView ..|> View MenuAction --|> Action -MenuView ..|> View MenuStore --|> Store +ContentAction --|> Action +MenuView ..|> View +ContentView ..|> View @enduml \ No newline at end of file diff --git a/flyweight/etc/flyweight.urm.puml b/flyweight/etc/flyweight.urm.puml index 98a2b4721..3f2203712 100644 --- a/flyweight/etc/flyweight.urm.puml +++ b/flyweight/etc/flyweight.urm.puml @@ -1,28 +1,17 @@ @startuml package com.iluwatar.flyweight { - class PoisonPotion { - + PoisonPotion() - + drink() - } - class StrengthPotion { - + StrengthPotion() - + drink() - } - class HealingPotion { - + HealingPotion() - + drink() - } class PotionFactory { - potions : Map + PotionFactory() ~ createPotion(type : PotionType) : Potion } - interface Potion { - + drink() {abstract} + class HealingPotion { + + HealingPotion() + + drink() } - class App { - + App() - + main(args : String[]) {static} + class InvisibilityPotion { + + InvisibilityPotion() + + drink() } class AlchemistShop { - bottomShelf : List @@ -33,12 +22,23 @@ package com.iluwatar.flyweight { + getBottomShelf() : List + getTopShelf() : List } - class HolyWaterPotion { - + HolyWaterPotion() + class App { + + App() + + main(args : String[]) {static} + } + interface Potion { + + drink() {abstract} + } + class PoisonPotion { + + PoisonPotion() + drink() } - class InvisibilityPotion { - + InvisibilityPotion() + class StrengthPotion { + + StrengthPotion() + + drink() + } + class HolyWaterPotion { + + HolyWaterPotion() + drink() } enum PotionType { @@ -52,9 +52,9 @@ package com.iluwatar.flyweight { } } AlchemistShop --> "-topShelf" Potion +HealingPotion ..|> Potion +InvisibilityPotion ..|> Potion PoisonPotion ..|> Potion StrengthPotion ..|> Potion -HealingPotion ..|> Potion HolyWaterPotion ..|> Potion -InvisibilityPotion ..|> Potion @enduml \ No newline at end of file diff --git a/front-controller/etc/front-controller.urm.puml b/front-controller/etc/front-controller.urm.puml index 17ccebae1..8fb9be184 100644 --- a/front-controller/etc/front-controller.urm.puml +++ b/front-controller/etc/front-controller.urm.puml @@ -1,5 +1,20 @@ @startuml package com.iluwatar.front.controller { + class ArcherView { + + ArcherView() + + display() + } + interface View { + + display() {abstract} + } + class CatapultView { + + CatapultView() + + display() + } + class ArcherCommand { + + ArcherCommand() + + process() + } class App { + App() + main(args : String[]) {static} @@ -10,41 +25,26 @@ package com.iluwatar.front.controller { - getCommandClass(request : String) : Class {static} + handleRequest(request : String) } - class ArcherView { - + ArcherView() - + display() - } - interface View { - + display() {abstract} - } - interface Command { - + process() {abstract} + class UnknownCommand { + + UnknownCommand() + + process() } class ErrorView { + ErrorView() + display() } - class ArcherCommand { - + ArcherCommand() - + process() - } - class CatapultView { - + CatapultView() - + display() - } class CatapultCommand { + CatapultCommand() + process() } - class UnknownCommand { - + UnknownCommand() - + process() + interface Command { + + process() {abstract} } } ArcherView ..|> View -ErrorView ..|> View -ArcherCommand ..|> Command CatapultView ..|> View -CatapultCommand ..|> Command +ArcherCommand ..|> Command UnknownCommand ..|> Command +ErrorView ..|> View +CatapultCommand ..|> Command @enduml \ No newline at end of file diff --git a/half-sync-half-async/etc/half-sync-half-async.urm.puml b/half-sync-half-async/etc/half-sync-half-async.urm.puml index e733dd586..88f49eb4d 100644 --- a/half-sync-half-async/etc/half-sync-half-async.urm.puml +++ b/half-sync-half-async/etc/half-sync-half-async.urm.puml @@ -1,5 +1,18 @@ @startuml package com.iluwatar.halfsynchalfasync { + class AsynchronousService { + - service : ExecutorService + + AsynchronousService(workQueue : BlockingQueue) + + execute(task : AsyncTask) + } + ~class ArithmeticSumTask { + - n : long + + ArithmeticSumTask(n : long) + + call() : Long + + onError(throwable : Throwable) + + onPostCall(result : Long) + + onPreCall() + } class App { + App() - ap(i : long) : long {static} @@ -11,19 +24,6 @@ package com.iluwatar.halfsynchalfasync { + onPostCall(O) {abstract} + onPreCall() {abstract} } - ~class ArithmeticSumTask { - - n : long - + ArithmeticSumTask(n : long) - + call() : Long - + onError(throwable : Throwable) - + onPostCall(result : Long) - + onPreCall() - } - class AsynchronousService { - - service : ExecutorService - + AsynchronousService(workQueue : BlockingQueue) - + execute(task : AsyncTask) - } } ArithmeticSumTask ..+ App ArithmeticSumTask ..|> AsyncTask diff --git a/hexagonal/etc/hexagonal.urm.puml b/hexagonal/etc/hexagonal.urm.puml index c4b0d0a73..a2f5d0469 100644 --- a/hexagonal/etc/hexagonal.urm.puml +++ b/hexagonal/etc/hexagonal.urm.puml @@ -1,31 +1,47 @@ @startuml -package com.iluwatar.hexagonal.service { - class LotteryServiceImpl { - - bank : WireTransfers - - notifications : LotteryNotifications - - repository : LotteryTicketRepository - + LotteryServiceImpl() - + checkTicketForPrize(id : LotteryTicketId, winningNumbers : LotteryNumbers) : LotteryTicketCheckResult - + submitTicket(ticket : LotteryTicket) : Optional +package com.iluwatar.hexagonal.sampledata { + class SampleData { + - PLAYERS : List {static} + + SampleData() + - getRandomPlayerDetails() : PlayerDetails {static} + + submitTickets(lotteryService : LotteryService, numTickets : int) {static} } - interface LotteryService { - + checkTicketForPrize(LotteryTicketId, LotteryNumbers) : LotteryTicketCheckResult {abstract} - + submitTicket(LotteryTicket) : Optional {abstract} +} +package com.iluwatar.hexagonal.service { + class ConsoleLottery { + + ConsoleLottery() + + main(args : String[]) {static} + - printMainMenu() {static} + - readString(scanner : Scanner) : String {static} + } +} +package com.iluwatar.hexagonal.mongo { + class MongoConnectionPropertiesLoader { + - DEFAULT_HOST : String {static} + - DEFAULT_PORT : int {static} + + MongoConnectionPropertiesLoader() + + load() {static} } } package com.iluwatar.hexagonal.domain { class LotteryTicketId { - - id : UUID + - id : int + - numAllocated : int {static} + LotteryTicketId() - + getId() : UUID + + LotteryTicketId(id : int) + + equals(o : Object) : boolean + + getId() : int + + hashCode() : int + + toString() : String } - class LotteryConstants { - + PLAYER_MAX_SALDO : int {static} - + PRIZE_AMOUNT : int {static} - + SERVICE_BANK_ACCOUNT : String {static} - + SERVICE_BANK_ACCOUNT_SALDO : int {static} - + TICKET_PRIZE : int {static} - + LotteryConstants() + class LotteryAdministration { + - notifications : LotteryEventLog + - repository : LotteryTicketRepository + - wireTransfers : WireTransfers + + LotteryAdministration(repository : LotteryTicketRepository, notifications : LotteryEventLog, wireTransfers : WireTransfers) + + getAllSubmittedTickets() : Map + + performLottery() : LotteryNumbers + + resetLottery() } class LotteryNumbers { + MAX_NUMBER : int {static} @@ -39,19 +55,34 @@ package com.iluwatar.hexagonal.domain { + equals(obj : Object) : boolean - generateRandomNumbers() + getNumbers() : Set + + getNumbersAsString() : String + hashCode() : int + + toString() : String + } + class LotteryService { + - notifications : LotteryEventLog + - repository : LotteryTicketRepository + - wireTransfers : WireTransfers + + LotteryService(repository : LotteryTicketRepository, notifications : LotteryEventLog, wireTransfers : WireTransfers) + + checkTicketForPrize(id : LotteryTicketId, winningNumbers : LotteryNumbers) : LotteryTicketCheckResult + + submitTicket(ticket : LotteryTicket) : Optional + } + -class RandomNumberGenerator { + - randomIterator : OfInt + + RandomNumberGenerator(min : int, max : int) + + nextInt() : int } class PlayerDetails { - bankAccountNumber : String - emailAddress : String - phoneNumber : String - - PlayerDetails(email : String, bankAccount : String, phone : String) - + create(email : String, bankAccount : String, phone : String) : PlayerDetails {static} + + PlayerDetails(email : String, bankAccount : String, phone : String) + equals(obj : Object) : boolean + getBankAccount() : String + getEmail() : String + getPhoneNumber() : String + hashCode() : int + + toString() : String } class LotteryTicketCheckResult { - checkResult : CheckResult @@ -63,20 +94,30 @@ package com.iluwatar.hexagonal.domain { + getResult() : CheckResult + hashCode() : int } + class LotteryConstants { + + PLAYER_MAX_SALDO : int {static} + + PRIZE_AMOUNT : int {static} + + SERVICE_BANK_ACCOUNT : String {static} + + SERVICE_BANK_ACCOUNT_SALDO : int {static} + + TICKET_PRIZE : int {static} + - LotteryConstants() + } class LotteryTicket { + - id : LotteryTicketId - lotteryNumbers : LotteryNumbers - playerDetails : PlayerDetails - - LotteryTicket(details : PlayerDetails, numbers : LotteryNumbers) - + create(details : PlayerDetails, numbers : LotteryNumbers) : LotteryTicket {static} + + LotteryTicket(id : LotteryTicketId, details : PlayerDetails, numbers : LotteryNumbers) + equals(obj : Object) : boolean + + getId() : LotteryTicketId + getNumbers() : LotteryNumbers + getPlayerDetails() : PlayerDetails + hashCode() : int + + setId(id : LotteryTicketId) + + toString() : String } - -class RandomNumberGenerator { - - randomIterator : OfInt - + RandomNumberGenerator(min : int, max : int) - + nextInt() : int + class LotteryUtils { + - LotteryUtils() + + checkTicketForPrize(repository : LotteryTicketRepository, id : LotteryTicketId, winningNumbers : LotteryNumbers) : LotteryTicketCheckResult {static} } enum CheckResult { + NO_PRIZE {static} @@ -87,23 +128,64 @@ package com.iluwatar.hexagonal.domain { } } package com.iluwatar.hexagonal.banking { - class WireTransfersImpl { - - accounts : Map {static} - + WireTransfersImpl() - + getFunds(bankAccount : String) : int - + setFunds(bankAccount : String, amount : int) - + transferFunds(amount : int, sourceBackAccount : String, destinationBankAccount : String) : boolean - } interface WireTransfers { + getFunds(String) : int {abstract} + setFunds(String, int) {abstract} + transferFunds(int, String, String) : boolean {abstract} } + class MongoBank { + - DEFAULT_ACCOUNTS_COLLECTION : String {static} + - DEFAULT_DB : String {static} + - accountsCollection : MongoCollection + - database : MongoDatabase + - mongoClient : MongoClient + + MongoBank() + + MongoBank(dbName : String, accountsCollectionName : String) + + connect() + + connect(dbName : String, accountsCollectionName : String) + + getAccountsCollection() : MongoCollection + + getFunds(bankAccount : String) : int + + getMongoClient() : MongoClient + + getMongoDatabase() : MongoDatabase + + setFunds(bankAccount : String, amount : int) + + transferFunds(amount : int, sourceBackAccount : String, destinationBankAccount : String) : boolean + } + class InMemoryBank { + - accounts : Map {static} + + InMemoryBank() + + getFunds(bankAccount : String) : int + + setFunds(bankAccount : String, amount : int) + + transferFunds(amount : int, sourceBackAccount : String, destinationBankAccount : String) : boolean + } } package com.iluwatar.hexagonal.database { - class LotteryTicketInMemoryRepository { + class MongoTicketRepository { + - DEFAULT_COUNTERS_COLLECTION : String {static} + - DEFAULT_DB : String {static} + - DEFAULT_TICKETS_COLLECTION : String {static} + - countersCollection : MongoCollection + - database : MongoDatabase + - mongoClient : MongoClient + - ticketsCollection : MongoCollection + + MongoTicketRepository() + + MongoTicketRepository(dbName : String, ticketsCollectionName : String, countersCollectionName : String) + + connect() + + connect(dbName : String, ticketsCollectionName : String, countersCollectionName : String) + + deleteAll() + - docToTicket(doc : Document) : LotteryTicket + + findAll() : Map + + findById(id : LotteryTicketId) : Optional + + getCountersCollection() : MongoCollection + + getMongoClient() : MongoClient + + getMongoDatabase() : MongoDatabase + + getNextId() : int + + getTicketsCollection() : MongoCollection + - initCounters() + + save(ticket : LotteryTicket) : Optional + } + class InMemoryTicketRepository { - tickets : Map {static} - + LotteryTicketInMemoryRepository() + + InMemoryTicketRepository() + deleteAll() + findAll() : Map + findById(id : LotteryTicketId) : Optional @@ -116,68 +198,79 @@ package com.iluwatar.hexagonal.database { + save(LotteryTicket) : Optional {abstract} } } -package com.iluwatar.hexagonal.eventlog { - interface LotteryNotifications { - + notifyNoWin(PlayerDetails) {abstract} - + notifyPrize(PlayerDetails, int) {abstract} - + notifyPrizeError(PlayerDetails, int) {abstract} - + notifyTicketSubmitError(PlayerDetails) {abstract} - + notifyTicketSubmitted(PlayerDetails) {abstract} - } - class LotteryNotificationsImpl { - + LotteryNotificationsImpl() - + notifyNoWin(details : PlayerDetails) - + notifyPrize(details : PlayerDetails, prizeAmount : int) - + notifyPrizeError(details : PlayerDetails, prizeAmount : int) - + notifyTicketSubmitError(details : PlayerDetails) - + notifyTicketSubmitted(details : PlayerDetails) - } -} package com.iluwatar.hexagonal { class App { - - allPlayerDetails : List {static} + App() - - getRandomPlayerDetails() : PlayerDetails {static} + main(args : String[]) {static} - - submitTickets(lotteryService : LotteryService, numTickets : int) {static} } } package com.iluwatar.hexagonal.administration { - interface LotteryAdministration { - + getAllSubmittedTickets() : Map {abstract} - + performLottery() : LotteryNumbers {abstract} - + resetLottery() {abstract} - } - class LotteryAdministrationImpl { - - bank : WireTransfers - - notifications : LotteryNotifications - - repository : LotteryTicketRepository - - service : LotteryService - + LotteryAdministrationImpl() - + getAllSubmittedTickets() : Map - + performLottery() : LotteryNumbers - + resetLottery() + class ConsoleAdministration { + + ConsoleAdministration() + + main(args : String[]) {static} + - printMainMenu() {static} + - readString(scanner : Scanner) : String {static} } } +package com.iluwatar.hexagonal.eventlog { + interface LotteryEventLog { + + prizeError(PlayerDetails, int) {abstract} + + ticketDidNotWin(PlayerDetails) {abstract} + + ticketSubmitError(PlayerDetails) {abstract} + + ticketSubmitted(PlayerDetails) {abstract} + + ticketWon(PlayerDetails, int) {abstract} + } + class StdOutEventLog { + + StdOutEventLog() + + prizeError(details : PlayerDetails, prizeAmount : int) + + ticketDidNotWin(details : PlayerDetails) + + ticketSubmitError(details : PlayerDetails) + + ticketSubmitted(details : PlayerDetails) + + ticketWon(details : PlayerDetails, prizeAmount : int) + } + class MongoEventLog { + - DEFAULT_DB : String {static} + - DEFAULT_EVENTS_COLLECTION : String {static} + - database : MongoDatabase + - eventsCollection : MongoCollection + - mongoClient : MongoClient + - stdOutEventLog : StdOutEventLog + + MongoEventLog() + + MongoEventLog(dbName : String, eventsCollectionName : String) + + connect() + + connect(dbName : String, eventsCollectionName : String) + + getEventsCollection() : MongoCollection + + getMongoClient() : MongoClient + + getMongoDatabase() : MongoDatabase + + prizeError(details : PlayerDetails, prizeAmount : int) + + ticketDidNotWin(details : PlayerDetails) + + ticketSubmitError(details : PlayerDetails) + + ticketSubmitted(details : PlayerDetails) + + ticketWon(details : PlayerDetails, prizeAmount : int) + } +} +LotteryAdministration --+ LotteryTicketCheckResult LotteryTicket --> "-playerDetails" PlayerDetails -LotteryAdministrationImpl --> "-bank" WireTransfers -App --> "-allPlayerDetails" PlayerDetails +MongoEventLog --> "-stdOutEventLog" StdOutEventLog +LotteryService --> "-wireTransfers" WireTransfers +LotteryAdministration --> "-notifications" LotteryEventLog RandomNumberGenerator ..+ PrimitiveIterator -LotteryAdministrationImpl --> "-repository" LotteryTicketRepository -LotteryAdministrationImpl --+ LotteryTicketCheckResult -LotteryServiceImpl --> "-notifications" LotteryNotifications +LotteryAdministration --> "-wireTransfers" WireTransfers +LotteryTicket --> "-id" LotteryTicketId +LotteryService --> "-notifications" LotteryEventLog +LotteryAdministration --> "-repository" LotteryTicketRepository LotteryTicket --> "-lotteryNumbers" LotteryNumbers -LotteryAdministrationImpl --> "-notifications" LotteryNotifications -LotteryServiceImpl --> "-repository" LotteryTicketRepository -LotteryServiceImpl --+ LotteryTicketCheckResult -LotteryServiceImpl --> "-bank" WireTransfers +SampleData --> "-PLAYERS" PlayerDetails +ConsoleLottery --+ LotteryTicketCheckResult RandomNumberGenerator ..+ LotteryNumbers -LotteryAdministrationImpl --> "-service" LotteryService +LotteryService --> "-repository" LotteryTicketRepository +LotteryUtils --+ LotteryTicketCheckResult LotteryTicketCheckResult --> "-checkResult" CheckResult CheckResult ..+ LotteryTicketCheckResult -LotteryTicketInMemoryRepository ..|> LotteryTicketRepository -WireTransfersImpl ..|> WireTransfers -LotteryServiceImpl ..|> LotteryService -LotteryNotificationsImpl ..|> LotteryNotifications -LotteryAdministrationImpl ..|> LotteryAdministration +MongoTicketRepository ..|> LotteryTicketRepository +MongoBank ..|> WireTransfers +InMemoryBank ..|> WireTransfers +StdOutEventLog ..|> LotteryEventLog +InMemoryTicketRepository ..|> LotteryTicketRepository +MongoEventLog ..|> LotteryEventLog @enduml \ No newline at end of file diff --git a/intercepting-filter/etc/intercepting-filter.urm.puml b/intercepting-filter/etc/intercepting-filter.urm.puml index f5bfb54e4..e3616c3ab 100644 --- a/intercepting-filter/etc/intercepting-filter.urm.puml +++ b/intercepting-filter/etc/intercepting-filter.urm.puml @@ -1,10 +1,16 @@ @startuml package com.iluwatar.intercepting.filter { - interface Filter { - + execute(Order) : String {abstract} - + getLast() : Filter {abstract} - + getNext() : Filter {abstract} - + setNext(Filter) {abstract} + class DepositFilter { + + DepositFilter() + + execute(order : Order) : String + } + class AddressFilter { + + AddressFilter() + + execute(order : Order) : String + } + class App { + + App() + + main(args : String[]) {static} } abstract class AbstractFilter { - next : Filter @@ -15,14 +21,6 @@ package com.iluwatar.intercepting.filter { + getNext() : Filter + setNext(filter : Filter) } - class ContactFilter { - + ContactFilter() - + execute(order : Order) : String - } - class OrderFilter { - + OrderFilter() - + execute(order : Order) : String - } class Order { - address : String - contactNumber : String @@ -42,47 +40,49 @@ package com.iluwatar.intercepting.filter { + setName(name : String) + setOrder(order : String) } - class AddressFilter { - + AddressFilter() - + execute(order : Order) : String - } - ~class DListener { - ~ DListener(this$0 : Target) - + actionPerformed(e : ActionEvent) - } class FilterManager { - filterChain : FilterChain + FilterManager() + addFilter(filter : Filter) + filterRequest(order : Order) : String } + class NameFilter { + + NameFilter() + + execute(order : Order) : String + } + class ContactFilter { + + ContactFilter() + + execute(order : Order) : String + } + interface Filter { + + execute(Order) : String {abstract} + + getLast() : Filter {abstract} + + getNext() : Filter {abstract} + + setNext(Filter) {abstract} + } + ~class DListener { + ~ DListener() + + actionPerformed(e : ActionEvent) + } + class OrderFilter { + + OrderFilter() + + execute(order : Order) : String + } class FilterChain { - chain : Filter + FilterChain() + addFilter(filter : Filter) + execute(order : Order) : String } - class DepositFilter { - + DepositFilter() - + execute(order : Order) : String - } - class App { - + App() - + main(args : String[]) {static} - } - class NameFilter { - + NameFilter() - + execute(order : Order) : String - } } AbstractFilter --> "-next" Filter DListener --+ Target FilterChain --> "-chain" Filter FilterManager --> "-filterChain" FilterChain +DepositFilter --|> AbstractFilter +AddressFilter --|> AbstractFilter AbstractFilter ..|> Filter +NameFilter --|> AbstractFilter ContactFilter --|> AbstractFilter OrderFilter --|> AbstractFilter -AddressFilter --|> AbstractFilter -DepositFilter --|> AbstractFilter -NameFilter --|> AbstractFilter @enduml \ No newline at end of file diff --git a/interpreter/etc/interpreter.urm.puml b/interpreter/etc/interpreter.urm.puml index bdbd369d6..dc0d83bf2 100644 --- a/interpreter/etc/interpreter.urm.puml +++ b/interpreter/etc/interpreter.urm.puml @@ -1,23 +1,5 @@ @startuml package com.iluwatar.interpreter { - abstract class Expression { - + Expression() - + interpret() : int {abstract} - + toString() : String {abstract} - } - class PlusExpression { - - leftExpression : Expression - - rightExpression : Expression - + PlusExpression(leftExpression : Expression, rightExpression : Expression) - + interpret() : int - + toString() : String - } - class App { - + App() - + getOperatorInstance(s : String, left : Expression, right : Expression) : Expression {static} - + isOperator(s : String) : boolean {static} - + main(args : String[]) {static} - } class NumberExpression { - number : int + NumberExpression(number : int) @@ -25,13 +7,6 @@ package com.iluwatar.interpreter { + interpret() : int + toString() : String } - class MultiplyExpression { - - leftExpression : Expression - - rightExpression : Expression - + MultiplyExpression(leftExpression : Expression, rightExpression : Expression) - + interpret() : int - + toString() : String - } class MinusExpression { - leftExpression : Expression - rightExpression : Expression @@ -39,12 +14,37 @@ package com.iluwatar.interpreter { + interpret() : int + toString() : String } + class App { + + App() + + getOperatorInstance(s : String, left : Expression, right : Expression) : Expression {static} + + isOperator(s : String) : boolean {static} + + main(args : String[]) {static} + } + abstract class Expression { + + Expression() + + interpret() : int {abstract} + + toString() : String {abstract} + } + class MultiplyExpression { + - leftExpression : Expression + - rightExpression : Expression + + MultiplyExpression(leftExpression : Expression, rightExpression : Expression) + + interpret() : int + + toString() : String + } + class PlusExpression { + - leftExpression : Expression + - rightExpression : Expression + + PlusExpression(leftExpression : Expression, rightExpression : Expression) + + interpret() : int + + toString() : String + } } MultiplyExpression --> "-leftExpression" Expression MinusExpression --> "-leftExpression" Expression PlusExpression --> "-leftExpression" Expression -PlusExpression --|> Expression NumberExpression --|> Expression -MultiplyExpression --|> Expression MinusExpression --|> Expression +MultiplyExpression --|> Expression +PlusExpression --|> Expression @enduml \ No newline at end of file diff --git a/iterator/etc/iterator.urm.puml b/iterator/etc/iterator.urm.puml index cbafd6595..032cd4c16 100644 --- a/iterator/etc/iterator.urm.puml +++ b/iterator/etc/iterator.urm.puml @@ -1,13 +1,17 @@ @startuml package com.iluwatar.iterator { - interface ItemIterator { - + hasNext() : boolean {abstract} - + next() : Item {abstract} - } class App { + App() + main(args : String[]) {static} } + class Item { + - name : String + - type : ItemType + + Item(type : ItemType, name : String) + + getType() : ItemType + + setType(type : ItemType) + + toString() : String + } class TreasureChestItemIterator { - chest : TreasureChest - idx : int @@ -23,13 +27,9 @@ package com.iluwatar.iterator { + getItems() : List ~ iterator(itemType : ItemType) : ItemIterator } - class Item { - - name : String - - type : ItemType - + Item(type : ItemType, name : String) - + getType() : ItemType - + setType(type : ItemType) - + toString() : String + interface ItemIterator { + + hasNext() : boolean {abstract} + + next() : Item {abstract} } enum ItemType { + ANY {static} diff --git a/layers/etc/layers.urm.puml b/layers/etc/layers.urm.puml index d67216ff8..2ec6e142e 100644 --- a/layers/etc/layers.urm.puml +++ b/layers/etc/layers.urm.puml @@ -3,62 +3,6 @@ package com.iluwatar.layers { interface View { + render() {abstract} } - class CakeBakingServiceImpl { - - context : AbstractApplicationContext - + CakeBakingServiceImpl() - + bakeNewCake(cakeInfo : CakeInfo) - + getAllCakes() : List - - getAvailableLayerEntities() : List - + getAvailableLayers() : List - - getAvailableToppingEntities() : List - + getAvailableToppings() : List - + saveNewLayer(layerInfo : CakeLayerInfo) - + saveNewTopping(toppingInfo : CakeToppingInfo) - } - interface CakeDao { - } - class CakeTopping { - - cake : Cake - - calories : int - - id : Long - - name : String - + CakeTopping() - + CakeTopping(name : String, calories : int) - + getCake() : Cake - + getCalories() : int - + getId() : Long - + getName() : String - + setCake(cake : Cake) - + setCalories(calories : int) - + setId(id : Long) - + setName(name : String) - + toString() : String - } - class CakeLayerInfo { - + calories : int - + id : Optional - + name : String - + CakeLayerInfo(id : Long, name : String, calories : int) - + CakeLayerInfo(name : String, calories : int) - + toString() : String - } - interface CakeLayerDao { - } - interface CakeToppingDao { - } - interface CakeBakingService { - + bakeNewCake(CakeInfo) {abstract} - + getAllCakes() : List {abstract} - + getAvailableLayers() : List {abstract} - + getAvailableToppings() : List {abstract} - + saveNewLayer(CakeLayerInfo) {abstract} - + saveNewTopping(CakeToppingInfo) {abstract} - } - class CakeViewImpl { - - cakeBakingService : CakeBakingService - + CakeViewImpl(cakeBakingService : CakeBakingService) - + render() - } class CakeToppingInfo { + calories : int + id : Optional @@ -67,35 +11,6 @@ package com.iluwatar.layers { + CakeToppingInfo(name : String, calories : int) + toString() : String } - class CakeInfo { - + cakeLayerInfos : List - + cakeToppingInfo : CakeToppingInfo - + id : Optional - + CakeInfo(cakeToppingInfo : CakeToppingInfo, cakeLayerInfos : List) - + CakeInfo(id : Long, cakeToppingInfo : CakeToppingInfo, cakeLayerInfos : List) - + calculateTotalCalories() : int - + toString() : String - } - class App { - - cakeBakingService : CakeBakingService {static} - + App() - - initializeData(cakeBakingService : CakeBakingService) {static} - + main(args : String[]) {static} - } - class Cake { - - id : Long - - layers : Set - - topping : CakeTopping - + Cake() - + addLayer(layer : CakeLayer) - + getId() : Long - + getLayers() : Set - + getTopping() : CakeTopping - + setId(id : Long) - + setLayers(layers : Set) - + setTopping(topping : CakeTopping) - + toString() : String - } class CakeLayer { - cake : Cake - calories : int @@ -113,6 +28,91 @@ package com.iluwatar.layers { + setName(name : String) + toString() : String } + class CakeLayerInfo { + + calories : int + + id : Optional + + name : String + + CakeLayerInfo(id : Long, name : String, calories : int) + + CakeLayerInfo(name : String, calories : int) + + toString() : String + } + class CakeViewImpl { + - cakeBakingService : CakeBakingService + + CakeViewImpl(cakeBakingService : CakeBakingService) + + render() + } + class CakeBakingServiceImpl { + - context : AbstractApplicationContext + + CakeBakingServiceImpl() + + bakeNewCake(cakeInfo : CakeInfo) + + getAllCakes() : List + - getAvailableLayerEntities() : List + + getAvailableLayers() : List + - getAvailableToppingEntities() : List + + getAvailableToppings() : List + + saveNewLayer(layerInfo : CakeLayerInfo) + + saveNewTopping(toppingInfo : CakeToppingInfo) + } + class CakeTopping { + - cake : Cake + - calories : int + - id : Long + - name : String + + CakeTopping() + + CakeTopping(name : String, calories : int) + + getCake() : Cake + + getCalories() : int + + getId() : Long + + getName() : String + + setCake(cake : Cake) + + setCalories(calories : int) + + setId(id : Long) + + setName(name : String) + + toString() : String + } + class Cake { + - id : Long + - layers : Set + - topping : CakeTopping + + Cake() + + addLayer(layer : CakeLayer) + + getId() : Long + + getLayers() : Set + + getTopping() : CakeTopping + + setId(id : Long) + + setLayers(layers : Set) + + setTopping(topping : CakeTopping) + + toString() : String + } + interface CakeToppingDao { + } + interface CakeBakingService { + + bakeNewCake(CakeInfo) {abstract} + + getAllCakes() : List {abstract} + + getAvailableLayers() : List {abstract} + + getAvailableToppings() : List {abstract} + + saveNewLayer(CakeLayerInfo) {abstract} + + saveNewTopping(CakeToppingInfo) {abstract} + } + class App { + - cakeBakingService : CakeBakingService {static} + + App() + - initializeData(cakeBakingService : CakeBakingService) {static} + + main(args : String[]) {static} + } + interface CakeDao { + } + interface CakeLayerDao { + } + class CakeInfo { + + cakeLayerInfos : List + + cakeToppingInfo : CakeToppingInfo + + id : Optional + + CakeInfo(cakeToppingInfo : CakeToppingInfo, cakeLayerInfos : List) + + CakeInfo(id : Long, cakeToppingInfo : CakeToppingInfo, cakeLayerInfos : List) + + calculateTotalCalories() : int + + toString() : String + } } CakeViewImpl --> "-cakeBakingService" CakeBakingService CakeInfo --> "-cakeToppingInfo" CakeToppingInfo @@ -120,6 +120,6 @@ CakeInfo --> "-cakeLayerInfos" CakeLayerInfo App --> "-cakeBakingService" CakeBakingService CakeLayer --> "-cake" Cake Cake --> "-topping" CakeTopping -CakeBakingServiceImpl ..|> CakeBakingService CakeViewImpl ..|> View +CakeBakingServiceImpl ..|> CakeBakingService @enduml \ No newline at end of file diff --git a/lazy-loading/etc/lazy-loading.urm.puml b/lazy-loading/etc/lazy-loading.urm.puml index 96c427553..80192160a 100644 --- a/lazy-loading/etc/lazy-loading.urm.puml +++ b/lazy-loading/etc/lazy-loading.urm.puml @@ -2,20 +2,24 @@ package com.iluwatar.lazy.loading { ~class HeavyFactory { - heavyInstance : Heavy - ~ HeavyFactory(this$0 : Java8Holder) + ~ HeavyFactory() + get() : Heavy } - class HolderNaive { + class App { + + App() + + main(args : String[]) {static} + } + class HolderThreadSafe { - heavy : Heavy - + HolderNaive() + + HolderThreadSafe() + getHeavy() : Heavy } class Heavy { + Heavy() } - class HolderThreadSafe { + class HolderNaive { - heavy : Heavy - + HolderThreadSafe() + + HolderNaive() + getHeavy() : Heavy } class Java8Holder { @@ -24,12 +28,8 @@ package com.iluwatar.lazy.loading { - createAndCacheHeavy() : Heavy + getHeavy() : Heavy } - class App { - + App() - + main(args : String[]) {static} - } } -HolderThreadSafe --> "-heavy" Heavy HolderNaive --> "-heavy" Heavy +HolderThreadSafe --> "-heavy" Heavy HeavyFactory --> "-heavyInstance" Heavy @enduml \ No newline at end of file diff --git a/mediator/etc/mediator.urm.puml b/mediator/etc/mediator.urm.puml index 0b3baab5a..330e024ab 100644 --- a/mediator/etc/mediator.urm.puml +++ b/mediator/etc/mediator.urm.puml @@ -1,24 +1,20 @@ @startuml package com.iluwatar.mediator { - class App { - + App() - + main(args : String[]) {static} - } - class Hobbit { - + Hobbit() - + toString() : String + interface Party { + + act(PartyMember, Action) {abstract} + + addMember(PartyMember) {abstract} } interface PartyMember { + act(Action) {abstract} + joinedParty(Party) {abstract} + partyAction(Action) {abstract} } - interface Party { - + act(PartyMember, Action) {abstract} - + addMember(PartyMember) {abstract} + class Rogue { + + Rogue() + + toString() : String } - class Wizard { - + Wizard() + class Hunter { + + Hunter() + toString() : String } class PartyImpl { @@ -27,12 +23,12 @@ package com.iluwatar.mediator { + act(actor : PartyMember, action : Action) + addMember(member : PartyMember) } - class Hunter { - + Hunter() + class Hobbit { + + Hobbit() + toString() : String } - class Rogue { - + Rogue() + class Wizard { + + Wizard() + toString() : String } abstract class PartyMemberBase { @@ -43,6 +39,10 @@ package com.iluwatar.mediator { + partyAction(action : Action) + toString() : String {abstract} } + class App { + + App() + + main(args : String[]) {static} + } enum Action { + ENEMY {static} + GOLD {static} @@ -59,10 +59,10 @@ package com.iluwatar.mediator { } PartyImpl --> "-members" PartyMember PartyMemberBase --> "-party" Party +Rogue --|> PartyMemberBase +Hunter --|> PartyMemberBase +PartyImpl ..|> Party Hobbit --|> PartyMemberBase Wizard --|> PartyMemberBase -PartyImpl ..|> Party -Hunter --|> PartyMemberBase -Rogue --|> PartyMemberBase PartyMemberBase ..|> PartyMember @enduml \ No newline at end of file diff --git a/memento/etc/memento.urm.puml b/memento/etc/memento.urm.puml index aa63b4ebe..316d4047d 100644 --- a/memento/etc/memento.urm.puml +++ b/memento/etc/memento.urm.puml @@ -1,17 +1,5 @@ @startuml package com.iluwatar.memento { - class Star { - - ageYears : int - - massTons : int - - type : StarType - + Star(startType : StarType, startAge : int, startMass : int) - ~ getMemento() : StarMemento - ~ setMemento(memento : StarMemento) - + timePasses() - + toString() : String - } - interface StarMemento { - } -class StarMementoInternal { - ageYears : int - massTons : int @@ -28,6 +16,18 @@ package com.iluwatar.memento { + App() + main(args : String[]) {static} } + interface StarMemento { + } + class Star { + - ageYears : int + - massTons : int + - type : StarType + + Star(startType : StarType, startAge : int, startMass : int) + ~ getMemento() : StarMemento + ~ setMemento(memento : StarMemento) + + timePasses() + + toString() : String + } enum StarType { + DEAD {static} + RED_GIANT {static} diff --git a/model-view-controller/etc/model-view-controller.urm.puml b/model-view-controller/etc/model-view-controller.urm.puml index f8137bdae..ad979fe0e 100644 --- a/model-view-controller/etc/model-view-controller.urm.puml +++ b/model-view-controller/etc/model-view-controller.urm.puml @@ -13,14 +13,6 @@ package com.iluwatar.model.view.controller { + setNourishment(nourishment : Nourishment) + toString() : String } - class App { - + App() - + main(args : String[]) {static} - } - class GiantView { - + GiantView() - + displayGiant(giant : GiantModel) - } class GiantController { - giant : GiantModel - view : GiantView @@ -33,6 +25,23 @@ package com.iluwatar.model.view.controller { + setNourishment(nourishment : Nourishment) + updateView() } + class GiantView { + + GiantView() + + displayGiant(giant : GiantModel) + } + class App { + + App() + + main(args : String[]) {static} + } + enum Health { + + DEAD {static} + + HEALTHY {static} + + WOUNDED {static} + - title : String + + toString() : String + + valueOf(name : String) : Health {static} + + values() : Health[] {static} + } enum Nourishment { + HUNGRY {static} + SATURATED {static} @@ -51,15 +60,6 @@ package com.iluwatar.model.view.controller { + valueOf(name : String) : Fatigue {static} + values() : Fatigue[] {static} } - enum Health { - + DEAD {static} - + HEALTHY {static} - + WOUNDED {static} - - title : String - + toString() : String - + valueOf(name : String) : Health {static} - + values() : Health[] {static} - } } GiantModel --> "-nourishment" Nourishment GiantController --> "-giant" GiantModel diff --git a/model-view-presenter/etc/model-view-presenter.urm.puml b/model-view-presenter/etc/model-view-presenter.urm.puml index 64bcfba32..0cec653e4 100644 --- a/model-view-presenter/etc/model-view-presenter.urm.puml +++ b/model-view-presenter/etc/model-view-presenter.urm.puml @@ -1,42 +1,5 @@ @startuml package com.iluwatar.model.view.presenter { - class FileLoader { - - fileName : String - - loaded : boolean - + FileLoader() - + fileExists() : boolean - + getFileName() : String - + isLoaded() : boolean - + loadData() : String - + setFileName(fileName : String) - } - class FileSelectorJFrame { - - area : JTextArea - - cancel : JButton - - contents : JLabel - - fileName : String - - info : JLabel - - input : JTextField - - ok : JButton - - panel : JPanel - - presenter : FileSelectorPresenter - - serialVersionUID : long {static} - + FileSelectorJFrame() - + actionPerformed(e : ActionEvent) - + close() - + displayData(data : String) - + getFileName() : String - + getPresenter() : FileSelectorPresenter - + isOpened() : boolean - + open() - + setFileName(name : String) - + setPresenter(presenter : FileSelectorPresenter) - + showMessage(message : String) - } - class App { - + App() - + main(args : String[]) {static} - } interface FileSelectorView { + close() {abstract} + displayData(String) {abstract} @@ -67,6 +30,16 @@ package com.iluwatar.model.view.presenter { + setPresenter(presenter : FileSelectorPresenter) + showMessage(message : String) } + class FileLoader { + - fileName : String + - loaded : boolean + + FileLoader() + + fileExists() : boolean + + getFileName() : String + + isLoaded() : boolean + + loadData() : String + + setFileName(fileName : String) + } class FileSelectorPresenter { - loader : FileLoader - view : FileSelectorView @@ -77,11 +50,38 @@ package com.iluwatar.model.view.presenter { + setLoader(loader : FileLoader) + start() } + class App { + + App() + + main(args : String[]) {static} + } + class FileSelectorJFrame { + - area : JTextArea + - cancel : JButton + - contents : JLabel + - fileName : String + - info : JLabel + - input : JTextField + - ok : JButton + - panel : JPanel + - presenter : FileSelectorPresenter + - serialVersionUID : long {static} + + FileSelectorJFrame() + + actionPerformed(e : ActionEvent) + + close() + + displayData(data : String) + + getFileName() : String + + getPresenter() : FileSelectorPresenter + + isOpened() : boolean + + open() + + setFileName(name : String) + + setPresenter(presenter : FileSelectorPresenter) + + showMessage(message : String) + } } -FileSelectorStub --> "-presenter" FileSelectorPresenter FileSelectorJFrame --> "-presenter" FileSelectorPresenter +FileSelectorStub --> "-presenter" FileSelectorPresenter FileSelectorPresenter --> "-loader" FileLoader FileSelectorPresenter --> "-view" FileSelectorView -FileSelectorJFrame ..|> FileSelectorView FileSelectorStub ..|> FileSelectorView +FileSelectorJFrame ..|> FileSelectorView @enduml \ No newline at end of file diff --git a/monostate/etc/monostate.urm.puml b/monostate/etc/monostate.urm.puml index 3c09bb4ed..6574bcad1 100644 --- a/monostate/etc/monostate.urm.puml +++ b/monostate/etc/monostate.urm.puml @@ -1,5 +1,13 @@ @startuml package com.iluwatar.monostate { + class App { + + App() + + main(args : String[]) {static} + } + class Request { + + value : String + + Request(value : String) + } class LoadBalancer { - id : int {static} - lastServedId : int {static} @@ -10,14 +18,6 @@ package com.iluwatar.monostate { + getNoOfServers() : int + serverRequest(request : Request) } - class App { - + App() - + main(args : String[]) {static} - } - class Request { - + value : String - + Request(value : String) - } class Server { + host : String + id : int diff --git a/mute-idiom/etc/mute-idiom.urm.puml b/mute-idiom/etc/mute-idiom.urm.puml index d4efc2db1..c992773f5 100644 --- a/mute-idiom/etc/mute-idiom.urm.puml +++ b/mute-idiom/etc/mute-idiom.urm.puml @@ -1,6 +1,7 @@ @startuml package com.iluwatar.mute { - interface Resource { + interface CheckedRunnable { + + run() {abstract} } class App { + App() @@ -16,8 +17,7 @@ package com.iluwatar.mute { + loggedMute(runnable : CheckedRunnable) {static} + mute(runnable : CheckedRunnable) {static} } - interface CheckedRunnable { - + run() {abstract} + interface Resource { } } @enduml \ No newline at end of file diff --git a/mutex/etc/mutex.urm.puml b/mutex/etc/mutex.urm.puml index 24ea83630..68b96d668 100644 --- a/mutex/etc/mutex.urm.puml +++ b/mutex/etc/mutex.urm.puml @@ -1,5 +1,11 @@ @startuml package com.iluwatar.mutex { + class Jar { + - beans : int + - lock : Lock + + Jar(beans : int, lock : Lock) + + takeBean() : boolean + } interface Lock { + acquire() {abstract} + release() {abstract} @@ -11,12 +17,6 @@ package com.iluwatar.mutex { + getOwner() : Object + release() } - class Jar { - - beans : int - - lock : Lock - + Jar(beans : int, lock : Lock) - + takeBean() : boolean - } class App { + App() + main(args : String[]) {static} diff --git a/naked-objects/etc/naked-objects-dom.urm.puml b/naked-objects/etc/naked-objects-dom.urm.puml index ea32b5787..6662a560a 100644 --- a/naked-objects/etc/naked-objects-dom.urm.puml +++ b/naked-objects/etc/naked-objects-dom.urm.puml @@ -23,58 +23,13 @@ package domainapp.dom.modules.simple { } class SimpleObject { - container : DomainObjectContainer - - dnFieldFlags : byte[] {static} - - dnFieldNames : String[] {static} - - dnFieldTypes : Class[] {static} - # dnFlags : byte - - dnInheritedFieldCount : int {static} - - dnPersistableSuperclass : Class {static} - # dnStateManager : StateManager - name : String + SimpleObject() - + ___dn$loadClass(className : String) : Class {static} - - __dnFieldFlagsInit() : byte[] {static} - - __dnFieldNamesInit() : String[] {static} - - __dnFieldTypesInit() : Class[] {static} - # __dnGetInheritedFieldCount() : int {static} - - __dnPersistableSuperclassInit() : Class {static} + compareTo(other : SimpleObject) : int + default0UpdateName() : String - # dnCopyField(obj : SimpleObject, index : int) - + dnCopyFields(obj : Object, indices : int[]) - + dnCopyKeyFieldsFromObjectId(fc : ObjectIdFieldConsumer, oid : Object) - # dnCopyKeyFieldsFromObjectId(oid : Object) - + dnCopyKeyFieldsToObjectId(fs : ObjectIdFieldSupplier, oid : Object) - + dnCopyKeyFieldsToObjectId(oid : Object) - + dnGetExecutionContext() : ExecutionContextReference - # dnGetManagedFieldCount() : int {static} - + dnGetObjectId() : Object - + dnGetTransactionalObjectId() : Object - + dnGetVersion() : Object - + dnGetname() : String - + dnIsDeleted() : boolean - + dnIsDetached() : boolean - + dnIsDirty() : boolean - + dnIsNew() : boolean - + dnIsPersistent() : boolean - + dnIsTransactional() : boolean - + dnMakeDirty(fieldName : String) - + dnNewInstance(sm : StateManager) : Persistable - + dnNewInstance(sm : StateManager, obj : Object) : Persistable - + dnNewObjectIdInstance() : Object - + dnNewObjectIdInstance(key : Object) : Object - # dnPreSerialize() - + dnProvideField(index : int) - + dnProvideFields(indices : int[]) - + dnReplaceField(index : int) - + dnReplaceFields(indices : int[]) - + dnReplaceFlags() - + dnReplaceStateManager(sm : StateManager) - + dnSetname(name : String) - - dnSuperClone() : Object + getName() : String + getVersionSequence() : Long - + setName(val : String) + + setName(name : String) + title() : TranslatableString + updateName(name : String) : SimpleObject + validateUpdateName(name : String) : TranslatableString diff --git a/naked-objects/etc/naked-objects-fixture.urm.puml b/naked-objects/etc/naked-objects-fixture.urm.puml index 65c44410a..21e38d710 100644 --- a/naked-objects/etc/naked-objects-fixture.urm.puml +++ b/naked-objects/etc/naked-objects-fixture.urm.puml @@ -1,16 +1,16 @@ @startuml package domainapp.dom.app.homepage { + class HomePageService { + ~ container : DomainObjectContainer + + HomePageService() + + homePage() : HomePageViewModel + } class HomePageViewModel { ~ simpleObjects : SimpleObjects + HomePageViewModel() + getObjects() : List + title() : String } - class HomePageService { - ~ container : DomainObjectContainer - + HomePageService() - + homePage() : HomePageViewModel - } } package domainapp.dom.modules.simple { class SimpleObject { diff --git a/naked-objects/etc/naked-objects-integtests.urm.puml b/naked-objects/etc/naked-objects-integtests.urm.puml index 1f2dfc4c2..65c44410a 100644 --- a/naked-objects/etc/naked-objects-integtests.urm.puml +++ b/naked-objects/etc/naked-objects-integtests.urm.puml @@ -1,26 +1,18 @@ @startuml package domainapp.dom.app.homepage { - class HomePageService { - ~ container : DomainObjectContainer - + HomePageService() - + homePage() : HomePageViewModel - } class HomePageViewModel { ~ simpleObjects : SimpleObjects + HomePageViewModel() + getObjects() : List + title() : String } + class HomePageService { + ~ container : DomainObjectContainer + + HomePageService() + + homePage() : HomePageViewModel + } } package domainapp.dom.modules.simple { - class SimpleObjects { - ~ container : DomainObjectContainer - + SimpleObjects() - + create(name : String) : SimpleObject - + findByName(name : String) : List - + listAll() : List - + title() : TranslatableString - } class SimpleObject { - container : DomainObjectContainer - dnFieldFlags : byte[] {static} @@ -79,6 +71,14 @@ package domainapp.dom.modules.simple { + updateName(name : String) : SimpleObject + validateUpdateName(name : String) : TranslatableString } + class SimpleObjects { + ~ container : DomainObjectContainer + + SimpleObjects() + + create(name : String) : SimpleObject + + findByName(name : String) : List + + listAll() : List + + title() : TranslatableString + } } package domainapp.fixture { class DomainAppFixturesProvider { diff --git a/null-object/etc/null-object.urm.puml b/null-object/etc/null-object.urm.puml index d0b2936c5..bd4f8446e 100644 --- a/null-object/etc/null-object.urm.puml +++ b/null-object/etc/null-object.urm.puml @@ -1,22 +1,5 @@ @startuml package com.iluwatar.nullobject { - class NullNode { - - instance : NullNode {static} - - NullNode() - + getInstance() : NullNode {static} - + getLeft() : Node - + getName() : String - + getRight() : Node - + getTreeSize() : int - + walk() - } - interface Node { - + getLeft() : Node {abstract} - + getName() : String {abstract} - + getRight() : Node {abstract} - + getTreeSize() : int {abstract} - + walk() {abstract} - } class App { + App() + main(args : String[]) {static} @@ -32,9 +15,26 @@ package com.iluwatar.nullobject { + getTreeSize() : int + walk() } + interface Node { + + getLeft() : Node {abstract} + + getName() : String {abstract} + + getRight() : Node {abstract} + + getTreeSize() : int {abstract} + + walk() {abstract} + } + class NullNode { + - instance : NullNode {static} + - NullNode() + + getInstance() : NullNode {static} + + getLeft() : Node + + getName() : String + + getRight() : Node + + getTreeSize() : int + + walk() + } } NullNode --> "-instance" NullNode NodeImpl --> "-left" Node -NullNode ..|> Node NodeImpl ..|> Node +NullNode ..|> Node @enduml \ No newline at end of file diff --git a/object-pool/etc/object-pool.urm.puml b/object-pool/etc/object-pool.urm.puml index 9df1081d3..caf0b6d7e 100644 --- a/object-pool/etc/object-pool.urm.puml +++ b/object-pool/etc/object-pool.urm.puml @@ -1,5 +1,9 @@ @startuml package com.iluwatar.object.pool { + class OliphauntPool { + + OliphauntPool() + # create() : Oliphaunt + } class Oliphaunt { - counter : int {static} - id : int @@ -7,14 +11,6 @@ package com.iluwatar.object.pool { + getId() : int + toString() : String } - class OliphauntPool { - + OliphauntPool() - # create() : Oliphaunt - } - class App { - + App() - + main(args : String[]) {static} - } abstract class ObjectPool { - available : HashSet - inUse : HashSet @@ -24,6 +20,10 @@ package com.iluwatar.object.pool { # create() : T {abstract} + toString() : String } + class App { + + App() + + main(args : String[]) {static} + } } OliphauntPool --|> ObjectPool @enduml \ No newline at end of file diff --git a/observer/etc/observer.urm.puml b/observer/etc/observer.urm.puml index 33485d731..e9a8f7b9b 100644 --- a/observer/etc/observer.urm.puml +++ b/observer/etc/observer.urm.puml @@ -4,9 +4,12 @@ package com.iluwatar.observer { + Orcs() + update(currentWeather : WeatherType) } - class Hobbits { - + Hobbits() - + update(currentWeather : WeatherType) + interface WeatherObserver { + + update(WeatherType) {abstract} + } + class App { + + App() + + main(args : String[]) {static} } class Weather { - currentWeather : WeatherType @@ -17,12 +20,9 @@ package com.iluwatar.observer { + removeObserver(obs : WeatherObserver) + timePasses() } - class App { - + App() - + main(args : String[]) {static} - } - interface WeatherObserver { - + update(WeatherType) {abstract} + class Hobbits { + + Hobbits() + + update(currentWeather : WeatherType) } enum WeatherType { + COLD {static} @@ -41,6 +41,11 @@ package com.iluwatar.observer.generic { } interface Race { } + class GWeather { + - currentWeather : WeatherType + + GWeather() + + timePasses() + } abstract class Observable, A> { # observers : List> + Observable, A>() @@ -48,26 +53,21 @@ package com.iluwatar.observer.generic { + notifyObservers(argument : A) + removeObserver(observer : O extends Observer) } - class GWeather { - - currentWeather : WeatherType - + GWeather() - + timePasses() - } - interface Observer, O extends Observer, A> { - + update(S extends Observable, A) {abstract} - } class GHobbits { + GHobbits() + update(weather : GWeather, weatherType : WeatherType) } + interface Observer, O extends Observer, A> { + + update(S extends Observable, A) {abstract} + } } Weather --> "-currentWeather" WeatherType GWeather --> "-currentWeather" WeatherType Weather --> "-observers" WeatherObserver GOrcs ..|> Race Orcs ..|> WeatherObserver -Hobbits ..|> WeatherObserver Race --|> Observer GWeather --|> Observable GHobbits ..|> Race +Hobbits ..|> WeatherObserver @enduml \ No newline at end of file diff --git a/poison-pill/etc/poison-pill.urm.puml b/poison-pill/etc/poison-pill.urm.puml index 58f9eb937..f05c40692 100644 --- a/poison-pill/etc/poison-pill.urm.puml +++ b/poison-pill/etc/poison-pill.urm.puml @@ -1,5 +1,8 @@ @startuml package com.iluwatar.poison.pill { + interface MqPublishPoint { + + put(Message) {abstract} + } interface Message { + POISON_PILL : Message {static} + addHeader(Headers, String) {abstract} @@ -12,21 +15,7 @@ package com.iluwatar.poison.pill { + App() + main(args : String[]) {static} } - class SimpleMessage { - - body : String - - headers : Map - + SimpleMessage() - + addHeader(header : Headers, value : String) - + getBody() : String - + getHeader(header : Headers) : String - + getHeaders() : Map - + setBody(body : String) - } - class SimpleMessageQueue { - - queue : BlockingQueue - + SimpleMessageQueue(bound : int) - + put(msg : Message) - + take() : Message + interface MessageQueue { } class Producer { - isStopped : boolean @@ -36,19 +25,30 @@ package com.iluwatar.poison.pill { + send(body : String) + stop() } - interface MqSubscribePoint { - + take() : Message {abstract} - } class Consumer { - name : String - queue : MqSubscribePoint + Consumer(name : String, queue : MqSubscribePoint) + consume() } - interface MessageQueue { + class SimpleMessageQueue { + - queue : BlockingQueue + + SimpleMessageQueue(bound : int) + + put(msg : Message) + + take() : Message } - interface MqPublishPoint { - + put(Message) {abstract} + interface MqSubscribePoint { + + take() : Message {abstract} + } + class SimpleMessage { + - body : String + - headers : Map + + SimpleMessage() + + addHeader(header : Headers, value : String) + + getBody() : String + + getHeader(header : Headers) : String + + getHeaders() : Map + + setBody(body : String) } enum Headers { + DATE {static} @@ -65,8 +65,8 @@ SimpleMessage --+ Message Producer --+ Message Message --> "-POISON_PILL" Message Consumer --+ Message -SimpleMessage ..|> Message -SimpleMessageQueue ..|> MessageQueue MessageQueue --|> MqPublishPoint MessageQueue --|> MqSubscribePoint +SimpleMessageQueue ..|> MessageQueue +SimpleMessage ..|> Message @enduml \ No newline at end of file diff --git a/pom.xml b/pom.xml index b1ae7d811..fcf1671c8 100644 --- a/pom.xml +++ b/pom.xml @@ -282,6 +282,25 @@ + + + + com.github.markusmo3.urm + + + urm-maven-plugin + + + [1.4.1,) + + + map + + + + + + diff --git a/private-class-data/etc/private-class-data.urm.puml b/private-class-data/etc/private-class-data.urm.puml index 0edc2c1a8..ad35c0bdd 100644 --- a/private-class-data/etc/private-class-data.urm.puml +++ b/private-class-data/etc/private-class-data.urm.puml @@ -1,18 +1,5 @@ @startuml package com.iluwatar.privateclassdata { - class Stew { - - numCarrots : int - - numMeat : int - - numPeppers : int - - numPotatoes : int - + Stew(numPotatoes : int, numCarrots : int, numMeat : int, numPeppers : int) - + mix() - + taste() - } - class App { - + App() - + main(args : String[]) {static} - } class StewData { - numCarrots : int - numMeat : int @@ -24,6 +11,19 @@ package com.iluwatar.privateclassdata { + getNumPeppers() : int + getNumPotatoes() : int } + class App { + + App() + + main(args : String[]) {static} + } + class Stew { + - numCarrots : int + - numMeat : int + - numPeppers : int + - numPotatoes : int + + Stew(numPotatoes : int, numCarrots : int, numMeat : int, numPeppers : int) + + mix() + + taste() + } class ImmutableStew { - data : StewData + ImmutableStew(numPotatoes : int, numCarrots : int, numMeat : int, numPeppers : int) diff --git a/producer-consumer/etc/producer-consumer.urm.puml b/producer-consumer/etc/producer-consumer.urm.puml index 9a6748552..8b793d75b 100644 --- a/producer-consumer/etc/producer-consumer.urm.puml +++ b/producer-consumer/etc/producer-consumer.urm.puml @@ -1,5 +1,22 @@ @startuml package com.iluwatar.producer.consumer { + class Consumer { + - name : String + - queue : ItemQueue + + Consumer(name : String, queue : ItemQueue) + + consume() + } + class Item { + - id : int + - producer : String + + Item(producer : String, id : int) + + getId() : int + + getProducer() : String + } + class App { + + App() + + main(args : String[]) {static} + } class Producer { - itemId : int - name : String @@ -13,23 +30,6 @@ package com.iluwatar.producer.consumer { + put(item : Item) + take() : Item } - class Item { - - id : int - - producer : String - + Item(producer : String, id : int) - + getId() : int - + getProducer() : String - } - class App { - + App() - + main(args : String[]) {static} - } - class Consumer { - - name : String - - queue : ItemQueue - + Consumer(name : String, queue : ItemQueue) - + consume() - } } Consumer --> "-queue" ItemQueue Producer --> "-queue" ItemQueue diff --git a/promise/etc/promise.urm.puml b/promise/etc/promise.urm.puml index d97871411..cd6e73252 100644 --- a/promise/etc/promise.urm.puml +++ b/promise/etc/promise.urm.puml @@ -24,12 +24,18 @@ package com.iluwatar.promise { - ConsumeAction(src : Promise, dest : Promise, action : Consumer) + run() } - -class TransformAction { - - dest : Promise - - func : Function - - src : Promise - - TransformAction(src : Promise, dest : Promise, func : Function) - + run() + class Promise { + - exceptionHandler : Consumer + - fulfillmentAction : Runnable + + Promise() + + fulfill(value : T) + + fulfillExceptionally(exception : Exception) + + fulfillInAsync(task : Callable, executor : Executor) : Promise + - handleException(exception : Exception) + + onError(exceptionHandler : Consumer) : Promise + - postFulfillment() + + thenAccept(action : Consumer) : Promise + + thenApply(func : Function) : Promise } class App { - DEFAULT_URL : String {static} @@ -47,18 +53,12 @@ package com.iluwatar.promise { - stop() - taskCompleted() } - class Promise { - - exceptionHandler : Consumer - - fulfillmentAction : Runnable - + Promise() - + fulfill(value : T) - + fulfillExceptionally(exception : Exception) - + fulfillInAsync(task : Callable, executor : Executor) : Promise - - handleException(exception : Exception) - + onError(exceptionHandler : Consumer) : Promise - - postFulfillment() - + thenAccept(action : Consumer) : Promise - + thenApply(func : Function) : Promise + -class TransformAction { + - dest : Promise + - func : Function + - src : Promise + - TransformAction(src : Promise, dest : Promise, func : Function) + + run() } class Utility { + Utility() diff --git a/property/etc/property.urm.puml b/property/etc/property.urm.puml index 7c90edccc..6ff0e5c52 100644 --- a/property/etc/property.urm.puml +++ b/property/etc/property.urm.puml @@ -1,5 +1,15 @@ @startuml package com.iluwatar.property { + class App { + + App() + + main(args : String[]) {static} + } + interface Prototype { + + get(Stats) : Integer {abstract} + + has(Stats) : boolean {abstract} + + remove(Stats) {abstract} + + set(Stats, Integer) {abstract} + } class Character { - name : String - properties : Map @@ -16,15 +26,12 @@ package com.iluwatar.property { + toString() : String + type() : Type } - interface Prototype { - + get(Stats) : Integer {abstract} - + has(Stats) : boolean {abstract} - + remove(Stats) {abstract} - + set(Stats, Integer) {abstract} - } - class App { - + App() - + main(args : String[]) {static} + enum Type { + + MAGE {static} + + ROGUE {static} + + WARRIOR {static} + + valueOf(name : String) : Type {static} + + values() : Type[] {static} } enum Stats { + AGILITY {static} @@ -38,13 +45,6 @@ package com.iluwatar.property { + valueOf(name : String) : Stats {static} + values() : Stats[] {static} } - enum Type { - + MAGE {static} - + ROGUE {static} - + WARRIOR {static} - + valueOf(name : String) : Type {static} - + values() : Type[] {static} - } } App --+ Character Character --> "-prototype" Prototype diff --git a/prototype/etc/prototype.urm.puml b/prototype/etc/prototype.urm.puml index 7bfc00e15..7ab26dd1b 100644 --- a/prototype/etc/prototype.urm.puml +++ b/prototype/etc/prototype.urm.puml @@ -1,59 +1,42 @@ @startuml package com.iluwatar.prototype { - interface HeroFactory { - + createBeast() : Beast {abstract} - + createMage() : Mage {abstract} - + createWarlord() : Warlord {abstract} + class OrcWarlord { + + OrcWarlord() + + clone() : Warlord + + toString() : String } class OrcBeast { + OrcBeast() + clone() : Beast + toString() : String } - abstract class Mage { - + Mage() - + clone() : Mage {abstract} - } - class HeroFactoryImpl { - - beast : Beast - - mage : Mage - - warlord : Warlord - + HeroFactoryImpl(mage : Mage, warlord : Warlord, beast : Beast) - + createBeast() : Beast - + createMage() : Mage - + createWarlord() : Warlord + abstract class Beast { + + Beast() + + clone() : Beast {abstract} } class ElfMage { + ElfMage() + clone() : Mage + toString() : String } + abstract class Mage { + + Mage() + + clone() : Mage {abstract} + } abstract class Prototype { + Prototype() + clone() : Object {abstract} } - class App { - + App() - + main(args : String[]) {static} - } - abstract class Warlord { - + Warlord() - + clone() : Warlord {abstract} - } - class OrcWarlord { - + OrcWarlord() - + clone() : Warlord - + toString() : String + interface HeroFactory { + + createBeast() : Beast {abstract} + + createMage() : Mage {abstract} + + createWarlord() : Warlord {abstract} } class ElfWarlord { + ElfWarlord() + clone() : Warlord + toString() : String } - abstract class Beast { - + Beast() - + clone() : Beast {abstract} - } class OrcMage { + OrcMage() + clone() : Mage @@ -64,18 +47,35 @@ package com.iluwatar.prototype { + clone() : Beast + toString() : String } + abstract class Warlord { + + Warlord() + + clone() : Warlord {abstract} + } + class HeroFactoryImpl { + - beast : Beast + - mage : Mage + - warlord : Warlord + + HeroFactoryImpl(mage : Mage, warlord : Warlord, beast : Beast) + + createBeast() : Beast + + createMage() : Mage + + createWarlord() : Warlord + } + class App { + + App() + + main(args : String[]) {static} + } } HeroFactoryImpl --> "-beast" Beast HeroFactoryImpl --> "-warlord" Warlord HeroFactoryImpl --> "-mage" Mage -OrcBeast --|> Beast -Mage --|> Prototype -HeroFactoryImpl ..|> HeroFactory -ElfMage --|> Mage -Warlord --|> Prototype OrcWarlord --|> Warlord -ElfWarlord --|> Warlord +OrcBeast --|> Beast Beast --|> Prototype +ElfMage --|> Mage +Mage --|> Prototype +ElfWarlord --|> Warlord OrcMage --|> Mage ElfBeast --|> Beast +Warlord --|> Prototype +HeroFactoryImpl ..|> HeroFactory @enduml \ No newline at end of file diff --git a/proxy/etc/proxy.urm.puml b/proxy/etc/proxy.urm.puml index 4203174de..1dc58087c 100644 --- a/proxy/etc/proxy.urm.puml +++ b/proxy/etc/proxy.urm.puml @@ -1,5 +1,11 @@ @startuml package com.iluwatar.proxy { + class WizardTowerProxy { + - NUM_WIZARDS_ALLOWED : int {static} + - numWizards : int + + WizardTowerProxy() + + enter(wizard : Wizard) + } class WizardTower { + WizardTower() + enter(wizard : Wizard) @@ -8,12 +14,6 @@ package com.iluwatar.proxy { + App() + main(args : String[]) {static} } - class WizardTowerProxy { - - NUM_WIZARDS_ALLOWED : int {static} - - numWizards : int - + WizardTowerProxy() - + enter(wizard : Wizard) - } class Wizard { - name : String + Wizard(name : String) diff --git a/reactor/etc/reactor.urm.puml b/reactor/etc/reactor.urm.puml index 302f2663c..ecf2f40f7 100644 --- a/reactor/etc/reactor.urm.puml +++ b/reactor/etc/reactor.urm.puml @@ -1,5 +1,24 @@ @startuml package com.iluwatar.reactor.app { + class App { + - channels : List + - dispatcher : Dispatcher + - reactor : NioReactor + + App(dispatcher : Dispatcher) + + main(args : String[]) {static} + + start() + + stop() + - tcpChannel(port : int, handler : ChannelHandler) : AbstractNioChannel + - udpChannel(port : int, handler : ChannelHandler) : AbstractNioChannel + } + class LoggingHandler { + - ACK : byte[] {static} + + LoggingHandler() + - doLogging(data : ByteBuffer) {static} + + handleChannelRead(channel : AbstractNioChannel, readObject : Object, key : SelectionKey) + - sendReply(channel : AbstractNioChannel, incomingPacket : DatagramPacket, key : SelectionKey) {static} + - sendReply(channel : AbstractNioChannel, key : SelectionKey) {static} + } ~class TcpLoggingClient { - clientName : String - serverPort : int @@ -13,14 +32,6 @@ package com.iluwatar.reactor.app { + UdpLoggingClient(clientName : String, port : int) + run() } - class LoggingHandler { - - ACK : byte[] {static} - + LoggingHandler() - - doLogging(data : ByteBuffer) {static} - + handleChannelRead(channel : AbstractNioChannel, readObject : Object, key : SelectionKey) - - sendReply(channel : AbstractNioChannel, incomingPacket : DatagramPacket, key : SelectionKey) {static} - - sendReply(channel : AbstractNioChannel, key : SelectionKey) {static} - } class AppClient { - service : ExecutorService + AppClient() @@ -29,58 +40,8 @@ package com.iluwatar.reactor.app { + start() + stop() } - class App { - - channels : List - - dispatcher : Dispatcher - - reactor : NioReactor - + App(dispatcher : Dispatcher) - + main(args : String[]) {static} - + start() - + stop() - - tcpChannel(port : int, handler : ChannelHandler) : AbstractNioChannel - - udpChannel(port : int, handler : ChannelHandler) : AbstractNioChannel - } } package com.iluwatar.reactor.framework { - interface Dispatcher { - + onChannelReadEvent(AbstractNioChannel, Object, SelectionKey) {abstract} - + stop() {abstract} - } - class SameThreadDispatcher { - + SameThreadDispatcher() - + onChannelReadEvent(channel : AbstractNioChannel, readObject : Object, key : SelectionKey) - + stop() - } - class ThreadPoolDispatcher { - - executorService : ExecutorService - + ThreadPoolDispatcher(poolSize : int) - + onChannelReadEvent(channel : AbstractNioChannel, readObject : Object, key : SelectionKey) - + stop() - } - interface ChannelHandler { - + handleChannelRead(AbstractNioChannel, Object, SelectionKey) {abstract} - } - class NioDatagramChannel { - - port : int - + NioDatagramChannel(port : int, handler : ChannelHandler) - + bind() - # doWrite(pendingWrite : Object, key : SelectionKey) - + getInterestedOps() : int - + getJavaChannel() : DatagramChannel - + read(key : SelectionKey) : DatagramPacket - + write(data : Object, key : SelectionKey) - } - class DatagramPacket { - - data : ByteBuffer - - receiver : SocketAddress - - sender : SocketAddress - + DatagramPacket(data : ByteBuffer) - + getData() : ByteBuffer - + getReceiver() : SocketAddress - + getSender() : SocketAddress - + setReceiver(receiver : SocketAddress) - + setSender(sender : SocketAddress) - } abstract class AbstractNioChannel { - channel : SelectableChannel - channelToPendingWrites : Map> @@ -97,6 +58,32 @@ package com.iluwatar.reactor.framework { ~ setReactor(reactor : NioReactor) + write(data : Object, key : SelectionKey) } + ~class ChangeKeyOpsCommand { + - interestedOps : int + - key : SelectionKey + + ChangeKeyOpsCommand(this$0 : SelectionKey, key : int) + + run() + + toString() : String + } + interface ChannelHandler { + + handleChannelRead(AbstractNioChannel, Object, SelectionKey) {abstract} + } + class NioDatagramChannel { + - port : int + + NioDatagramChannel(port : int, handler : ChannelHandler) + + bind() + # doWrite(pendingWrite : Object, key : SelectionKey) + + getInterestedOps() : int + + getJavaChannel() : DatagramChannel + + read(key : SelectionKey) : DatagramPacket + + write(data : Object, key : SelectionKey) + } + class ThreadPoolDispatcher { + - executorService : ExecutorService + + ThreadPoolDispatcher(poolSize : int) + + onChannelReadEvent(channel : AbstractNioChannel, readObject : Object, key : SelectionKey) + + stop() + } class NioServerSocketChannel { - port : int + NioServerSocketChannel(port : int, handler : ChannelHandler) @@ -106,6 +93,26 @@ package com.iluwatar.reactor.framework { + getJavaChannel() : ServerSocketChannel + read(key : SelectionKey) : ByteBuffer } + class SameThreadDispatcher { + + SameThreadDispatcher() + + onChannelReadEvent(channel : AbstractNioChannel, readObject : Object, key : SelectionKey) + + stop() + } + interface Dispatcher { + + onChannelReadEvent(AbstractNioChannel, Object, SelectionKey) {abstract} + + stop() {abstract} + } + class DatagramPacket { + - data : ByteBuffer + - receiver : SocketAddress + - sender : SocketAddress + + DatagramPacket(data : ByteBuffer) + + getData() : ByteBuffer + + getReceiver() : SocketAddress + + getSender() : SocketAddress + + setReceiver(receiver : SocketAddress) + + setSender(sender : SocketAddress) + } class NioReactor { - dispatcher : Dispatcher - pendingCommands : Queue @@ -124,28 +131,21 @@ package com.iluwatar.reactor.framework { + start() + stop() } - ~class ChangeKeyOpsCommand { - - interestedOps : int - - key : SelectionKey - + ChangeKeyOpsCommand(this$0 : NioReactor, key : SelectionKey, interestedOps : int) - + run() - + toString() : String - } } AbstractNioChannel --> "-handler" ChannelHandler UdpLoggingClient ..+ AppClient -AbstractNioChannel --> "-reactor" NioReactor TcpLoggingClient ..+ AppClient +AbstractNioChannel --> "-reactor" NioReactor NioReactor --> "-dispatcher" Dispatcher App --> "-reactor" NioReactor App --> "-channels" AbstractNioChannel DatagramPacket ..+ NioDatagramChannel -ChangeKeyOpsCommand --+ NioReactor -App --> "-dispatcher" Dispatcher LoggingHandler --+ NioDatagramChannel -SameThreadDispatcher ..|> Dispatcher +App --> "-dispatcher" Dispatcher +ChangeKeyOpsCommand --+ NioReactor +NioDatagramChannel --|> AbstractNioChannel LoggingHandler ..|> ChannelHandler ThreadPoolDispatcher ..|> Dispatcher -NioDatagramChannel --|> AbstractNioChannel NioServerSocketChannel --|> AbstractNioChannel +SameThreadDispatcher ..|> Dispatcher @enduml \ No newline at end of file diff --git a/reader-writer-lock/etc/reader-writer-lock.urm.puml b/reader-writer-lock/etc/reader-writer-lock.urm.puml index 22b303cf5..1760cf3e4 100644 --- a/reader-writer-lock/etc/reader-writer-lock.urm.puml +++ b/reader-writer-lock/etc/reader-writer-lock.urm.puml @@ -1,21 +1,5 @@ @startuml package com.iluwatar.reader.writer.lock { - -class ReadLock { - - ReadLock(ReaderWriterLock) - + lock() - + lockInterruptibly() - + newCondition() : Condition - + tryLock() : boolean - + tryLock(time : long, unit : TimeUnit) : boolean - + unlock() - } - class Writer { - - name : String - - writeLock : Lock - + Writer(name : String, writeLock : Lock) - + run() - + write() - } class ReaderWriterLock { - currentReaderCount : int - globalMutex : Set @@ -31,7 +15,7 @@ package com.iluwatar.reader.writer.lock { + writeLock() : Lock } -class WriteLock { - - WriteLock(ReaderWriterLock) + - WriteLock() + lock() + lockInterruptibly() + newCondition() : Condition @@ -43,6 +27,22 @@ package com.iluwatar.reader.writer.lock { + App() + main(args : String[]) {static} } + -class ReadLock { + - ReadLock() + + lock() + + lockInterruptibly() + + newCondition() : Condition + + tryLock() : boolean + + tryLock(time : long, unit : TimeUnit) : boolean + + unlock() + } + class Writer { + - name : String + - writeLock : Lock + + Writer(name : String, writeLock : Lock) + + run() + + write() + } class Reader { - name : String - readLock : Lock @@ -51,8 +51,8 @@ package com.iluwatar.reader.writer.lock { + run() } } -ReadLock --+ ReaderWriterLock ReaderWriterLock --> "-readerLock" ReadLock +ReadLock --+ ReaderWriterLock ReaderWriterLock --> "-writerLock" WriteLock WriteLock --+ ReaderWriterLock @enduml \ No newline at end of file diff --git a/repository/etc/repository.urm.puml b/repository/etc/repository.urm.puml index 49a2c8fdc..ad1759033 100644 --- a/repository/etc/repository.urm.puml +++ b/repository/etc/repository.urm.puml @@ -1,9 +1,34 @@ @startuml package com.iluwatar.repository { + class PersonSpecifications { + + PersonSpecifications() + } + class NameEqualSpec { + + name : String + + NameEqualSpec(name : String) + + toPredicate(root : Root, query : CriteriaQuery, cb : CriteriaBuilder) : Predicate + } class App { + App() + main(args : String[]) {static} } + interface PersonRepository { + + findByName(String) : Person {abstract} + } + class AgeBetweenSpec { + - from : int + - to : int + + AgeBetweenSpec(from : int, to : int) + + toPredicate(root : Root, query : CriteriaQuery, cb : CriteriaBuilder) : Predicate + } + class AppConfig { + + AppConfig() + + dataSource() : DataSource + + entityManagerFactory() : LocalContainerEntityManagerFactoryBean + - jpaProperties() : Properties {static} + + main(args : String[]) {static} + + transactionManager() : JpaTransactionManager + } class Person { - age : int - id : Long @@ -23,31 +48,6 @@ package com.iluwatar.repository { + setSurname(surname : String) + toString() : String } - class AgeBetweenSpec { - - from : int - - to : int - + AgeBetweenSpec(from : int, to : int) - + toPredicate(root : Root, query : CriteriaQuery, cb : CriteriaBuilder) : Predicate - } - class AppConfig { - + AppConfig() - + dataSource() : DataSource - + entityManagerFactory() : LocalContainerEntityManagerFactoryBean - - jpaProperties() : Properties {static} - + main(args : String[]) {static} - + transactionManager() : JpaTransactionManager - } - interface PersonRepository { - + findByName(String) : Person {abstract} - } - class NameEqualSpec { - + name : String - + NameEqualSpec(name : String) - + toPredicate(root : Root, query : CriteriaQuery, cb : CriteriaBuilder) : Predicate - } - class PersonSpecifications { - + PersonSpecifications() - } } App --+ PersonSpecifications AppConfig --+ PersonSpecifications diff --git a/resource-acquisition-is-initialization/etc/resource-acquisition-is-initialization.urm.puml b/resource-acquisition-is-initialization/etc/resource-acquisition-is-initialization.urm.puml index 847b716a0..81560c7f5 100644 --- a/resource-acquisition-is-initialization/etc/resource-acquisition-is-initialization.urm.puml +++ b/resource-acquisition-is-initialization/etc/resource-acquisition-is-initialization.urm.puml @@ -4,13 +4,13 @@ package com.iluwatar.resource.acquisition.is.initialization { + App() + main(args : String[]) {static} } - class TreasureChest { - + TreasureChest() - + close() - } class SlidingDoor { + SlidingDoor() + close() } + class TreasureChest { + + TreasureChest() + + close() + } } @enduml \ No newline at end of file diff --git a/semaphore/etc/semaphore.urm.puml b/semaphore/etc/semaphore.urm.puml index f85fff921..a94ff5a7c 100644 --- a/semaphore/etc/semaphore.urm.puml +++ b/semaphore/etc/semaphore.urm.puml @@ -1,32 +1,11 @@ @startuml package com.iluwatar.semaphore { - class FruitShop { - - available : boolean[] - - bowls : FruitBowl[] - - semaphore : Semaphore - + FruitShop() - + countFruit() : int - + returnBowl(bowl : FruitBowl) - + takeBowl() : FruitBowl - } - class FruitBowl { - - fruit : ArrayList - + FruitBowl() - + countFruit() : int - + put(f : Fruit) - + take() : Fruit - + toString() : String - } class Fruit { - type : FruitType + Fruit(type : FruitType) + getType() : FruitType + toString() : String } - interface Lock { - + acquire() {abstract} - + release() {abstract} - } class App { + App() + main(args : String[]) {static} @@ -40,6 +19,27 @@ package com.iluwatar.semaphore { + getNumLicenses() : int + release() } + class FruitShop { + - available : boolean[] + - bowls : FruitBowl[] + - semaphore : Semaphore + + FruitShop() + + countFruit() : int + + returnBowl(bowl : FruitBowl) + + takeBowl() : FruitBowl + } + interface Lock { + + acquire() {abstract} + + release() {abstract} + } + class FruitBowl { + - fruit : ArrayList + + FruitBowl() + + countFruit() : int + + put(f : Fruit) + + take() : Fruit + + toString() : String + } enum FruitType { + APPLE {static} + LEMON {static} diff --git a/servant/etc/servant.urm.puml b/servant/etc/servant.urm.puml index 48d48bd84..b7391f5dd 100644 --- a/servant/etc/servant.urm.puml +++ b/servant/etc/servant.urm.puml @@ -1,24 +1,5 @@ @startuml package com.iluwatar.servant { - class King { - - complimentReceived : boolean - - isDrunk : boolean - - isHappy : boolean - - isHungry : boolean - + King() - + changeMood() - + getDrink() - + getFed() - + getMood() : boolean - + receiveCompliments() - } - ~interface Royalty { - + changeMood() {abstract} - + getDrink() {abstract} - + getFed() {abstract} - + getMood() : boolean {abstract} - + receiveCompliments() {abstract} - } class Servant { + name : String + Servant(name : String) @@ -48,8 +29,27 @@ package com.iluwatar.servant { + main(args : String[]) {static} + scenario(servant : Servant, compliment : int) {static} } + class King { + - complimentReceived : boolean + - isDrunk : boolean + - isHappy : boolean + - isHungry : boolean + + King() + + changeMood() + + getDrink() + + getFed() + + getMood() : boolean + + receiveCompliments() + } + ~interface Royalty { + + changeMood() {abstract} + + getDrink() {abstract} + + getFed() {abstract} + + getMood() : boolean {abstract} + + receiveCompliments() {abstract} + } } App --> "-jenkins" Servant -King ..|> Royalty Queen ..|> Royalty +King ..|> Royalty @enduml \ No newline at end of file diff --git a/service-layer/etc/service-layer.urm.puml b/service-layer/etc/service-layer.urm.puml index c67ffa645..880384b9f 100644 --- a/service-layer/etc/service-layer.urm.puml +++ b/service-layer/etc/service-layer.urm.puml @@ -55,6 +55,9 @@ package com.iluwatar.servicelayer.magic { } } package com.iluwatar.servicelayer.wizard { + interface WizardDao { + + findByName(String) : Wizard {abstract} + } class Wizard { - id : Long - name : String @@ -74,9 +77,6 @@ package com.iluwatar.servicelayer.wizard { + WizardDaoImpl() + findByName(name : String) : Wizard } - interface WizardDao { - + findByName(String) : Wizard {abstract} - } } package com.iluwatar.servicelayer.app { class App { @@ -86,33 +86,14 @@ package com.iluwatar.servicelayer.app { + queryData() {static} } } -package com.iluwatar.servicelayer.spell { - class SpellDaoImpl { - + SpellDaoImpl() - + findByName(name : String) : Spell - } - class Spell { - - id : Long - - name : String - - spellbook : Spellbook - + Spell() - + Spell(name : String) - + getId() : Long - + getName() : String - + getSpellbook() : Spellbook - + setId(id : Long) - + setName(name : String) - + setSpellbook(spellbook : Spellbook) - + toString() : String - } - interface SpellDao { - + findByName(String) : Spell {abstract} - } -} package com.iluwatar.servicelayer.spellbook { interface SpellbookDao { + findByName(String) : Spellbook {abstract} } + class SpellbookDaoImpl { + + SpellbookDaoImpl() + + findByName(name : String) : Spellbook + } class Spellbook { - id : Long - name : String @@ -131,9 +112,28 @@ package com.iluwatar.servicelayer.spellbook { + setWizards(wizards : Set) + toString() : String } - class SpellbookDaoImpl { - + SpellbookDaoImpl() - + findByName(name : String) : Spellbook +} +package com.iluwatar.servicelayer.spell { + class SpellDaoImpl { + + SpellDaoImpl() + + findByName(name : String) : Spell + } + interface SpellDao { + + findByName(String) : Spell {abstract} + } + class Spell { + - id : Long + - name : String + - spellbook : Spellbook + + Spell() + + Spell(name : String) + + getId() : Long + + getName() : String + + getSpellbook() : Spellbook + + setId(id : Long) + + setName(name : String) + + setSpellbook(spellbook : Spellbook) + + toString() : String } } MagicServiceImpl --> "-wizardDao" WizardDao @@ -141,18 +141,18 @@ MagicServiceImpl --> "-spellbookDao" SpellbookDao MagicServiceImpl --> "-spellDao" SpellDao Spellbook --> "-spells" Spell Spellbook --> "-wizards" Wizard -Wizard --|> BaseEntity -SpellbookDao --|> Dao SpellDaoImpl ..|> SpellDao SpellDaoImpl --|> DaoBaseImpl -MagicServiceImpl ..|> MagicService -DaoBaseImpl ..|> Dao -WizardDaoImpl ..|> WizardDao -WizardDaoImpl --|> DaoBaseImpl -Spellbook --|> BaseEntity +SpellbookDao --|> Dao +WizardDao --|> Dao SpellbookDaoImpl ..|> SpellbookDao SpellbookDaoImpl --|> DaoBaseImpl -Spell --|> BaseEntity -WizardDao --|> Dao +MagicServiceImpl ..|> MagicService SpellDao --|> Dao +Spell --|> BaseEntity +Spellbook --|> BaseEntity +Wizard --|> BaseEntity +WizardDaoImpl ..|> WizardDao +WizardDaoImpl --|> DaoBaseImpl +DaoBaseImpl ..|> Dao @enduml \ No newline at end of file diff --git a/service-locator/etc/service-locator.urm.puml b/service-locator/etc/service-locator.urm.puml index 085b05b28..9e41e7f40 100644 --- a/service-locator/etc/service-locator.urm.puml +++ b/service-locator/etc/service-locator.urm.puml @@ -1,25 +1,10 @@ @startuml package com.iluwatar.servicelocator { - interface Service { - + execute() {abstract} - + getId() : int {abstract} - + getName() : String {abstract} - } - class InitContext { - + InitContext() - + lookup(serviceName : String) : Object - } class ServiceLocator { - serviceCache : ServiceCache {static} - ServiceLocator() + getService(serviceJndiName : String) : Service {static} } - class ServiceCache { - - serviceCache : Map - + ServiceCache() - + addService(newService : Service) - + getService(serviceName : String) : Service - } class App { + App() + main(args : String[]) {static} @@ -32,6 +17,21 @@ package com.iluwatar.servicelocator { + getId() : int + getName() : String } + class InitContext { + + InitContext() + + lookup(serviceName : String) : Object + } + class ServiceCache { + - serviceCache : Map + + ServiceCache() + + addService(newService : Service) + + getService(serviceName : String) : Service + } + interface Service { + + execute() {abstract} + + getId() : int {abstract} + + getName() : String {abstract} + } } ServiceLocator --> "-serviceCache" ServiceCache ServiceImpl ..|> Service diff --git a/singleton/etc/singleton.urm.puml b/singleton/etc/singleton.urm.puml index f5ec19879..a13091772 100644 --- a/singleton/etc/singleton.urm.puml +++ b/singleton/etc/singleton.urm.puml @@ -1,32 +1,32 @@ @startuml package com.iluwatar.singleton { + class App { + + App() + + main(args : String[]) {static} + } class ThreadSafeLazyLoadedIvoryTower { - instance : ThreadSafeLazyLoadedIvoryTower {static} - ThreadSafeLazyLoadedIvoryTower() + getInstance() : ThreadSafeLazyLoadedIvoryTower {static} } - -class HelperHolder { - + INSTANCE : InitializingOnDemandHolderIdiom {static} - - HelperHolder() - } - class App { - + App() - + main(args : String[]) {static} + class InitializingOnDemandHolderIdiom { + - InitializingOnDemandHolderIdiom() + + getInstance() : InitializingOnDemandHolderIdiom {static} } class ThreadSafeDoubleCheckLocking { - instance : ThreadSafeDoubleCheckLocking {static} - ThreadSafeDoubleCheckLocking() + getInstance() : ThreadSafeDoubleCheckLocking {static} } - class InitializingOnDemandHolderIdiom { - - InitializingOnDemandHolderIdiom() - + getInstance() : InitializingOnDemandHolderIdiom {static} - } class IvoryTower { - INSTANCE : IvoryTower {static} - IvoryTower() + getInstance() : IvoryTower {static} } + -class HelperHolder { + - INSTANCE : InitializingOnDemandHolderIdiom {static} + - HelperHolder() + } enum EnumIvoryTower { + INSTANCE {static} + toString() : String diff --git a/specification/etc/specification.urm.puml b/specification/etc/specification.urm.puml index 0009a1bcd..2f194d340 100644 --- a/specification/etc/specification.urm.puml +++ b/specification/etc/specification.urm.puml @@ -1,17 +1,5 @@ @startuml package com.iluwatar.specification.creature { - class Goblin { - + Goblin() - } - interface Creature { - + getColor() : Color {abstract} - + getMovement() : Movement {abstract} - + getName() : String {abstract} - + getSize() : Size {abstract} - } - class Troll { - + Troll() - } abstract class AbstractCreature { - color : Color - movement : Movement @@ -24,20 +12,41 @@ package com.iluwatar.specification.creature { + getSize() : Size + toString() : String } + class Troll { + + Troll() + } + class Octopus { + + Octopus() + } class Shark { + Shark() } + class Goblin { + + Goblin() + } class KillerBee { + KillerBee() } - class Octopus { - + Octopus() + interface Creature { + + getColor() : Color {abstract} + + getMovement() : Movement {abstract} + + getName() : String {abstract} + + getSize() : Size {abstract} } class Dragon { + Dragon() } } package com.iluwatar.specification.property { + enum Size { + + LARGE {static} + + NORMAL {static} + + SMALL {static} + - title : String + + toString() : String + + valueOf(name : String) : Size {static} + + values() : Size[] {static} + } enum Color { + DARK {static} + GREEN {static} @@ -57,15 +66,6 @@ package com.iluwatar.specification.property { + valueOf(name : String) : Movement {static} + values() : Movement[] {static} } - enum Size { - + LARGE {static} - + NORMAL {static} - + SMALL {static} - - title : String - + toString() : String - + valueOf(name : String) : Size {static} - + values() : Size[] {static} - } } package com.iluwatar.specification.app { class App { @@ -74,9 +74,9 @@ package com.iluwatar.specification.app { } } package com.iluwatar.specification.selector { - class SizeSelector { - - s : Size - + SizeSelector(s : Size) + class MovementSelector { + - m : Movement + + MovementSelector(m : Movement) + test(t : Creature) : boolean } class ColorSelector { @@ -84,9 +84,9 @@ package com.iluwatar.specification.selector { + ColorSelector(c : Color) + test(t : Creature) : boolean } - class MovementSelector { - - m : Movement - + MovementSelector(m : Movement) + class SizeSelector { + - s : Size + + SizeSelector(s : Size) + test(t : Creature) : boolean } } @@ -96,11 +96,11 @@ MovementSelector --> "-m" Movement AbstractCreature --> "-movement" Movement AbstractCreature --> "-size" Size ColorSelector --> "-c" Color -Goblin --|> AbstractCreature -Troll --|> AbstractCreature AbstractCreature ..|> Creature -Shark --|> AbstractCreature -KillerBee --|> AbstractCreature +Troll --|> AbstractCreature Octopus --|> AbstractCreature +Shark --|> AbstractCreature +Goblin --|> AbstractCreature +KillerBee --|> AbstractCreature Dragon --|> AbstractCreature @enduml \ No newline at end of file diff --git a/state/etc/state.urm.puml b/state/etc/state.urm.puml index a0951ff6e..378c11cd1 100644 --- a/state/etc/state.urm.puml +++ b/state/etc/state.urm.puml @@ -1,5 +1,19 @@ @startuml package com.iluwatar.state { + class PeacefulState { + - mammoth : Mammoth + + PeacefulState(mammoth : Mammoth) + + observe() + + onEnterState() + } + interface State { + + observe() {abstract} + + onEnterState() {abstract} + } + class App { + + App() + + main(args : String[]) {static} + } class AngryState { - mammoth : Mammoth + AngryState(mammoth : Mammoth) @@ -14,24 +28,10 @@ package com.iluwatar.state { + timePasses() + toString() : String } - interface State { - + observe() {abstract} - + onEnterState() {abstract} - } - class PeacefulState { - - mammoth : Mammoth - + PeacefulState(mammoth : Mammoth) - + observe() - + onEnterState() - } - class App { - + App() - + main(args : String[]) {static} - } } -PeacefulState --> "-mammoth" Mammoth AngryState --> "-mammoth" Mammoth +PeacefulState --> "-mammoth" Mammoth Mammoth --> "-state" State -AngryState ..|> State PeacefulState ..|> State +AngryState ..|> State @enduml \ No newline at end of file diff --git a/step-builder/etc/step-builder.urm.puml b/step-builder/etc/step-builder.urm.puml index cc1f88ef0..129ecbf30 100644 --- a/step-builder/etc/step-builder.urm.puml +++ b/step-builder/etc/step-builder.urm.puml @@ -1,8 +1,16 @@ @startuml package com.iluwatar.stepbuilder { + interface AbilityStep { + + noAbilities() : BuildStep {abstract} + + noMoreAbilities() : BuildStep {abstract} + + withAbility(String) : AbilityStep {abstract} + } interface BuildStep { + build() : Character {abstract} } + interface NameStep { + + name(String) : ClassStep {abstract} + } -class CharacterSteps { - abilities : List - fighterClass : String @@ -27,22 +35,6 @@ package com.iluwatar.stepbuilder { + App() + main(args : String[]) {static} } - interface ClassStep { - + fighterClass(String) : WeaponStep {abstract} - + wizardClass(String) : SpellStep {abstract} - } - interface WeaponStep { - + noWeapon() : BuildStep {abstract} - + withWeapon(String) : AbilityStep {abstract} - } - interface AbilityStep { - + noAbilities() : BuildStep {abstract} - + noMoreAbilities() : BuildStep {abstract} - + withAbility(String) : AbilityStep {abstract} - } - interface NameStep { - + name(String) : ClassStep {abstract} - } class CharacterStepBuilder { - CharacterStepBuilder() + newBuilder() : NameStep {static} @@ -73,13 +65,21 @@ package com.iluwatar.stepbuilder { + noSpell() : BuildStep {abstract} + withSpell(String) : AbilityStep {abstract} } + interface ClassStep { + + fighterClass(String) : WeaponStep {abstract} + + wizardClass(String) : SpellStep {abstract} + } + interface WeaponStep { + + noWeapon() : BuildStep {abstract} + + withWeapon(String) : AbilityStep {abstract} + } } App --+ CharacterStepBuilder WeaponStep ..+ CharacterStepBuilder -SpellStep ..+ CharacterStepBuilder -AbilityStep ..+ CharacterStepBuilder ClassStep ..+ CharacterStepBuilder +SpellStep ..+ CharacterStepBuilder CharacterSteps ..+ CharacterStepBuilder +AbilityStep ..+ CharacterStepBuilder NameStep ..+ CharacterStepBuilder BuildStep ..+ CharacterStepBuilder CharacterSteps ..|> NameStep diff --git a/strategy/etc/strategy.urm.puml b/strategy/etc/strategy.urm.puml index 2cc072863..db86b9ed6 100644 --- a/strategy/etc/strategy.urm.puml +++ b/strategy/etc/strategy.urm.puml @@ -6,28 +6,28 @@ package com.iluwatar.strategy { + changeStrategy(strategy : DragonSlayingStrategy) + goToBattle() } - class SpellStrategy { - + SpellStrategy() + interface DragonSlayingStrategy { + + execute() {abstract} + } + class App { + + App() + + main(args : String[]) {static} + } + class MeleeStrategy { + + MeleeStrategy() + execute() } class ProjectileStrategy { + ProjectileStrategy() + execute() } - interface DragonSlayingStrategy { - + execute() {abstract} - } - class MeleeStrategy { - + MeleeStrategy() + class SpellStrategy { + + SpellStrategy() + execute() } - class App { - + App() - + main(args : String[]) {static} - } } DragonSlayer --> "-strategy" DragonSlayingStrategy -SpellStrategy ..|> DragonSlayingStrategy -ProjectileStrategy ..|> DragonSlayingStrategy MeleeStrategy ..|> DragonSlayingStrategy +ProjectileStrategy ..|> DragonSlayingStrategy +SpellStrategy ..|> DragonSlayingStrategy @enduml \ No newline at end of file diff --git a/template-method/etc/template-method.urm.puml b/template-method/etc/template-method.urm.puml index c98287bc6..c2c6045fe 100644 --- a/template-method/etc/template-method.urm.puml +++ b/template-method/etc/template-method.urm.puml @@ -1,17 +1,17 @@ @startuml package com.iluwatar.templatemethod { - class SubtleMethod { - + SubtleMethod() - # confuseTarget(target : String) - # pickTarget() : String - # stealTheItem(target : String) - } class HitAndRunMethod { + HitAndRunMethod() # confuseTarget(target : String) # pickTarget() : String # stealTheItem(target : String) } + class HalflingThief { + - method : StealingMethod + + HalflingThief(method : StealingMethod) + + changeMethod(method : StealingMethod) + + steal() + } abstract class StealingMethod { + StealingMethod() # confuseTarget(String) {abstract} @@ -19,18 +19,18 @@ package com.iluwatar.templatemethod { + steal() # stealTheItem(String) {abstract} } + class SubtleMethod { + + SubtleMethod() + # confuseTarget(target : String) + # pickTarget() : String + # stealTheItem(target : String) + } class App { + App() + main(args : String[]) {static} } - class HalflingThief { - - method : StealingMethod - + HalflingThief(method : StealingMethod) - + changeMethod(method : StealingMethod) - + steal() - } } HalflingThief --> "-method" StealingMethod -SubtleMethod --|> StealingMethod HitAndRunMethod --|> StealingMethod +SubtleMethod --|> StealingMethod @enduml \ No newline at end of file diff --git a/thread-pool/etc/thread-pool.urm.puml b/thread-pool/etc/thread-pool.urm.puml index 2b73e2d53..421ea1dce 100644 --- a/thread-pool/etc/thread-pool.urm.puml +++ b/thread-pool/etc/thread-pool.urm.puml @@ -1,14 +1,5 @@ @startuml package com.iluwatar.threadpool { - class Worker { - - task : Task - + Worker(task : Task) - + run() - } - class App { - + App() - + main(args : String[]) {static} - } abstract class Task { - ID_GENERATOR : AtomicInteger {static} - id : int @@ -18,18 +9,27 @@ package com.iluwatar.threadpool { + getTimeMs() : int + toString() : String } - class PotatoPeelingTask { - - TIME_PER_POTATO : int {static} - + PotatoPeelingTask(numPotatoes : int) - + toString() : String - } class CoffeeMakingTask { - TIME_PER_CUP : int {static} + CoffeeMakingTask(numCups : int) + toString() : String } + class Worker { + - task : Task + + Worker(task : Task) + + run() + } + class PotatoPeelingTask { + - TIME_PER_POTATO : int {static} + + PotatoPeelingTask(numPotatoes : int) + + toString() : String + } + class App { + + App() + + main(args : String[]) {static} + } } Worker --> "-task" Task -PotatoPeelingTask --|> Task CoffeeMakingTask --|> Task +PotatoPeelingTask --|> Task @enduml \ No newline at end of file diff --git a/tolerant-reader/etc/tolerant-reader.urm.puml b/tolerant-reader/etc/tolerant-reader.urm.puml index 9e2bc83b3..f203f8257 100644 --- a/tolerant-reader/etc/tolerant-reader.urm.puml +++ b/tolerant-reader/etc/tolerant-reader.urm.puml @@ -1,11 +1,5 @@ @startuml package com.iluwatar.tolerantreader { - class RainbowFishSerializer { - - RainbowFishSerializer() - + readV1(filename : String) : RainbowFish {static} - + writeV1(rainbowFish : RainbowFish, filename : String) {static} - + writeV2(rainbowFish : RainbowFishV2, filename : String) {static} - } class RainbowFish { - age : int - lengthMeters : int @@ -18,6 +12,10 @@ package com.iluwatar.tolerantreader { + getName() : String + getWeightTons() : int } + class App { + + App() + + main(args : String[]) {static} + } class RainbowFishV2 { - angry : boolean - hungry : boolean @@ -29,9 +27,11 @@ package com.iluwatar.tolerantreader { + getHungry() : boolean + getSleeping() : boolean } - class App { - + App() - + main(args : String[]) {static} + class RainbowFishSerializer { + - RainbowFishSerializer() + + readV1(filename : String) : RainbowFish {static} + + writeV1(rainbowFish : RainbowFish, filename : String) {static} + + writeV2(rainbowFish : RainbowFishV2, filename : String) {static} } } RainbowFishV2 --|> RainbowFish diff --git a/twin/etc/twin.urm.puml b/twin/etc/twin.urm.puml index b95325abb..b4bd52468 100644 --- a/twin/etc/twin.urm.puml +++ b/twin/etc/twin.urm.puml @@ -1,9 +1,10 @@ @startuml package com.iluwatar.twin { - class App { - + App() - + main(args : String[]) {static} - - waiting() {static} + abstract class GameItem { + + GameItem() + + click() {abstract} + + doDraw() {abstract} + + draw() } class BallItem { - isSuspended : boolean @@ -14,11 +15,10 @@ package com.iluwatar.twin { + move() + setTwin(twin : BallThread) } - abstract class GameItem { - + GameItem() - + click() {abstract} - + doDraw() {abstract} - + draw() + class App { + + App() + + main(args : String[]) {static} + - waiting() {static} } } BallItem --|> GameItem diff --git a/value-object/etc/value-object.urm.puml b/value-object/etc/value-object.urm.puml index 223f91957..6c81de017 100644 --- a/value-object/etc/value-object.urm.puml +++ b/value-object/etc/value-object.urm.puml @@ -1,9 +1,5 @@ @startuml package com.iluwatar.value.object { - class App { - + App() - + main(args : String[]) {static} - } class HeroStat { - intelligence : int - luck : int @@ -17,5 +13,9 @@ package com.iluwatar.value.object { + toString() : String + valueOf(strength : int, intelligence : int, luck : int) : HeroStat {static} } + class App { + + App() + + main(args : String[]) {static} + } } @enduml \ No newline at end of file diff --git a/visitor/etc/visitor.urm.puml b/visitor/etc/visitor.urm.puml index 3f5689f71..1f28e4e2f 100644 --- a/visitor/etc/visitor.urm.puml +++ b/visitor/etc/visitor.urm.puml @@ -1,57 +1,57 @@ @startuml package com.iluwatar.visitor { + class Commander { + + Commander(children : Unit[]) + + accept(visitor : UnitVisitor) + + toString() : String + } + interface UnitVisitor { + + visitCommander(Commander) {abstract} + + visitSergeant(Sergeant) {abstract} + + visitSoldier(Soldier) {abstract} + } class CommanderVisitor { + CommanderVisitor() + visitCommander(commander : Commander) + visitSergeant(sergeant : Sergeant) + visitSoldier(soldier : Soldier) } + class Soldier { + + Soldier(children : Unit[]) + + accept(visitor : UnitVisitor) + + toString() : String + } + class App { + + App() + + main(args : String[]) {static} + } + abstract class Unit { + - children : Unit[] + + Unit(children : Unit[]) + + accept(visitor : UnitVisitor) + } + class SoldierVisitor { + + SoldierVisitor() + + visitCommander(commander : Commander) + + visitSergeant(sergeant : Sergeant) + + visitSoldier(soldier : Soldier) + } + class SergeantVisitor { + + SergeantVisitor() + + visitCommander(commander : Commander) + + visitSergeant(sergeant : Sergeant) + + visitSoldier(soldier : Soldier) + } class Sergeant { + Sergeant(children : Unit[]) + accept(visitor : UnitVisitor) + toString() : String } - class Commander { - + Commander(children : Unit[]) - + accept(visitor : UnitVisitor) - + toString() : String - } - abstract class Unit { - - children : Unit[] - + Unit(children : Unit[]) - + accept(visitor : UnitVisitor) - } - class Soldier { - + Soldier(children : Unit[]) - + accept(visitor : UnitVisitor) - + toString() : String - } - class SergeantVisitor { - + SergeantVisitor() - + visitCommander(commander : Commander) - + visitSergeant(sergeant : Sergeant) - + visitSoldier(soldier : Soldier) - } - interface UnitVisitor { - + visitCommander(Commander) {abstract} - + visitSergeant(Sergeant) {abstract} - + visitSoldier(Soldier) {abstract} - } - class App { - + App() - + main(args : String[]) {static} - } - class SoldierVisitor { - + SoldierVisitor() - + visitCommander(commander : Commander) - + visitSergeant(sergeant : Sergeant) - + visitSoldier(soldier : Soldier) - } } -CommanderVisitor ..|> UnitVisitor -Sergeant --|> Unit Commander --|> Unit +CommanderVisitor ..|> UnitVisitor Soldier --|> Unit -SergeantVisitor ..|> UnitVisitor SoldierVisitor ..|> UnitVisitor +SergeantVisitor ..|> UnitVisitor +Sergeant --|> Unit @enduml \ No newline at end of file