diff --git a/abstract-document/README.md b/abstract-document/README.md index e9a2bed94fd8..15f5c6c85de9 100644 --- a/abstract-document/README.md +++ b/abstract-document/README.md @@ -5,8 +5,7 @@ folder: abstract-document permalink: /patterns/abstract-document/ categories: Structural tags: - - Java - - Difficulty-Intermediate + - Extensibility --- ## Intent diff --git a/abstract-factory/README.md b/abstract-factory/README.md index a4fc5cc746da..6a840f316974 100644 --- a/abstract-factory/README.md +++ b/abstract-factory/README.md @@ -5,9 +5,7 @@ folder: abstract-factory permalink: /patterns/abstract-factory/ categories: Creational tags: - - Java - - Gang Of Four - - Difficulty-Intermediate + - Gang of Four --- ## Also known as diff --git a/acyclic-visitor/README.md b/acyclic-visitor/README.md index cc5f467b7960..f293e4393f20 100644 --- a/acyclic-visitor/README.md +++ b/acyclic-visitor/README.md @@ -5,8 +5,7 @@ folder: acyclic-visitor permalink: /patterns/acyclic-visitor/ categories: Behavioral tags: - - Java - - Difficulty-Intermediate + - Extensibility --- ## Intent diff --git a/adapter/README.md b/adapter/README.md index b1ad775cf3e3..a8a0214be83c 100644 --- a/adapter/README.md +++ b/adapter/README.md @@ -5,9 +5,7 @@ folder: adapter permalink: /patterns/adapter/ categories: Structural tags: - - Java - - Gang Of Four - - Difficulty-Beginner + - Gang of Four --- ## Also known as diff --git a/aggregator-microservices/README.md b/aggregator-microservices/README.md index c3498d315ab0..4d64178a66a5 100644 --- a/aggregator-microservices/README.md +++ b/aggregator-microservices/README.md @@ -5,8 +5,7 @@ folder: aggregator-microservices permalink: /patterns/aggregator-microservices/ categories: Architectural tags: -- Java -- Spring +- Cloud distributed --- ## Intent diff --git a/ambassador/README.md b/ambassador/README.md index 862c579a0ec9..78b3a885669f 100644 --- a/ambassador/README.md +++ b/ambassador/README.md @@ -5,8 +5,7 @@ folder: ambassador permalink: /patterns/ambassador/ categories: Structural tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Intent diff --git a/api-gateway/README.md b/api-gateway/README.md index 2fd04900e8a3..3a4f13e35e62 100644 --- a/api-gateway/README.md +++ b/api-gateway/README.md @@ -5,9 +5,8 @@ folder: api-gateway permalink: /patterns/api-gateway/ categories: Architectural tags: -- Java -- Difficulty-Intermediate -- Spring +- Cloud distributed +- Decoupling --- ## Intent diff --git a/async-method-invocation/README.md b/async-method-invocation/README.md index f1faa396d1ff..d1bda1a528cd 100644 --- a/async-method-invocation/README.md +++ b/async-method-invocation/README.md @@ -5,9 +5,6 @@ folder: async-method-invocation permalink: /patterns/async-method-invocation/ categories: Concurrency tags: - - Java - - Difficulty-Intermediate - - Functional - Reactive --- diff --git a/balking/README.md b/balking/README.md index 36a3efcb9f69..22257ac7bb52 100644 --- a/balking/README.md +++ b/balking/README.md @@ -5,8 +5,7 @@ folder: balking permalink: /patterns/balking/ categories: Concurrency tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent diff --git a/bridge/README.md b/bridge/README.md index c48e1025cab7..ebd6e5b41e20 100644 --- a/bridge/README.md +++ b/bridge/README.md @@ -5,9 +5,7 @@ folder: bridge permalink: /patterns/bridge/ categories: Structural tags: - - Java - - Gang Of Four - - Difficulty-Intermediate + - Gang of Four --- ## Also known as diff --git a/builder/README.md b/builder/README.md index c6190ef17a97..ccfc378d6e36 100644 --- a/builder/README.md +++ b/builder/README.md @@ -5,9 +5,7 @@ folder: builder permalink: /patterns/builder/ categories: Creational tags: - - Java - - Gang Of Four - - Difficulty-Intermediate + - Gang of Four --- ## Intent diff --git a/business-delegate/README.md b/business-delegate/README.md index 5debebbbad9f..38eb591b8549 100644 --- a/business-delegate/README.md +++ b/business-delegate/README.md @@ -3,10 +3,9 @@ layout: pattern title: Business Delegate folder: business-delegate permalink: /patterns/business-delegate/ -categories: Business Tier +categories: Structural tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Intent diff --git a/bytecode/README.md b/bytecode/README.md index 13d8013d6d24..ee3f96ed8ac3 100644 --- a/bytecode/README.md +++ b/bytecode/README.md @@ -5,8 +5,7 @@ folder: bytecode permalink: /patterns/bytecode/ categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Game programming --- ## Intent diff --git a/caching/README.md b/caching/README.md index 34fe0222af4e..4172cc72ab62 100644 --- a/caching/README.md +++ b/caching/README.md @@ -3,10 +3,8 @@ layout: pattern title: Caching folder: caching permalink: /patterns/caching/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Intermediate - Performance --- diff --git a/callback/README.md b/callback/README.md index 27af6337cacc..6942019f3693 100644 --- a/callback/README.md +++ b/callback/README.md @@ -3,12 +3,9 @@ layout: pattern title: Callback folder: callback permalink: /patterns/callback/ -categories: Other +categories: Idiom tags: - - Java - - Difficulty-Beginner - - Functional - - Idiom + - Reactive --- ## Intent diff --git a/chain/README.md b/chain/README.md index 7fdc4243b3ac..1dc8af41c0e3 100644 --- a/chain/README.md +++ b/chain/README.md @@ -5,9 +5,7 @@ folder: chain permalink: /patterns/chain/ categories: Behavioral tags: - - Java - - Gang Of Four - - Difficulty-Intermediate + - Gang of Four --- ## Intent diff --git a/circuit-breaker/README.md b/circuit-breaker/README.md index 8e840ce1efb3..e0ef7d1fb7eb 100644 --- a/circuit-breaker/README.md +++ b/circuit-breaker/README.md @@ -3,11 +3,10 @@ layout: pattern title: Circuit Breaker folder: circuit-breaker permalink: /patterns/circuit-breaker/ -categories: Other +categories: Behavioral tags: - - Java - Performance - - Difficulty-Intermediate + - Decoupling --- ## Intent @@ -179,6 +178,7 @@ Use the Circuit Breaker pattern when - [Retry Pattern](https://github.com/iluwatar/java-design-patterns/tree/master/retry) ## Real world examples + * [Spring Circuit Breaker module](https://spring.io/guides/gs/circuit-breaker) * [Netflix Hystrix API](https://github.com/Netflix/Hystrix) diff --git a/collection-pipeline/README.md b/collection-pipeline/README.md index 3f223dd07c65..8cf1a7c96314 100644 --- a/collection-pipeline/README.md +++ b/collection-pipeline/README.md @@ -3,11 +3,9 @@ layout: pattern title: Collection Pipeline folder: collection-pipeline permalink: /patterns/collection-pipeline/ -categories: Other +categories: Functional tags: - - Java - - Difficulty-Beginner - - Functional + - Reactive --- ## Intent @@ -28,4 +26,4 @@ Use the Collection Pipeline pattern when * [Function composition and the Collection Pipeline pattern](https://www.ibm.com/developerworks/library/j-java8idioms2/index.html) * [Martin Fowler](https://martinfowler.com/articles/collection-pipeline/) -* [Java8 Streams](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) \ No newline at end of file +* [Java8 Streams](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) diff --git a/combinator/README.md b/combinator/README.md index 98d353050dbf..6fa727a3f20c 100644 --- a/combinator/README.md +++ b/combinator/README.md @@ -3,11 +3,9 @@ layout: pattern title: Combinator folder: combinator permalink: /patterns/combinator/ -categories: Behavioral +categories: Idiom tags: - - Functional - Reactive - - Idiom --- ## Also known as @@ -23,13 +21,16 @@ and some "combinators" which can combine values of type T in various ways to bui ## Applicability Use the combinator pattern when: + - You are able to create a more complex value from more plain values but having the same type(a combination of them) ## Real world examples + - java.util.function.Function#compose - java.util.function.Function#andThen ## Credits + - [Example for java](https://gtrefs.github.io/code/combinator-pattern/) - [Combinator pattern](https://wiki.haskell.org/Combinator_pattern) -- [Combinatory logic](https://wiki.haskell.org/Combinatory_logic) \ No newline at end of file +- [Combinatory logic](https://wiki.haskell.org/Combinatory_logic) diff --git a/command/README.md b/command/README.md index bbe149df099a..bab95b90ce1d 100644 --- a/command/README.md +++ b/command/README.md @@ -5,10 +5,7 @@ folder: command permalink: /patterns/command/ categories: Behavioral tags: - - Java - - Gang Of Four - - Difficulty-Intermediate - - Functional + - Gang of Four --- ## Also known as diff --git a/commander/README.md b/commander/README.md index 0cee5dc77ee6..d8f7c1c5ae8f 100644 --- a/commander/README.md +++ b/commander/README.md @@ -3,10 +3,9 @@ layout: pattern title: Commander folder: commander permalink: /patterns/commander/ -categories: Other +categories: Concurrency tags: - - Java - - Difficulty-Intermediate + - Cloud distributed --- ## Intent @@ -24,4 +23,5 @@ Handling distributed transactions can be tricky, but if we choose to not handle We need a mechanism in place which can handle these kinds of situations. We have to direct the order to either one of the services (in this example, shipping) and then add the order into the database of the other service (in this example, payment), since two databses cannot be updated atomically. If currently unable to do it, there should be a queue where this request can be queued, and there has to be a mechanism which allows for a failure in the queueing as well. All this needs to be done by constant retries while ensuring idempotence (even if the request is made several times, the change should only be applied once) by a commander class, to reach a state of eventual consistency. ## Credits + * [https://www.grahamlea.com/2016/08/distributed-transactions-microservices-icebergs/] diff --git a/composite/README.md b/composite/README.md index ba939b8035a6..1db1ce14fb68 100644 --- a/composite/README.md +++ b/composite/README.md @@ -5,9 +5,7 @@ folder: composite permalink: /patterns/composite/ categories: Structural tags: - - Java - - Gang Of Four - - Difficulty-Intermediate + - Gang of Four --- ## Intent diff --git a/converter/README.md b/converter/README.md index 824d47e3813a..3be8ce331b2f 100644 --- a/converter/README.md +++ b/converter/README.md @@ -3,10 +3,9 @@ layout: pattern title: Converter folder: converter permalink: /patterns/converter/ -categories: Business Tier +categories: Creational tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent @@ -64,20 +63,26 @@ The specialized converters inherit from this base class as follows. public class UserConverter extends Converter { public UserConverter() { - super(userDto -> new User(userDto.getFirstName(), userDto.getLastName(), userDto.isActive(), - userDto.getEmail()), - user -> new UserDto(user.getFirstName(), user.getLastName(), user.isActive(), - user.getUserId())); + super(UserConverter::convertToEntity, UserConverter::convertToDto); } + + private static UserDto convertToDto(User user) { + return new UserDto(user.getFirstName(), user.getLastName(), user.isActive(), user.getUserId()); + } + + private static User convertToEntity(UserDto dto) { + return new User(dto.getFirstName(), dto.getLastName(), dto.isActive(), dto.getEmail()); + } + } ``` Now mapping between User and UserDto becomes trivial. ```java -Converter userConverter = new UserConverter(); -UserDto dtoUser = new UserDto("John", "Doe", true, "whatever[at]wherever.com"); -User user = userConverter.convertFromDto(dtoUser); +var userConverter = new UserConverter(); +var dtoUser = new UserDto("John", "Doe", true, "whatever[at]wherever.com"); +var user = userConverter.convertFromDto(dtoUser); ``` ## Class diagram diff --git a/converter/src/main/java/com/iluwatar/converter/App.java b/converter/src/main/java/com/iluwatar/converter/App.java index 935fc4f19943..2d4ec0429d21 100644 --- a/converter/src/main/java/com/iluwatar/converter/App.java +++ b/converter/src/main/java/com/iluwatar/converter/App.java @@ -49,8 +49,11 @@ public static void main(String[] args) { User user = userConverter.convertFromDto(dtoUser); LOGGER.info("Entity converted from DTO:" + user); - var users = List.of(new User("Camile", "Tough", false, "124sad"), - new User("Marti", "Luther", true, "42309fd"), new User("Kate", "Smith", true, "if0243")); + var users = List.of( + new User("Camile", "Tough", false, "124sad"), + new User("Marti", "Luther", true, "42309fd"), + new User("Kate", "Smith", true, "if0243") + ); LOGGER.info("Domain entities:"); users.stream().map(User::toString).forEach(LOGGER::info); diff --git a/converter/src/main/java/com/iluwatar/converter/User.java b/converter/src/main/java/com/iluwatar/converter/User.java index ae5e89f7c9a1..637d77a25e8e 100644 --- a/converter/src/main/java/com/iluwatar/converter/User.java +++ b/converter/src/main/java/com/iluwatar/converter/User.java @@ -73,7 +73,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - User user = (User) o; + var user = (User) o; return isActive == user.isActive && Objects.equals(firstName, user.firstName) && Objects .equals(lastName, user.lastName) && Objects.equals(userId, user.userId); } diff --git a/converter/src/main/java/com/iluwatar/converter/UserConverter.java b/converter/src/main/java/com/iluwatar/converter/UserConverter.java index 8637c042d48f..c2341695e5d9 100644 --- a/converter/src/main/java/com/iluwatar/converter/UserConverter.java +++ b/converter/src/main/java/com/iluwatar/converter/UserConverter.java @@ -28,13 +28,16 @@ */ public class UserConverter extends Converter { - /** - * Constructor. - */ public UserConverter() { - super(userDto -> new User(userDto.getFirstName(), userDto.getLastName(), userDto.isActive(), - userDto.getEmail()), - user -> new UserDto(user.getFirstName(), user.getLastName(), user.isActive(), - user.getUserId())); + super(UserConverter::convertToEntity, UserConverter::convertToDto); } + + private static UserDto convertToDto(User user) { + return new UserDto(user.getFirstName(), user.getLastName(), user.isActive(), user.getUserId()); + } + + private static User convertToEntity(UserDto dto) { + return new User(dto.getFirstName(), dto.getLastName(), dto.isActive(), dto.getEmail()); + } + } diff --git a/converter/src/main/java/com/iluwatar/converter/UserDto.java b/converter/src/main/java/com/iluwatar/converter/UserDto.java index eae77e90130e..e75aaab8cf76 100644 --- a/converter/src/main/java/com/iluwatar/converter/UserDto.java +++ b/converter/src/main/java/com/iluwatar/converter/UserDto.java @@ -74,7 +74,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - UserDto userDto = (UserDto) o; + var userDto = (UserDto) o; return isActive == userDto.isActive && Objects.equals(firstName, userDto.firstName) && Objects .equals(lastName, userDto.lastName) && Objects.equals(email, userDto.email); } diff --git a/converter/src/test/java/com/iluwatar/converter/AppTest.java b/converter/src/test/java/com/iluwatar/converter/AppTest.java index c9ed28787419..ed53c686393c 100644 --- a/converter/src/test/java/com/iluwatar/converter/AppTest.java +++ b/converter/src/test/java/com/iluwatar/converter/AppTest.java @@ -32,8 +32,7 @@ public class AppTest { @Test public void testMain() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/converter/src/test/java/com/iluwatar/converter/ConverterTest.java b/converter/src/test/java/com/iluwatar/converter/ConverterTest.java index 92d47bb41087..d9e4e418bb98 100644 --- a/converter/src/test/java/com/iluwatar/converter/ConverterTest.java +++ b/converter/src/test/java/com/iluwatar/converter/ConverterTest.java @@ -23,12 +23,11 @@ package com.iluwatar.converter; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.List; import java.util.Random; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; /** * Tests for {@link Converter} @@ -42,8 +41,8 @@ public class ConverterTest { */ @Test public void testConversionsStartingFromDomain() { - User u1 = new User("Tom", "Hanks", true, "tom@hanks.com"); - User u2 = userConverter.convertFromDto(userConverter.convertFromEntity(u1)); + var u1 = new User("Tom", "Hanks", true, "tom@hanks.com"); + var u2 = userConverter.convertFromDto(userConverter.convertFromEntity(u1)); assertEquals(u1, u2); } @@ -52,37 +51,47 @@ public void testConversionsStartingFromDomain() { */ @Test public void testConversionsStartingFromDto() { - UserDto u1 = new UserDto("Tom", "Hanks", true, "tom@hanks.com"); - UserDto u2 = userConverter.convertFromEntity(userConverter.convertFromDto(u1)); + var u1 = new UserDto("Tom", "Hanks", true, "tom@hanks.com"); + var u2 = userConverter.convertFromEntity(userConverter.convertFromDto(u1)); assertEquals(u1, u2); } /** - * Tests the custom users converter. Thanks to Java8 lambdas, converter can be easily and - * cleanly instantiated allowing various different conversion strategies to be implemented. + * Tests the custom users converter. Thanks to Java8 lambdas, converter can be easily and cleanly + * instantiated allowing various different conversion strategies to be implemented. */ @Test public void testCustomConverter() { - Converter converter = new Converter<>( - userDto -> new User(userDto.getFirstName(), userDto.getLastName(), userDto.isActive(), - String.valueOf(new Random().nextInt())), - user -> new UserDto(user.getFirstName(), user.getLastName(), user.isActive(), - user.getFirstName().toLowerCase() + user.getLastName().toLowerCase() + "@whatever.com")); - User u1 = new User("John", "Doe", false, "12324"); - UserDto userDto = converter.convertFromEntity(u1); + var converter = new Converter( + userDto -> new User( + userDto.getFirstName(), + userDto.getLastName(), + userDto.isActive(), + String.valueOf(new Random().nextInt()) + ), + user -> new UserDto( + user.getFirstName(), + user.getLastName(), + user.isActive(), + user.getFirstName().toLowerCase() + user.getLastName().toLowerCase() + "@whatever.com") + ); + var u1 = new User("John", "Doe", false, "12324"); + var userDto = converter.convertFromEntity(u1); assertEquals("johndoe@whatever.com", userDto.getEmail()); } /** - * Test whether converting a collection of Users to DTO Users and then converting them back to domain - * users returns an equal collection. + * Test whether converting a collection of Users to DTO Users and then converting them back to + * domain users returns an equal collection. */ @Test public void testCollectionConversion() { - List users = List.of(new User("Camile", "Tough", false, "124sad"), - new User("Marti", "Luther", true, "42309fd"), - new User("Kate", "Smith", true, "if0243")); - List fromDtos = userConverter.createFromDtos(userConverter.createFromEntities(users)); + var users = List.of( + new User("Camile", "Tough", false, "124sad"), + new User("Marti", "Luther", true, "42309fd"), + new User("Kate", "Smith", true, "if0243") + ); + var fromDtos = userConverter.createFromDtos(userConverter.createFromEntities(users)); assertEquals(users, fromDtos); } } diff --git a/cqrs/README.md b/cqrs/README.md index b9cbeacd8775..431ae6279d14 100644 --- a/cqrs/README.md +++ b/cqrs/README.md @@ -5,8 +5,8 @@ folder: cqrs permalink: /patterns/cqrs/ categories: Architectural tags: - - Java - - Difficulty-Intermediate + - Performance + - Cloud distributed --- ## Intent diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/app/App.java b/cqrs/src/main/java/com/iluwatar/cqrs/app/App.java index b1b0ddeac9ea..436c2d1306db 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/app/App.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/app/App.java @@ -24,15 +24,9 @@ package com.iluwatar.cqrs.app; import com.iluwatar.cqrs.commandes.CommandServiceImpl; -import com.iluwatar.cqrs.commandes.ICommandService; import com.iluwatar.cqrs.constants.AppConstants; -import com.iluwatar.cqrs.dto.Author; -import com.iluwatar.cqrs.dto.Book; -import com.iluwatar.cqrs.queries.IQueryService; import com.iluwatar.cqrs.queries.QueryServiceImpl; import com.iluwatar.cqrs.util.HibernateUtil; -import java.math.BigInteger; -import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,7 +50,7 @@ public class App { * @param args command line args */ public static void main(String[] args) { - ICommandService commands = new CommandServiceImpl(); + var commands = new CommandServiceImpl(); // Create Authors and Books using CommandService commands.authorCreated(AppConstants.E_EVANS, "Eric Evans", "evans@email.com"); @@ -72,15 +66,15 @@ public static void main(String[] args) { commands.bookAddedToAuthor("Domain Specific Languages", 48.89, AppConstants.M_FOWLER); commands.authorNameUpdated(AppConstants.E_EVANS, "Eric J. Evans"); - IQueryService queries = new QueryServiceImpl(); + var queries = new QueryServiceImpl(); // Query the database using QueryService - Author nullAuthor = queries.getAuthorByUsername("username"); - Author evans = queries.getAuthorByUsername(AppConstants.E_EVANS); - BigInteger blochBooksCount = queries.getAuthorBooksCount(AppConstants.J_BLOCH); - BigInteger authorsCount = queries.getAuthorsCount(); - Book dddBook = queries.getBook("Domain-Driven Design"); - List blochBooks = queries.getAuthorBooks(AppConstants.J_BLOCH); + var nullAuthor = queries.getAuthorByUsername("username"); + var evans = queries.getAuthorByUsername(AppConstants.E_EVANS); + var blochBooksCount = queries.getAuthorBooksCount(AppConstants.J_BLOCH); + var authorsCount = queries.getAuthorsCount(); + var dddBook = queries.getBook("Domain-Driven Design"); + var blochBooks = queries.getAuthorBooks(AppConstants.J_BLOCH); LOGGER.info("Author username : {}", nullAuthor); LOGGER.info("Author evans : {}", evans); diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java b/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java index c8146845e33b..ba08811e7fc0 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/commandes/CommandServiceImpl.java @@ -26,8 +26,6 @@ import com.iluwatar.cqrs.domain.model.Author; import com.iluwatar.cqrs.domain.model.Book; import com.iluwatar.cqrs.util.HibernateUtil; -import org.hibernate.Query; -import org.hibernate.Session; import org.hibernate.SessionFactory; /** @@ -39,9 +37,9 @@ public class CommandServiceImpl implements ICommandService { private SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); private Author getAuthorByUsername(String username) { - Author author = null; - try (Session session = sessionFactory.openSession()) { - Query query = session.createQuery("from Author where username=:username"); + Author author; + try (var session = sessionFactory.openSession()) { + var query = session.createQuery("from Author where username=:username"); query.setParameter("username", username); author = (Author) query.uniqueResult(); } @@ -53,9 +51,9 @@ private Author getAuthorByUsername(String username) { } private Book getBookByTitle(String title) { - Book book = null; - try (Session session = sessionFactory.openSession()) { - Query query = session.createQuery("from Book where title=:title"); + Book book; + try (var session = sessionFactory.openSession()) { + var query = session.createQuery("from Book where title=:title"); query.setParameter("title", title); book = (Book) query.uniqueResult(); } @@ -68,8 +66,8 @@ private Book getBookByTitle(String title) { @Override public void authorCreated(String username, String name, String email) { - Author author = new Author(username, name, email); - try (Session session = sessionFactory.openSession()) { + var author = new Author(username, name, email); + try (var session = sessionFactory.openSession()) { session.beginTransaction(); session.save(author); session.getTransaction().commit(); @@ -78,9 +76,9 @@ public void authorCreated(String username, String name, String email) { @Override public void bookAddedToAuthor(String title, double price, String username) { - Author author = getAuthorByUsername(username); - Book book = new Book(title, price, author); - try (Session session = sessionFactory.openSession()) { + var author = getAuthorByUsername(username); + var book = new Book(title, price, author); + try (var session = sessionFactory.openSession()) { session.beginTransaction(); session.save(book); session.getTransaction().commit(); @@ -89,9 +87,9 @@ public void bookAddedToAuthor(String title, double price, String username) { @Override public void authorNameUpdated(String username, String name) { - Author author = getAuthorByUsername(username); + var author = getAuthorByUsername(username); author.setName(name); - try (Session session = sessionFactory.openSession()) { + try (var session = sessionFactory.openSession()) { session.beginTransaction(); session.update(author); session.getTransaction().commit(); @@ -100,9 +98,9 @@ public void authorNameUpdated(String username, String name) { @Override public void authorUsernameUpdated(String oldUsername, String newUsername) { - Author author = getAuthorByUsername(oldUsername); + var author = getAuthorByUsername(oldUsername); author.setUsername(newUsername); - try (Session session = sessionFactory.openSession()) { + try (var session = sessionFactory.openSession()) { session.beginTransaction(); session.update(author); session.getTransaction().commit(); @@ -111,9 +109,9 @@ public void authorUsernameUpdated(String oldUsername, String newUsername) { @Override public void authorEmailUpdated(String username, String email) { - Author author = getAuthorByUsername(username); + var author = getAuthorByUsername(username); author.setEmail(email); - try (Session session = sessionFactory.openSession()) { + try (var session = sessionFactory.openSession()) { session.beginTransaction(); session.update(author); session.getTransaction().commit(); @@ -122,9 +120,9 @@ public void authorEmailUpdated(String username, String email) { @Override public void bookTitleUpdated(String oldTitle, String newTitle) { - Book book = getBookByTitle(oldTitle); + var book = getBookByTitle(oldTitle); book.setTitle(newTitle); - try (Session session = sessionFactory.openSession()) { + try (var session = sessionFactory.openSession()) { session.beginTransaction(); session.update(book); session.getTransaction().commit(); @@ -133,9 +131,9 @@ public void bookTitleUpdated(String oldTitle, String newTitle) { @Override public void bookPriceUpdated(String title, double price) { - Book book = getBookByTitle(title); + var book = getBookByTitle(title); book.setPrice(price); - try (Session session = sessionFactory.openSession()) { + try (var session = sessionFactory.openSession()) { session.beginTransaction(); session.update(book); session.getTransaction().commit(); diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/dto/Author.java b/cqrs/src/main/java/com/iluwatar/cqrs/dto/Author.java index 8318c4a951f3..f3fa3f03b6e3 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/dto/Author.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/dto/Author.java @@ -80,7 +80,7 @@ public boolean equals(Object obj) { if (!(obj instanceof Author)) { return false; } - Author other = (Author) obj; + var other = (Author) obj; return username.equals(other.getUsername()) && email.equals(other.getEmail()) && name .equals(other.getName()); diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/dto/Book.java b/cqrs/src/main/java/com/iluwatar/cqrs/dto/Book.java index c859b0c769dd..afddd5f28d8d 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/dto/Book.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/dto/Book.java @@ -73,7 +73,7 @@ public boolean equals(Object obj) { if (!(obj instanceof Book)) { return false; } - Book book = (Book) obj; + var book = (Book) obj; return title.equals(book.getTitle()) && price == book.getPrice(); } diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java b/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java index 24532515d412..9b008402edc8 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/queries/QueryServiceImpl.java @@ -29,8 +29,6 @@ import com.iluwatar.cqrs.util.HibernateUtil; import java.math.BigInteger; import java.util.List; -import org.hibernate.SQLQuery; -import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.transform.Transformers; @@ -44,9 +42,9 @@ public class QueryServiceImpl implements IQueryService { @Override public Author getAuthorByUsername(String username) { - Author authorDTo = null; - try (Session session = sessionFactory.openSession()) { - SQLQuery sqlQuery = session.createSQLQuery("SELECT a.username as \"username\"," + Author authorDTo; + try (var session = sessionFactory.openSession()) { + var sqlQuery = session.createSQLQuery("SELECT a.username as \"username\"," + " a.name as \"name\", a.email as \"email\"" + "FROM Author a where a.username=:username"); sqlQuery.setParameter(AppConstants.USER_NAME, username); @@ -58,9 +56,9 @@ public Author getAuthorByUsername(String username) { @Override public Book getBook(String title) { - Book bookDTo = null; - try (Session session = sessionFactory.openSession()) { - SQLQuery sqlQuery = session.createSQLQuery("SELECT b.title as \"title\"," + Book bookDTo; + try (var session = sessionFactory.openSession()) { + var sqlQuery = session.createSQLQuery("SELECT b.title as \"title\"," + " b.price as \"price\"" + " FROM Book b where b.title=:title"); sqlQuery.setParameter("title", title); bookDTo = @@ -71,9 +69,9 @@ public Book getBook(String title) { @Override public List getAuthorBooks(String username) { - List bookDTos = null; - try (Session session = sessionFactory.openSession()) { - SQLQuery sqlQuery = session.createSQLQuery("SELECT b.title as \"title\", b.price as \"price\"" + List bookDTos; + try (var session = sessionFactory.openSession()) { + var sqlQuery = session.createSQLQuery("SELECT b.title as \"title\", b.price as \"price\"" + " FROM Author a , Book b where b.author_id = a.id and a.username=:username"); sqlQuery.setParameter(AppConstants.USER_NAME, username); bookDTos = sqlQuery.setResultTransformer(Transformers.aliasToBean(Book.class)).list(); @@ -83,9 +81,9 @@ public List getAuthorBooks(String username) { @Override public BigInteger getAuthorBooksCount(String username) { - BigInteger bookcount = null; - try (Session session = sessionFactory.openSession()) { - SQLQuery sqlQuery = session.createSQLQuery( + BigInteger bookcount; + try (var session = sessionFactory.openSession()) { + var sqlQuery = session.createSQLQuery( "SELECT count(b.title)" + " FROM Book b, Author a" + " where b.author_id = a.id and a.username=:username"); sqlQuery.setParameter(AppConstants.USER_NAME, username); @@ -96,9 +94,9 @@ public BigInteger getAuthorBooksCount(String username) { @Override public BigInteger getAuthorsCount() { - BigInteger authorcount = null; - try (Session session = sessionFactory.openSession()) { - SQLQuery sqlQuery = session.createSQLQuery("SELECT count(id) from Author"); + BigInteger authorcount; + try (var session = sessionFactory.openSession()) { + var sqlQuery = session.createSQLQuery("SELECT count(id) from Author"); authorcount = (BigInteger) sqlQuery.uniqueResult(); } return authorcount; diff --git a/cqrs/src/main/java/com/iluwatar/cqrs/util/HibernateUtil.java b/cqrs/src/main/java/com/iluwatar/cqrs/util/HibernateUtil.java index 6d9788a5efe0..31610e5c1b01 100644 --- a/cqrs/src/main/java/com/iluwatar/cqrs/util/HibernateUtil.java +++ b/cqrs/src/main/java/com/iluwatar/cqrs/util/HibernateUtil.java @@ -25,7 +25,6 @@ import org.hibernate.SessionFactory; import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,8 +41,7 @@ public class HibernateUtil { private static SessionFactory buildSessionFactory() { // configures settings from hibernate.cfg.xml - final StandardServiceRegistry registry = - new StandardServiceRegistryBuilder().configure().build(); + final var registry = new StandardServiceRegistryBuilder().configure().build(); try { return new MetadataSources(registry).buildMetadata().buildSessionFactory(); } catch (Exception ex) { diff --git a/cqrs/src/test/java/com/iluwatar/cqrs/IntegrationTest.java b/cqrs/src/test/java/com/iluwatar/cqrs/IntegrationTest.java index dd6babf00754..e0bb07fd1de6 100644 --- a/cqrs/src/test/java/com/iluwatar/cqrs/IntegrationTest.java +++ b/cqrs/src/test/java/com/iluwatar/cqrs/IntegrationTest.java @@ -23,33 +23,28 @@ package com.iluwatar.cqrs; -import java.math.BigInteger; -import java.util.List; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.iluwatar.cqrs.commandes.CommandServiceImpl; -import com.iluwatar.cqrs.commandes.ICommandService; import com.iluwatar.cqrs.dto.Author; import com.iluwatar.cqrs.dto.Book; import com.iluwatar.cqrs.queries.IQueryService; import com.iluwatar.cqrs.queries.QueryServiceImpl; +import java.math.BigInteger; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - /** * Integration test of IQueryService and ICommandService with h2 data - * */ public class IntegrationTest { private static IQueryService queryService; - private static ICommandService commandService; @BeforeAll public static void initializeAndPopulateDatabase() { - commandService = new CommandServiceImpl(); + var commandService = new CommandServiceImpl(); queryService = new QueryServiceImpl(); // create first author1 @@ -73,7 +68,7 @@ public static void initializeAndPopulateDatabase() { @Test public void testGetAuthorByUsername() { - Author author = queryService.getAuthorByUsername("username1"); + var author = queryService.getAuthorByUsername("username1"); assertEquals("username1", author.getUsername()); assertEquals("name1", author.getName()); assertEquals("email1", author.getEmail()); @@ -81,22 +76,22 @@ public void testGetAuthorByUsername() { @Test public void testGetUpdatedAuthorByUsername() { - Author author = queryService.getAuthorByUsername("new_username2"); - Author expectedAuthor = new Author("new_name2", "new_email2", "new_username2"); + var author = queryService.getAuthorByUsername("new_username2"); + var expectedAuthor = new Author("new_name2", "new_email2", "new_username2"); assertEquals(expectedAuthor, author); } @Test public void testGetBook() { - Book book = queryService.getBook("title1"); + var book = queryService.getBook("title1"); assertEquals("title1", book.getTitle()); assertEquals(10, book.getPrice(), 0.01); } @Test public void testGetAuthorBooks() { - List books = queryService.getAuthorBooks("username1"); + var books = queryService.getAuthorBooks("username1"); assertEquals(2, books.size()); assertTrue(books.contains(new Book("title1", 10))); assertTrue(books.contains(new Book("new_title2", 30))); @@ -104,13 +99,13 @@ public void testGetAuthorBooks() { @Test public void testGetAuthorBooksCount() { - BigInteger bookCount = queryService.getAuthorBooksCount("username1"); + var bookCount = queryService.getAuthorBooksCount("username1"); assertEquals(new BigInteger("2"), bookCount); } @Test public void testGetAuthorsCount() { - BigInteger authorCount = queryService.getAuthorsCount(); + var authorCount = queryService.getAuthorsCount(); assertEquals(new BigInteger("2"), authorCount); } diff --git a/dao/README.md b/dao/README.md index e1120fbf2af4..9065cb3eeb06 100644 --- a/dao/README.md +++ b/dao/README.md @@ -3,10 +3,9 @@ layout: pattern title: Data Access Object folder: dao permalink: /patterns/dao/ -categories: Persistence Tier +categories: Architectural tags: - - Java - - Difficulty-Beginner + - Data access --- ## Intent diff --git a/dao/src/main/java/com/iluwatar/dao/App.java b/dao/src/main/java/com/iluwatar/dao/App.java index 9faa8577a9ba..de9c7b7c1c10 100644 --- a/dao/src/main/java/com/iluwatar/dao/App.java +++ b/dao/src/main/java/com/iluwatar/dao/App.java @@ -23,11 +23,8 @@ package com.iluwatar.dao; -import java.sql.Connection; import java.sql.SQLException; -import java.sql.Statement; import java.util.List; -import java.util.stream.Stream; import javax.sql.DataSource; import org.h2.jdbcx.JdbcDataSource; import org.slf4j.Logger; @@ -57,32 +54,32 @@ public class App { * @throws Exception if any error occurs. */ public static void main(final String[] args) throws Exception { - final CustomerDao inMemoryDao = new InMemoryCustomerDao(); + final var inMemoryDao = new InMemoryCustomerDao(); performOperationsUsing(inMemoryDao); - final DataSource dataSource = createDataSource(); + final var dataSource = createDataSource(); createSchema(dataSource); - final CustomerDao dbDao = new DbCustomerDao(dataSource); + final var dbDao = new DbCustomerDao(dataSource); performOperationsUsing(dbDao); deleteSchema(dataSource); } private static void deleteSchema(DataSource dataSource) throws SQLException { - try (Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement()) { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { statement.execute(CustomerSchemaSql.DELETE_SCHEMA_SQL); } } private static void createSchema(DataSource dataSource) throws SQLException { - try (Connection connection = dataSource.getConnection(); - Statement statement = connection.createStatement()) { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { statement.execute(CustomerSchemaSql.CREATE_SCHEMA_SQL); } } private static DataSource createDataSource() { - JdbcDataSource dataSource = new JdbcDataSource(); + var dataSource = new JdbcDataSource(); dataSource.setURL(DB_URL); return dataSource; } @@ -90,18 +87,18 @@ private static DataSource createDataSource() { private static void performOperationsUsing(final CustomerDao customerDao) throws Exception { addCustomers(customerDao); log.info(ALL_CUSTOMERS); - try (Stream customerStream = customerDao.getAll()) { + try (var customerStream = customerDao.getAll()) { customerStream.forEach((customer) -> log.info(customer.toString())); } log.info("customerDao.getCustomerById(2): " + customerDao.getById(2)); - final Customer customer = new Customer(4, "Dan", "Danson"); + final var customer = new Customer(4, "Dan", "Danson"); customerDao.add(customer); log.info(ALL_CUSTOMERS + customerDao.getAll()); customer.setFirstName("Daniel"); customer.setLastName("Danielson"); customerDao.update(customer); log.info(ALL_CUSTOMERS); - try (Stream customerStream = customerDao.getAll()) { + try (var customerStream = customerDao.getAll()) { customerStream.forEach((cust) -> log.info(cust.toString())); } customerDao.delete(customer); @@ -109,7 +106,7 @@ private static void performOperationsUsing(final CustomerDao customerDao) throws } private static void addCustomers(CustomerDao customerDao) throws Exception { - for (Customer customer : generateSampleCustomers()) { + for (var customer : generateSampleCustomers()) { customerDao.add(customer); } } @@ -120,9 +117,9 @@ private static void addCustomers(CustomerDao customerDao) throws Exception { * @return list of customers. */ public static List generateSampleCustomers() { - final Customer customer1 = new Customer(1, "Adam", "Adamson"); - final Customer customer2 = new Customer(2, "Bob", "Bobson"); - final Customer customer3 = new Customer(3, "Carl", "Carlson"); + final var customer1 = new Customer(1, "Adam", "Adamson"); + final var customer2 = new Customer(2, "Bob", "Bobson"); + final var customer3 = new Customer(3, "Carl", "Carlson"); return List.of(customer1, customer2, customer3); } } diff --git a/dao/src/main/java/com/iluwatar/dao/Customer.java b/dao/src/main/java/com/iluwatar/dao/Customer.java index dd84426eb19e..43649989b53d 100644 --- a/dao/src/main/java/com/iluwatar/dao/Customer.java +++ b/dao/src/main/java/com/iluwatar/dao/Customer.java @@ -73,11 +73,11 @@ public String toString() { @Override public boolean equals(final Object that) { - boolean isEqual = false; + var isEqual = false; if (this == that) { isEqual = true; } else if (that != null && getClass() == that.getClass()) { - final Customer customer = (Customer) that; + final var customer = (Customer) that; if (getId() == customer.getId()) { isEqual = true; } diff --git a/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java b/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java index 689a889fda76..15f20eb43b30 100644 --- a/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java +++ b/dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java @@ -65,13 +65,10 @@ public DbCustomerDao(DataSource dataSource) { */ @Override public Stream getAll() throws Exception { - - Connection connection; try { - connection = getConnection(); - PreparedStatement statement = - connection.prepareStatement("SELECT * FROM CUSTOMERS"); // NOSONAR - ResultSet resultSet = statement.executeQuery(); // NOSONAR + var connection = getConnection(); + var statement = connection.prepareStatement("SELECT * FROM CUSTOMERS"); + var resultSet = statement.executeQuery(); // NOSONAR return StreamSupport.stream(new Spliterators.AbstractSpliterator(Long.MAX_VALUE, Spliterator.ORDERED) { @@ -121,9 +118,8 @@ public Optional getById(int id) throws Exception { ResultSet resultSet = null; - try (Connection connection = getConnection(); - PreparedStatement statement = - connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) { + try (var connection = getConnection(); + var statement = connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) { statement.setInt(1, id); resultSet = statement.executeQuery(); @@ -150,9 +146,8 @@ public boolean add(Customer customer) throws Exception { return false; } - try (Connection connection = getConnection(); - PreparedStatement statement = - connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) { + try (var connection = getConnection(); + var statement = connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) { statement.setInt(1, customer.getId()); statement.setString(2, customer.getFirstName()); statement.setString(3, customer.getLastName()); @@ -168,8 +163,8 @@ public boolean add(Customer customer) throws Exception { */ @Override public boolean update(Customer customer) throws Exception { - try (Connection connection = getConnection(); - PreparedStatement statement = + try (var connection = getConnection(); + var statement = connection .prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) { statement.setString(1, customer.getFirstName()); @@ -186,9 +181,8 @@ public boolean update(Customer customer) throws Exception { */ @Override public boolean delete(Customer customer) throws Exception { - try (Connection connection = getConnection(); - PreparedStatement statement = - connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) { + try (var connection = getConnection(); + var statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) { statement.setInt(1, customer.getId()); return statement.executeUpdate() > 0; } catch (SQLException ex) { diff --git a/dao/src/test/java/com/iluwatar/dao/AppTest.java b/dao/src/test/java/com/iluwatar/dao/AppTest.java index d15aceae246a..edfcf7cd05ba 100644 --- a/dao/src/test/java/com/iluwatar/dao/AppTest.java +++ b/dao/src/test/java/com/iluwatar/dao/AppTest.java @@ -31,7 +31,6 @@ public class AppTest { @Test public void test() throws Exception { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/dao/src/test/java/com/iluwatar/dao/CustomerTest.java b/dao/src/test/java/com/iluwatar/dao/CustomerTest.java index c27905353d47..479b619a3614 100644 --- a/dao/src/test/java/com/iluwatar/dao/CustomerTest.java +++ b/dao/src/test/java/com/iluwatar/dao/CustomerTest.java @@ -46,36 +46,36 @@ public void setUp() { @Test public void getAndSetId() { - final int newId = 2; + final var newId = 2; customer.setId(newId); assertEquals(newId, customer.getId()); } @Test public void getAndSetFirstname() { - final String newFirstname = "Bill"; + final var newFirstname = "Bill"; customer.setFirstName(newFirstname); assertEquals(newFirstname, customer.getFirstName()); } @Test public void getAndSetLastname() { - final String newLastname = "Clinton"; + final var newLastname = "Clinton"; customer.setLastName(newLastname); assertEquals(newLastname, customer.getLastName()); } @Test public void notEqualWithDifferentId() { - final int newId = 2; - final Customer otherCustomer = new Customer(newId, FIRSTNAME, LASTNAME); + final var newId = 2; + final var otherCustomer = new Customer(newId, FIRSTNAME, LASTNAME); assertNotEquals(customer, otherCustomer); assertNotEquals(customer.hashCode(), otherCustomer.hashCode()); } @Test public void equalsWithSameObjectValues() { - final Customer otherCustomer = new Customer(ID, FIRSTNAME, LASTNAME); + final var otherCustomer = new Customer(ID, FIRSTNAME, LASTNAME); assertEquals(customer, otherCustomer); assertEquals(customer.hashCode(), otherCustomer.hashCode()); } diff --git a/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java index b7c0e5508bdd..b7a0b9769a2f 100644 --- a/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java +++ b/dao/src/test/java/com/iluwatar/dao/DbCustomerDaoTest.java @@ -23,20 +23,6 @@ package com.iluwatar.dao; -import org.h2.jdbcx.JdbcDataSource; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.stream.Stream; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -46,6 +32,17 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import javax.sql.DataSource; +import org.h2.jdbcx.JdbcDataSource; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + /** * Tests {@link DbCustomerDao}. */ @@ -57,12 +54,13 @@ public class DbCustomerDaoTest { /** * Creates customers schema. + * * @throws SQLException if there is any error while creating schema. */ @BeforeEach public void createSchema() throws SQLException { - try (Connection connection = DriverManager.getConnection(DB_URL); - Statement statement = connection.createStatement()) { + try (var connection = DriverManager.getConnection(DB_URL); + var statement = connection.createStatement()) { statement.execute(CustomerSchemaSql.CREATE_SCHEMA_SQL); } } @@ -75,14 +73,15 @@ public class ConnectionSuccess { /** * Setup for connection success scenario. + * * @throws Exception if any error occurs. */ @BeforeEach public void setUp() throws Exception { - JdbcDataSource dataSource = new JdbcDataSource(); + var dataSource = new JdbcDataSource(); dataSource.setURL(DB_URL); dao = new DbCustomerDao(dataSource); - boolean result = dao.add(existingCustomer); + var result = dao.add(existingCustomer); assertTrue(result); } @@ -94,12 +93,12 @@ public class NonExistingCustomer { @Test public void addingShouldResultInSuccess() throws Exception { - try (Stream allCustomers = dao.getAll()) { + try (var allCustomers = dao.getAll()) { assumeTrue(allCustomers.count() == 1); } - final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund"); - boolean result = dao.add(nonExistingCustomer); + final var nonExistingCustomer = new Customer(2, "Robert", "Englund"); + var result = dao.add(nonExistingCustomer); assertTrue(result); assertCustomerCountIs(2); @@ -108,8 +107,8 @@ public void addingShouldResultInSuccess() throws Exception { @Test public void deletionShouldBeFailureAndNotAffectExistingCustomers() throws Exception { - final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund"); - boolean result = dao.delete(nonExistingCustomer); + final var nonExistingCustomer = new Customer(2, "Robert", "Englund"); + var result = dao.delete(nonExistingCustomer); assertFalse(result); assertCustomerCountIs(1); @@ -117,11 +116,11 @@ public void deletionShouldBeFailureAndNotAffectExistingCustomers() throws Except @Test public void updationShouldBeFailureAndNotAffectExistingCustomers() throws Exception { - final int nonExistingId = getNonExistingCustomerId(); - final String newFirstname = "Douglas"; - final String newLastname = "MacArthur"; - final Customer customer = new Customer(nonExistingId, newFirstname, newLastname); - boolean result = dao.update(customer); + final var nonExistingId = getNonExistingCustomerId(); + final var newFirstname = "Douglas"; + final var newLastname = "MacArthur"; + final var customer = new Customer(nonExistingId, newFirstname, newLastname); + var result = dao.update(customer); assertFalse(result); assertFalse(dao.getById(nonExistingId).isPresent()); @@ -136,16 +135,14 @@ public void retrieveShouldReturnNoCustomer() throws Exception { /** * Represents a scenario where DAO operations are being performed on an already existing * customer. - * */ @Nested public class ExistingCustomer { @Test public void addingShouldResultInFailureAndNotAffectExistingCustomers() throws Exception { - Customer existingCustomer = new Customer(1, "Freddy", "Krueger"); - - boolean result = dao.add(existingCustomer); + var existingCustomer = new Customer(1, "Freddy", "Krueger"); + var result = dao.add(existingCustomer); assertFalse(result); assertCustomerCountIs(1); @@ -154,7 +151,7 @@ public void addingShouldResultInFailureAndNotAffectExistingCustomers() throws Ex @Test public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() throws Exception { - boolean result = dao.delete(existingCustomer); + var result = dao.delete(existingCustomer); assertTrue(result); assertCustomerCountIs(0); @@ -162,15 +159,16 @@ public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() throws Exc } @Test - public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() throws Exception { - final String newFirstname = "Bernard"; - final String newLastname = "Montgomery"; - final Customer customer = new Customer(existingCustomer.getId(), newFirstname, newLastname); - boolean result = dao.update(customer); + public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() throws + Exception { + final var newFirstname = "Bernard"; + final var newLastname = "Montgomery"; + final var customer = new Customer(existingCustomer.getId(), newFirstname, newLastname); + var result = dao.update(customer); assertTrue(result); - final Customer cust = dao.getById(existingCustomer.getId()).get(); + final var cust = dao.getById(existingCustomer.getId()).get(); assertEquals(newFirstname, cust.getFirstName()); assertEquals(newLastname, cust.getLastName()); } @@ -178,28 +176,28 @@ public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdate } /** - * Represents a scenario where DB connectivity is not present due to network issue, or - * DB service unavailable. - * + * Represents a scenario where DB connectivity is not present due to network issue, or DB service + * unavailable. */ @Nested public class ConnectivityIssue { - + private static final String EXCEPTION_CAUSE = "Connection not available"; /** * setup a connection failure scenario. + * * @throws SQLException if any error occurs. */ @BeforeEach public void setUp() throws SQLException { dao = new DbCustomerDao(mockedDatasource()); } - + private DataSource mockedDatasource() throws SQLException { - DataSource mockedDataSource = mock(DataSource.class); - Connection mockedConnection = mock(Connection.class); - SQLException exception = new SQLException(EXCEPTION_CAUSE); + var mockedDataSource = mock(DataSource.class); + var mockedConnection = mock(Connection.class); + var exception = new SQLException(EXCEPTION_CAUSE); doThrow(exception).when(mockedConnection).prepareStatement(Mockito.anyString()); doReturn(mockedConnection).when(mockedDataSource).getConnection(); return mockedDataSource; @@ -211,30 +209,30 @@ public void addingACustomerFailsWithExceptionAsFeedbackToClient() { dao.add(new Customer(2, "Bernard", "Montgomery")); }); } - + @Test public void deletingACustomerFailsWithExceptionAsFeedbackToTheClient() { assertThrows(Exception.class, () -> { dao.delete(existingCustomer); }); } - + @Test public void updatingACustomerFailsWithFeedbackToTheClient() { - final String newFirstname = "Bernard"; - final String newLastname = "Montgomery"; + final var newFirstname = "Bernard"; + final var newLastname = "Montgomery"; assertThrows(Exception.class, () -> { dao.update(new Customer(existingCustomer.getId(), newFirstname, newLastname)); }); } - + @Test public void retrievingACustomerByIdFailsWithExceptionAsFeedbackToClient() { assertThrows(Exception.class, () -> { dao.getById(existingCustomer.getId()); }); } - + @Test public void retrievingAllCustomersFailsWithExceptionAsFeedbackToClient() { assertThrows(Exception.class, () -> { @@ -246,18 +244,19 @@ public void retrievingAllCustomersFailsWithExceptionAsFeedbackToClient() { /** * Delete customer schema for fresh setup per test. + * * @throws SQLException if any error occurs. */ @AfterEach public void deleteSchema() throws SQLException { - try (Connection connection = DriverManager.getConnection(DB_URL); - Statement statement = connection.createStatement()) { + try (var connection = DriverManager.getConnection(DB_URL); + var statement = connection.createStatement()) { statement.execute(CustomerSchemaSql.DELETE_SCHEMA_SQL); } } private void assertCustomerCountIs(int count) throws Exception { - try (Stream allCustomers = dao.getAll()) { + try (var allCustomers = dao.getAll()) { assertEquals(count, allCustomers.count()); } } @@ -265,7 +264,7 @@ private void assertCustomerCountIs(int count) throws Exception { /** * An arbitrary number which does not correspond to an active Customer id. - * + * * @return an int of a customer id which doesn't exist */ private int getNonExistingCustomerId() { diff --git a/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java b/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java index e863324376ea..64ce433df98e 100644 --- a/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java +++ b/dao/src/test/java/com/iluwatar/dao/InMemoryCustomerDaoTest.java @@ -23,18 +23,15 @@ package com.iluwatar.dao; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import java.util.Optional; -import java.util.stream.Stream; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + /** * Tests {@link InMemoryCustomerDao}. */ @@ -50,20 +47,20 @@ public void setUp() { } /** - * Represents the scenario when the DAO operations are being performed on a non existent - * customer. + * Represents the scenario when the DAO operations are being performed on a non existent + * customer. */ @Nested public class NonExistingCustomer { @Test public void addingShouldResultInSuccess() throws Exception { - try (Stream allCustomers = dao.getAll()) { + try (var allCustomers = dao.getAll()) { assumeTrue(allCustomers.count() == 1); } - final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund"); - boolean result = dao.add(nonExistingCustomer); + final var nonExistingCustomer = new Customer(2, "Robert", "Englund"); + var result = dao.add(nonExistingCustomer); assertTrue(result); assertCustomerCountIs(2); @@ -72,8 +69,8 @@ public void addingShouldResultInSuccess() throws Exception { @Test public void deletionShouldBeFailureAndNotAffectExistingCustomers() throws Exception { - final Customer nonExistingCustomer = new Customer(2, "Robert", "Englund"); - boolean result = dao.delete(nonExistingCustomer); + final var nonExistingCustomer = new Customer(2, "Robert", "Englund"); + var result = dao.delete(nonExistingCustomer); assertFalse(result); assertCustomerCountIs(1); @@ -81,11 +78,11 @@ public void deletionShouldBeFailureAndNotAffectExistingCustomers() throws Except @Test public void updationShouldBeFailureAndNotAffectExistingCustomers() throws Exception { - final int nonExistingId = getNonExistingCustomerId(); - final String newFirstname = "Douglas"; - final String newLastname = "MacArthur"; - final Customer customer = new Customer(nonExistingId, newFirstname, newLastname); - boolean result = dao.update(customer); + final var nonExistingId = getNonExistingCustomerId(); + final var newFirstname = "Douglas"; + final var newLastname = "MacArthur"; + final var customer = new Customer(nonExistingId, newFirstname, newLastname); + var result = dao.update(customer); assertFalse(result); assertFalse(dao.getById(nonExistingId).isPresent()); @@ -106,7 +103,7 @@ public class ExistingCustomer { @Test public void addingShouldResultInFailureAndNotAffectExistingCustomers() throws Exception { - boolean result = dao.add(CUSTOMER); + var result = dao.add(CUSTOMER); assertFalse(result); assertCustomerCountIs(1); @@ -115,7 +112,7 @@ public void addingShouldResultInFailureAndNotAffectExistingCustomers() throws Ex @Test public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() throws Exception { - boolean result = dao.delete(CUSTOMER); + var result = dao.delete(CUSTOMER); assertTrue(result); assertCustomerCountIs(0); @@ -123,23 +120,24 @@ public void deletionShouldBeSuccessAndCustomerShouldBeNonAccessible() throws Exc } @Test - public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() throws Exception { - final String newFirstname = "Bernard"; - final String newLastname = "Montgomery"; - final Customer customer = new Customer(CUSTOMER.getId(), newFirstname, newLastname); - boolean result = dao.update(customer); + public void updationShouldBeSuccessAndAccessingTheSameCustomerShouldReturnUpdatedInformation() throws + Exception { + final var newFirstname = "Bernard"; + final var newLastname = "Montgomery"; + final var customer = new Customer(CUSTOMER.getId(), newFirstname, newLastname); + var result = dao.update(customer); assertTrue(result); - final Customer cust = dao.getById(CUSTOMER.getId()).get(); + final var cust = dao.getById(CUSTOMER.getId()).get(); assertEquals(newFirstname, cust.getFirstName()); assertEquals(newLastname, cust.getLastName()); } - + @Test public void retriveShouldReturnTheCustomer() { - Optional optionalCustomer = dao.getById(CUSTOMER.getId()); - + var optionalCustomer = dao.getById(CUSTOMER.getId()); + assertTrue(optionalCustomer.isPresent()); assertEquals(CUSTOMER, optionalCustomer.get()); } @@ -147,15 +145,15 @@ public void retriveShouldReturnTheCustomer() { /** * An arbitrary number which does not correspond to an active Customer id. - * + * * @return an int of a customer id which doesn't exist */ private int getNonExistingCustomerId() { return 999; } - + private void assertCustomerCountIs(int count) throws Exception { - try (Stream allCustomers = dao.getAll()) { + try (var allCustomers = dao.getAll()) { assertEquals(count, allCustomers.count()); } } diff --git a/data-bus/README.md b/data-bus/README.md index 428c4db96f5b..cf54beb32525 100644 --- a/data-bus/README.md +++ b/data-bus/README.md @@ -6,8 +6,7 @@ permalink: /patterns/data-bus/ categories: Architectural tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Intent diff --git a/data-bus/src/main/java/com/iluwatar/databus/App.java b/data-bus/src/main/java/com/iluwatar/databus/App.java index da4c6f07e726..8f3b8cfbe32c 100644 --- a/data-bus/src/main/java/com/iluwatar/databus/App.java +++ b/data-bus/src/main/java/com/iluwatar/databus/App.java @@ -59,11 +59,11 @@ class App { public static void main(String[] args) { - final DataBus bus = DataBus.getInstance(); + final var bus = DataBus.getInstance(); bus.subscribe(new StatusMember(1)); bus.subscribe(new StatusMember(2)); - final MessageCollectorMember foo = new MessageCollectorMember("Foo"); - final MessageCollectorMember bar = new MessageCollectorMember("Bar"); + final var foo = new MessageCollectorMember("Foo"); + final var bar = new MessageCollectorMember("Bar"); bus.subscribe(foo); bus.publish(StartingData.of(LocalDateTime.now())); bus.publish(MessageData.of("Only Foo should see this")); diff --git a/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java b/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java index 332f6f935508..5a82182252a8 100644 --- a/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java +++ b/data-bus/src/main/java/com/iluwatar/databus/members/MessageCollectorMember.java @@ -27,7 +27,6 @@ import com.iluwatar.databus.Member; import com.iluwatar.databus.data.MessageData; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.logging.Logger; @@ -61,6 +60,6 @@ private void handleEvent(MessageData data) { } public List getMessages() { - return Collections.unmodifiableList(messages); + return List.copyOf(messages); } } diff --git a/data-bus/src/test/java/com/iluwatar/databus/DataBusTest.java b/data-bus/src/test/java/com/iluwatar/databus/DataBusTest.java index 829ff5107efc..a6491d5a7fb6 100644 --- a/data-bus/src/test/java/com/iluwatar/databus/DataBusTest.java +++ b/data-bus/src/test/java/com/iluwatar/databus/DataBusTest.java @@ -23,14 +23,14 @@ package com.iluwatar.databus; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.never; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import static org.mockito.BDDMockito.then; -import static org.mockito.Mockito.never; - /** * Tests for {@link DataBus}. * @@ -52,7 +52,7 @@ public void setUp() { @Test public void publishedEventIsReceivedBySubscribedMember() { //given - final DataBus dataBus = DataBus.getInstance(); + final var dataBus = DataBus.getInstance(); dataBus.subscribe(member); //when dataBus.publish(event); @@ -63,7 +63,7 @@ public void publishedEventIsReceivedBySubscribedMember() { @Test public void publishedEventIsNotReceivedByMemberAfterUnsubscribing() { //given - final DataBus dataBus = DataBus.getInstance(); + final var dataBus = DataBus.getInstance(); dataBus.subscribe(member); dataBus.unsubscribe(member); //when diff --git a/data-bus/src/test/java/com/iluwatar/databus/members/MessageCollectorMemberTest.java b/data-bus/src/test/java/com/iluwatar/databus/members/MessageCollectorMemberTest.java index b985a86bb40d..ebbdaea1ebc0 100644 --- a/data-bus/src/test/java/com/iluwatar/databus/members/MessageCollectorMemberTest.java +++ b/data-bus/src/test/java/com/iluwatar/databus/members/MessageCollectorMemberTest.java @@ -23,14 +23,13 @@ package com.iluwatar.databus.members; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.iluwatar.databus.data.MessageData; import com.iluwatar.databus.data.StartingData; -import org.junit.jupiter.api.Test; - import java.time.LocalDateTime; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * Tests for {@link MessageCollectorMember}. @@ -42,9 +41,9 @@ public class MessageCollectorMemberTest { @Test public void collectMessageFromMessageData() { //given - final String message = "message"; - final MessageData messageData = new MessageData(message); - final MessageCollectorMember collector = new MessageCollectorMember("collector"); + final var message = "message"; + final var messageData = new MessageData(message); + final var collector = new MessageCollectorMember("collector"); //when collector.accept(messageData); //then @@ -54,8 +53,8 @@ public void collectMessageFromMessageData() { @Test public void collectIgnoresMessageFromOtherDataTypes() { //given - final StartingData startingData = new StartingData(LocalDateTime.now()); - final MessageCollectorMember collector = new MessageCollectorMember("collector"); + final var startingData = new StartingData(LocalDateTime.now()); + final var collector = new MessageCollectorMember("collector"); //when collector.accept(startingData); //then diff --git a/data-bus/src/test/java/com/iluwatar/databus/members/StatusMemberTest.java b/data-bus/src/test/java/com/iluwatar/databus/members/StatusMemberTest.java index 20a2bc9b7dfa..c7b411c565a8 100644 --- a/data-bus/src/test/java/com/iluwatar/databus/members/StatusMemberTest.java +++ b/data-bus/src/test/java/com/iluwatar/databus/members/StatusMemberTest.java @@ -23,17 +23,16 @@ package com.iluwatar.databus.members; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + import com.iluwatar.databus.DataBus; import com.iluwatar.databus.data.MessageData; import com.iluwatar.databus.data.StartingData; import com.iluwatar.databus.data.StoppingData; -import org.junit.jupiter.api.Test; - import java.time.LocalDateTime; import java.time.Month; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; /** * Tests for {@link StatusMember}. @@ -45,9 +44,9 @@ public class StatusMemberTest { @Test public void statusRecordsTheStartTime() { //given - final LocalDateTime startTime = LocalDateTime.of(2017, Month.APRIL, 1, 19, 9); - final StartingData startingData = new StartingData(startTime); - final StatusMember statusMember = new StatusMember(1); + final var startTime = LocalDateTime.of(2017, Month.APRIL, 1, 19, 9); + final var startingData = new StartingData(startTime); + final var statusMember = new StatusMember(1); //when statusMember.accept(startingData); //then @@ -57,10 +56,10 @@ public void statusRecordsTheStartTime() { @Test public void statusRecordsTheStopTime() { //given - final LocalDateTime stop = LocalDateTime.of(2017, Month.APRIL, 1, 19, 12); - final StoppingData stoppingData = new StoppingData(stop); + final var stop = LocalDateTime.of(2017, Month.APRIL, 1, 19, 12); + final var stoppingData = new StoppingData(stop); stoppingData.setDataBus(DataBus.getInstance()); - final StatusMember statusMember = new StatusMember(1); + final var statusMember = new StatusMember(1); //when statusMember.accept(stoppingData); //then @@ -70,8 +69,8 @@ public void statusRecordsTheStopTime() { @Test public void statusIgnoresMessageData() { //given - final MessageData messageData = new MessageData("message"); - final StatusMember statusMember = new StatusMember(1); + final var messageData = new MessageData("message"); + final var statusMember = new StatusMember(1); //when statusMember.accept(messageData); //then diff --git a/data-locality/README.md b/data-locality/README.md index 8811e59acd7b..cabf7ab031ec 100644 --- a/data-locality/README.md +++ b/data-locality/README.md @@ -3,10 +3,9 @@ layout: pattern title: Data Locality folder: data-locality permalink: /patterns/data-locality/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Intermediate + - Game programming - Performance --- diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/Application.java b/data-locality/src/main/java/com/iluwatar/data/locality/Application.java index 064465fc7d00..463a02b784f1 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/Application.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/Application.java @@ -46,7 +46,7 @@ public class Application { */ public static void main(String[] args) { LOGGER.info("Start Game Application using Data-Locality pattern"); - GameEntity gameEntity = new GameEntity(NUM_ENTITIES); + var gameEntity = new GameEntity(NUM_ENTITIES); gameEntity.start(); gameEntity.update(); } diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java index 20fac010720a..616ebf8015b4 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/AiComponentManager.java @@ -25,6 +25,7 @@ import com.iluwatar.data.locality.game.component.AiComponent; import com.iluwatar.data.locality.game.component.Component; +import java.util.stream.IntStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,9 +51,7 @@ public AiComponentManager(int numEntities) { */ public void start() { LOGGER.info("Start AI Game Component"); - for (int i = 0; i < numEntities; i++) { - AI_COMPONENTS[i] = new AiComponent(); - } + IntStream.range(0, numEntities).forEach(i -> AI_COMPONENTS[i] = new AiComponent()); } /** @@ -60,10 +59,8 @@ public void start() { */ public void update() { LOGGER.info("Update AI Game Component"); - for (int i = 0; i < numEntities; i++) { - if (AI_COMPONENTS.length > i && AI_COMPONENTS[i] != null) { - AI_COMPONENTS[i].update(); - } - } + IntStream.range(0, numEntities) + .filter(i -> AI_COMPONENTS.length > i && AI_COMPONENTS[i] != null) + .forEach(i -> AI_COMPONENTS[i].update()); } } diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java index 36f762587984..61ba4ebddca8 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/PhysicsComponentManager.java @@ -25,6 +25,7 @@ import com.iluwatar.data.locality.game.component.Component; import com.iluwatar.data.locality.game.component.PhysicsComponent; +import java.util.stream.IntStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,9 +51,7 @@ public PhysicsComponentManager(int numEntities) { */ public void start() { LOGGER.info("Start Physics Game Component "); - for (int i = 0; i < numEntities; i++) { - PHYSICS_COMPONENTS[i] = new PhysicsComponent(); - } + IntStream.range(0, numEntities).forEach(i -> PHYSICS_COMPONENTS[i] = new PhysicsComponent()); } @@ -62,10 +61,8 @@ public void start() { public void update() { LOGGER.info("Update Physics Game Component "); // Process physics. - for (int i = 0; i < numEntities; i++) { - if (PHYSICS_COMPONENTS.length > i && PHYSICS_COMPONENTS[i] != null) { - PHYSICS_COMPONENTS[i].update(); - } - } + IntStream.range(0, numEntities) + .filter(i -> PHYSICS_COMPONENTS.length > i && PHYSICS_COMPONENTS[i] != null) + .forEach(i -> PHYSICS_COMPONENTS[i].update()); } } diff --git a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java index fd6ef9640154..f8c4b3522321 100644 --- a/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java +++ b/data-locality/src/main/java/com/iluwatar/data/locality/game/component/manager/RenderComponentManager.java @@ -25,6 +25,7 @@ import com.iluwatar.data.locality.game.component.Component; import com.iluwatar.data.locality.game.component.RenderComponent; +import java.util.stream.IntStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,9 +51,7 @@ public RenderComponentManager(int numEntities) { */ public void start() { LOGGER.info("Start Render Game Component "); - for (int i = 0; i < numEntities; i++) { - RENDER_COMPONENTS[i] = new RenderComponent(); - } + IntStream.range(0, numEntities).forEach(i -> RENDER_COMPONENTS[i] = new RenderComponent()); } @@ -62,10 +61,8 @@ public void start() { public void render() { LOGGER.info("Update Render Game Component "); // Process Render. - for (int i = 0; i < numEntities; i++) { - if (RENDER_COMPONENTS.length > i && RENDER_COMPONENTS[i] != null) { - RENDER_COMPONENTS[i].render(); - } - } + IntStream.range(0, numEntities) + .filter(i -> RENDER_COMPONENTS.length > i && RENDER_COMPONENTS[i] != null) + .forEach(i -> RENDER_COMPONENTS[i].render()); } } diff --git a/data-mapper/README.md b/data-mapper/README.md index f23d5a62ac8e..fe0af92365ec 100644 --- a/data-mapper/README.md +++ b/data-mapper/README.md @@ -3,10 +3,9 @@ layout: pattern title: Data Mapper folder: data-mapper permalink: /patterns/data-mapper/ -categories: Persistence Tier +categories: Architectural tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java index 49d6c63d39df..9bfc329523d1 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/App.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/App.java @@ -23,7 +23,6 @@ package com.iluwatar.datamapper; -import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,10 +50,10 @@ public final class App { public static void main(final String... args) { /* Create new data mapper for type 'first' */ - final StudentDataMapper mapper = new StudentDataMapperImpl(); + final var mapper = new StudentDataMapperImpl(); /* Create new student */ - Student student = new Student(1, "Adam", 'A'); + var student = new Student(1, "Adam", 'A'); /* Add student in respectibe store */ mapper.insert(student); @@ -62,7 +61,7 @@ public static void main(final String... args) { log.debug(STUDENT_STRING + student + ", is inserted"); /* Find this student */ - final Optional studentToBeFound = mapper.find(student.getStudentId()); + final var studentToBeFound = mapper.find(student.getStudentId()); log.debug(STUDENT_STRING + studentToBeFound + ", is searched"); diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java b/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java index 5a368f9ce768..25075b1e00f6 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/Student.java @@ -85,7 +85,7 @@ public boolean equals(final Object inputObject) { isEqual = true; } else if (inputObject != null && getClass() == inputObject.getClass()) { - final Student inputStudent = (Student) inputObject; + final var inputStudent = (Student) inputObject; /* If student id matched */ if (this.getStudentId() == inputStudent.getStudentId()) { diff --git a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java index cc92ab81e7f9..85ad4aa8d233 100644 --- a/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java +++ b/data-mapper/src/main/java/com/iluwatar/datamapper/StudentDataMapperImpl.java @@ -37,71 +37,36 @@ public final class StudentDataMapperImpl implements StudentDataMapper { @Override public Optional find(int studentId) { - - /* Compare with existing students */ - for (final Student student : this.getStudents()) { - - /* Check if student is found */ - if (student.getStudentId() == studentId) { - - return Optional.of(student); - } - } - - /* Return empty value */ - return Optional.empty(); + return this.getStudents().stream().filter(x -> x.getStudentId() == studentId).findFirst(); } @Override public void update(Student studentToBeUpdated) throws DataMapperException { - - - /* Check with existing students */ - if (this.getStudents().contains(studentToBeUpdated)) { - - /* Get the index of student in list */ - final int index = this.getStudents().indexOf(studentToBeUpdated); - - /* Update the student in list */ - this.getStudents().set(index, studentToBeUpdated); - - } else { - - /* Throw user error after wrapping in a runtime exception */ - throw new DataMapperException("Student [" + studentToBeUpdated.getName() + "] is not found"); - } + String name = studentToBeUpdated.getName(); + Integer index = Optional.of(studentToBeUpdated) + .map(Student::getStudentId) + .flatMap(this::find) + .map(students::indexOf) + .orElseThrow(() -> new DataMapperException("Student [" + name + "] is not found")); + students.set(index, studentToBeUpdated); } @Override public void insert(Student studentToBeInserted) throws DataMapperException { - - /* Check with existing students */ - if (!this.getStudents().contains(studentToBeInserted)) { - - /* Add student in list */ - this.getStudents().add(studentToBeInserted); - - } else { - - /* Throw user error after wrapping in a runtime exception */ - throw new DataMapperException("Student already [" + studentToBeInserted - .getName() + "] exists"); + Optional student = find(studentToBeInserted.getStudentId()); + if (student.isPresent()) { + String name = studentToBeInserted.getName(); + throw new DataMapperException("Student already [" + name + "] exists"); } + + students.add(studentToBeInserted); } @Override public void delete(Student studentToBeDeleted) throws DataMapperException { - - /* Check with existing students */ - if (this.getStudents().contains(studentToBeDeleted)) { - - /* Delete the student from list */ - this.getStudents().remove(studentToBeDeleted); - - } else { - - /* Throw user error after wrapping in a runtime exception */ - throw new DataMapperException("Student [" + studentToBeDeleted.getName() + "] is not found"); + if (!students.remove(studentToBeDeleted)) { + String name = studentToBeDeleted.getName(); + throw new DataMapperException("Student [" + name + "] is not found"); } } diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java index bf99bcaa7fe3..ec1d71be4245 100644 --- a/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java +++ b/data-mapper/src/test/java/com/iluwatar/datamapper/AppTest.java @@ -32,7 +32,6 @@ public final class AppTest { @Test public void test() { - final String[] args = {}; - App.main(args); + App.main(); } } diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java index dc0217bdf63d..717e4fe909cb 100644 --- a/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java +++ b/data-mapper/src/test/java/com/iluwatar/datamapper/DataMapperTest.java @@ -23,11 +23,11 @@ package com.iluwatar.datamapper; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import org.junit.jupiter.api.Test; + /** * The Data Mapper (DM) is a layer of software that separates the in-memory objects from the * database. Its responsibility is to transfer data between the two and also to isolate them from @@ -46,11 +46,11 @@ public class DataMapperTest { public void testFirstDataMapper() { /* Create new data mapper of first type */ - final StudentDataMapper mapper = new StudentDataMapperImpl(); + final var mapper = new StudentDataMapperImpl(); /* Create new student */ - int studentId = 1; - Student student = new Student(studentId, "Adam", 'A'); + var studentId = 1; + var student = new Student(studentId, "Adam", 'A'); /* Add student in respectibe db */ mapper.insert(student); @@ -59,7 +59,7 @@ public void testFirstDataMapper() { assertEquals(studentId, mapper.find(student.getStudentId()).get().getStudentId()); /* Update existing student object */ - String updatedName = "AdamUpdated"; + var updatedName = "AdamUpdated"; student = new Student(student.getStudentId(), updatedName, 'A'); /* Update student in respectibe db */ diff --git a/data-mapper/src/test/java/com/iluwatar/datamapper/StudentTest.java b/data-mapper/src/test/java/com/iluwatar/datamapper/StudentTest.java index 5d2316424104..2ea7a3daa41f 100644 --- a/data-mapper/src/test/java/com/iluwatar/datamapper/StudentTest.java +++ b/data-mapper/src/test/java/com/iluwatar/datamapper/StudentTest.java @@ -23,12 +23,10 @@ package com.iluwatar.datamapper; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; /** * Tests {@link Student}. @@ -36,8 +34,8 @@ public final class StudentTest { /** - * This API tests the equality behaviour of Student object - * Object Equality should work as per logic defined in equals method + * This API tests the equality behaviour of Student object Object Equality should work as per + * logic defined in equals method * * @throws Exception if any execution error during test */ @@ -45,9 +43,9 @@ public final class StudentTest { public void testEquality() throws Exception { /* Create some students */ - final Student firstStudent = new Student(1, "Adam", 'A'); - final Student secondStudent = new Student(2, "Donald", 'B'); - final Student secondSameStudent = new Student(2, "Donald", 'B'); + final var firstStudent = new Student(1, "Adam", 'A'); + final var secondStudent = new Student(2, "Donald", 'B'); + final var secondSameStudent = new Student(2, "Donald", 'B'); /* Check equals functionality: should return 'true' */ assertEquals(firstStudent, firstStudent); diff --git a/data-transfer-object/README.md b/data-transfer-object/README.md index c023795273cc..f269fc66bcf0 100644 --- a/data-transfer-object/README.md +++ b/data-transfer-object/README.md @@ -5,10 +5,7 @@ folder: data-transfer-object permalink: /patterns/data-transfer-object/ categories: Architectural tags: - - Java - - KISS - - YAGNI - - Difficulty-Beginner + - Performance --- ## Intent diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java index 860faf478da0..ebc44dc573e6 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java @@ -48,16 +48,14 @@ public class CustomerClientApp { * @param args program argument. */ public static void main(String[] args) { - List customers = new ArrayList<>(); - CustomerDto customerOne = new CustomerDto("1", "Kelly", "Brown"); - CustomerDto customerTwo = new CustomerDto("2", "Alfonso", "Bass"); - customers.add(customerOne); - customers.add(customerTwo); + var customerOne = new CustomerDto("1", "Kelly", "Brown"); + var customerTwo = new CustomerDto("2", "Alfonso", "Bass"); + var customers = new ArrayList<>(List.of(customerOne, customerTwo)); - CustomerResource customerResource = new CustomerResource(customers); + var customerResource = new CustomerResource(customers); LOGGER.info("All customers:-"); - List allCustomers = customerResource.getAllCustomers(); + var allCustomers = customerResource.getAllCustomers(); printCustomerDetails(allCustomers); LOGGER.info("----------------------------------------------------------"); @@ -70,7 +68,7 @@ public static void main(String[] args) { LOGGER.info("----------------------------------------------------------"); LOGGER.info("Adding customer three}"); - CustomerDto customerThree = new CustomerDto("3", "Lynda", "Blair"); + var customerThree = new CustomerDto("3", "Lynda", "Blair"); customerResource.save(customerThree); allCustomers = customerResource.getAllCustomers(); printCustomerDetails(allCustomers); diff --git a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java index 339c666b7b6b..7765fd5bf4d7 100644 --- a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java +++ b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java @@ -23,13 +23,12 @@ package com.iluwatar.datatransfer; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * tests {@link CustomerResource}. @@ -37,13 +36,9 @@ public class CustomerResourceTest { @Test public void shouldGetAllCustomers() { - CustomerDto customer = new CustomerDto("1", "Melody", "Yates"); - List customers = new ArrayList<>(); - customers.add(customer); - - CustomerResource customerResource = new CustomerResource(customers); - - List allCustomers = customerResource.getAllCustomers(); + var customers = List.of(new CustomerDto("1", "Melody", "Yates")); + var customerResource = new CustomerResource(customers); + var allCustomers = customerResource.getAllCustomers(); assertEquals(1, allCustomers.size()); assertEquals("1", allCustomers.get(0).getId()); @@ -53,12 +48,12 @@ public void shouldGetAllCustomers() { @Test public void shouldSaveCustomer() { - CustomerDto customer = new CustomerDto("1", "Rita", "Reynolds"); - CustomerResource customerResource = new CustomerResource(new ArrayList<>()); + var customer = new CustomerDto("1", "Rita", "Reynolds"); + var customerResource = new CustomerResource(new ArrayList<>()); customerResource.save(customer); - List allCustomers = customerResource.getAllCustomers(); + var allCustomers = customerResource.getAllCustomers(); assertEquals("1", allCustomers.get(0).getId()); assertEquals("Rita", allCustomers.get(0).getFirstName()); assertEquals("Reynolds", allCustomers.get(0).getLastName()); @@ -66,15 +61,13 @@ public void shouldSaveCustomer() { @Test public void shouldDeleteCustomer() { - CustomerDto customer = new CustomerDto("1", "Terry", "Nguyen"); - List customers = new ArrayList<>(); - customers.add(customer); - - CustomerResource customerResource = new CustomerResource(customers); + var customer = new CustomerDto("1", "Terry", "Nguyen"); + var customers = new ArrayList<>(List.of(customer)); + var customerResource = new CustomerResource(customers); customerResource.delete(customer.getId()); - List allCustomers = customerResource.getAllCustomers(); + var allCustomers = customerResource.getAllCustomers(); assertTrue(allCustomers.isEmpty()); } diff --git a/decorator/README.md b/decorator/README.md index 6adb5d057639..99f225a4c011 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -5,9 +5,8 @@ folder: decorator permalink: /patterns/decorator/ categories: Structural tags: - - Java - Gang Of Four - - Difficulty-Beginner + - Extensibility --- ## Also known as @@ -99,12 +98,12 @@ Here's the troll in action ```java // simple troll -Troll troll = new SimpleTroll(); +var troll = new SimpleTroll(); troll.attack(); // The troll tries to grab you! troll.fleeBattle(); // The troll shrieks in horror and runs away! // change the behavior of the simple troll by adding a decorator -Troll clubbedTroll = new ClubbedTroll(troll); +var clubbedTroll = new ClubbedTroll(troll); clubbedTroll.attack(); // The troll tries to grab you! The troll swings at you with a club! clubbedTroll.fleeBattle(); // The troll shrieks in horror and runs away! ``` diff --git a/decorator/src/main/java/com/iluwatar/decorator/App.java b/decorator/src/main/java/com/iluwatar/decorator/App.java index 9d28bd10876f..25d03e4c8cc3 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/App.java +++ b/decorator/src/main/java/com/iluwatar/decorator/App.java @@ -49,14 +49,14 @@ public static void main(String[] args) { // simple troll LOGGER.info("A simple looking troll approaches."); - Troll troll = new SimpleTroll(); + var troll = new SimpleTroll(); troll.attack(); troll.fleeBattle(); LOGGER.info("Simple troll power {}.\n", troll.getAttackPower()); // change the behavior of the simple troll by adding a decorator LOGGER.info("A troll with huge club surprises you."); - Troll clubbedTroll = new ClubbedTroll(troll); + var clubbedTroll = new ClubbedTroll(troll); clubbedTroll.attack(); clubbedTroll.fleeBattle(); LOGGER.info("Clubbed troll power {}.\n", clubbedTroll.getAttackPower()); diff --git a/decorator/src/test/java/com/iluwatar/decorator/AppTest.java b/decorator/src/test/java/com/iluwatar/decorator/AppTest.java index c55e1f998525..e8d4c8505d5c 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/AppTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/AppTest.java @@ -26,15 +26,12 @@ import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java index 1d624740850a..28970db1b105 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java @@ -23,14 +23,14 @@ package com.iluwatar.decorator; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.internal.verification.VerificationModeFactory.times; +import org.junit.jupiter.api.Test; + /** * Tests for {@link ClubbedTroll} */ @@ -39,10 +39,10 @@ public class ClubbedTrollTest { @Test public void testClubbedTroll() { // Create a normal troll first, but make sure we can spy on it later on. - final Troll simpleTroll = spy(new SimpleTroll()); + final var simpleTroll = spy(new SimpleTroll()); // Now we want to decorate the troll to make it stronger ... - final Troll clubbed = new ClubbedTroll(simpleTroll); + final var clubbed = new ClubbedTroll(simpleTroll); assertEquals(20, clubbed.getAttackPower()); verify(simpleTroll, times(1)).getAttackPower(); diff --git a/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java index 30261e0214f4..c9f62407c913 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java @@ -23,19 +23,18 @@ package com.iluwatar.decorator; +import static org.junit.jupiter.api.Assertions.assertEquals; + import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.AppenderBase; +import java.util.LinkedList; +import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.slf4j.LoggerFactory; -import java.util.LinkedList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * Tests for {@link SimpleTroll} */ @@ -55,7 +54,7 @@ public void tearDown() { @Test public void testTrollActions() { - final SimpleTroll troll = new SimpleTroll(); + final var troll = new SimpleTroll(); assertEquals(10, troll.getAttackPower()); troll.attack(); diff --git a/delegation/README.md b/delegation/README.md index b18c6f7f3470..25bd16dc2d51 100644 --- a/delegation/README.md +++ b/delegation/README.md @@ -3,10 +3,9 @@ layout: pattern title: Delegation folder: delegation permalink: /patterns/delegation/ -categories: Behavioral +categories: Structural tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Also known as diff --git a/delegation/src/main/java/com/iluwatar/delegation/simple/App.java b/delegation/src/main/java/com/iluwatar/delegation/simple/App.java index b568c836f668..9b9f1284ea95 100644 --- a/delegation/src/main/java/com/iluwatar/delegation/simple/App.java +++ b/delegation/src/main/java/com/iluwatar/delegation/simple/App.java @@ -51,9 +51,9 @@ public class App { * @param args command line args */ public static void main(String[] args) { - PrinterController hpPrinterController = new PrinterController(new HpPrinter()); - PrinterController canonPrinterController = new PrinterController(new CanonPrinter()); - PrinterController epsonPrinterController = new PrinterController(new EpsonPrinter()); + var hpPrinterController = new PrinterController(new HpPrinter()); + var canonPrinterController = new PrinterController(new CanonPrinter()); + var epsonPrinterController = new PrinterController(new EpsonPrinter()); hpPrinterController.print(MESSAGE_TO_PRINT); canonPrinterController.print(MESSAGE_TO_PRINT); diff --git a/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java b/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java index 21040577e9ba..2865c76c1e78 100644 --- a/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java +++ b/delegation/src/test/java/com/iluwatar/delegation/simple/AppTest.java @@ -32,8 +32,7 @@ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java b/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java index 4c924a794f02..2da1e05713eb 100644 --- a/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java +++ b/delegation/src/test/java/com/iluwatar/delegation/simple/DelegateTest.java @@ -23,22 +23,21 @@ package com.iluwatar.delegation.simple; +import static org.junit.jupiter.api.Assertions.assertEquals; + import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.AppenderBase; import com.iluwatar.delegation.simple.printers.CanonPrinter; import com.iluwatar.delegation.simple.printers.EpsonPrinter; import com.iluwatar.delegation.simple.printers.HpPrinter; +import java.util.LinkedList; +import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.slf4j.LoggerFactory; -import java.util.LinkedList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * Test for Delegation Pattern */ @@ -60,7 +59,7 @@ public void tearDown() { @Test public void testCanonPrinter() throws Exception { - PrinterController printerController = new PrinterController(new CanonPrinter()); + var printerController = new PrinterController(new CanonPrinter()); printerController.print(MESSAGE); assertEquals("Canon Printer : Test Message Printed", appender.getLastMessage()); @@ -68,7 +67,7 @@ public void testCanonPrinter() throws Exception { @Test public void testHpPrinter() throws Exception { - PrinterController printerController = new PrinterController(new HpPrinter()); + var printerController = new PrinterController(new HpPrinter()); printerController.print(MESSAGE); assertEquals("HP Printer : Test Message Printed", appender.getLastMessage()); @@ -76,7 +75,7 @@ public void testHpPrinter() throws Exception { @Test public void testEpsonPrinter() throws Exception { - PrinterController printerController = new PrinterController(new EpsonPrinter()); + var printerController = new PrinterController(new EpsonPrinter()); printerController.print(MESSAGE); assertEquals("Epson Printer : Test Message Printed", appender.getLastMessage()); diff --git a/dependency-injection/README.md b/dependency-injection/README.md index ba81dc7034c5..90edd4061bae 100644 --- a/dependency-injection/README.md +++ b/dependency-injection/README.md @@ -3,10 +3,9 @@ layout: pattern title: Dependency Injection folder: dependency-injection permalink: /patterns/dependency-injection/ -categories: Behavioral +categories: Creational tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent diff --git a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/App.java b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/App.java index 79c6400b12f9..6762cbbc7b9d 100644 --- a/dependency-injection/src/main/java/com/iluwatar/dependency/injection/App.java +++ b/dependency-injection/src/main/java/com/iluwatar/dependency/injection/App.java @@ -24,7 +24,6 @@ package com.iluwatar.dependency.injection; import com.google.inject.Guice; -import com.google.inject.Injector; /** * Dependency Injection pattern deals with how objects handle their dependencies. The pattern @@ -55,18 +54,18 @@ public class App { * @param args command line args */ public static void main(String[] args) { - SimpleWizard simpleWizard = new SimpleWizard(); + var simpleWizard = new SimpleWizard(); simpleWizard.smoke(); - AdvancedWizard advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco()); + var advancedWizard = new AdvancedWizard(new SecondBreakfastTobacco()); advancedWizard.smoke(); - AdvancedSorceress advancedSorceress = new AdvancedSorceress(); + var advancedSorceress = new AdvancedSorceress(); advancedSorceress.setTobacco(new SecondBreakfastTobacco()); advancedSorceress.smoke(); - Injector injector = Guice.createInjector(new TobaccoModule()); - GuiceWizard guiceWizard = injector.getInstance(GuiceWizard.class); + var injector = Guice.createInjector(new TobaccoModule()); + var guiceWizard = injector.getInstance(GuiceWizard.class); guiceWizard.smoke(); } } diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedSorceressTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedSorceressTest.java index 46380352761f..701cc1754dad 100644 --- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedSorceressTest.java +++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedSorceressTest.java @@ -23,13 +23,14 @@ package com.iluwatar.dependency.injection; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.iluwatar.dependency.injection.utils.InMemoryAppender; +import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * Date: 28/04/17 - 7:40 AM @@ -52,27 +53,29 @@ public void tearDown() { } /** - * Test if the {@link AdvancedSorceress} smokes whatever instance of {@link Tobacco} is passed to her - * through the setter's parameter + * Test if the {@link AdvancedSorceress} smokes whatever instance of {@link Tobacco} is passed to + * her through the setter's parameter */ @Test public void testSmokeEveryThing() throws Exception { - final Tobacco[] tobaccos = { - new OldTobyTobacco(), new RivendellTobacco(), new SecondBreakfastTobacco() - }; + List tobaccos = List.of( + new OldTobyTobacco(), + new RivendellTobacco(), + new SecondBreakfastTobacco() + ); - for (final Tobacco tobacco : tobaccos) { - final AdvancedSorceress advancedSorceress = new AdvancedSorceress(); + // Verify if the sorceress is smoking the correct tobacco ... + tobaccos.forEach(tobacco -> { + final var advancedSorceress = new AdvancedSorceress(); advancedSorceress.setTobacco(tobacco); advancedSorceress.smoke(); - // Verify if the sorceress is smoking the correct tobacco ... - assertEquals("AdvancedSorceress smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage()); - - } + String lastMessage = appender.getLastMessage(); + assertEquals("AdvancedSorceress smoking " + tobacco.getClass().getSimpleName(), lastMessage); + }); // ... and nothing else is happening. - assertEquals(tobaccos.length, appender.getLogSize()); + assertEquals(tobaccos.size(), appender.getLogSize()); } } diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedWizardTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedWizardTest.java index 391f851c809e..b076e87c0256 100644 --- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedWizardTest.java +++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AdvancedWizardTest.java @@ -23,13 +23,14 @@ package com.iluwatar.dependency.injection; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.iluwatar.dependency.injection.utils.InMemoryAppender; +import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * Date: 12/10/15 - 8:40 PM @@ -57,21 +58,22 @@ public void tearDown() { @Test public void testSmokeEveryThing() throws Exception { - final Tobacco[] tobaccos = { - new OldTobyTobacco(), new RivendellTobacco(), new SecondBreakfastTobacco() - }; + List tobaccos = List.of( + new OldTobyTobacco(), + new RivendellTobacco(), + new SecondBreakfastTobacco() + ); - for (final Tobacco tobacco : tobaccos) { + // Verify if the wizard is smoking the correct tobacco ... + tobaccos.forEach(tobacco -> { final AdvancedWizard advancedWizard = new AdvancedWizard(tobacco); advancedWizard.smoke(); - - // Verify if the wizard is smoking the correct tobacco ... - assertEquals("AdvancedWizard smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage()); - - } + String lastMessage = appender.getLastMessage(); + assertEquals("AdvancedWizard smoking " + tobacco.getClass().getSimpleName(), lastMessage); + }); // ... and nothing else is happening. - assertEquals(tobaccos.length, appender.getLogSize()); + assertEquals(tobaccos.size(), appender.getLogSize()); } diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java index cd68ba4e4196..51115496d54e 100644 --- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java +++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/AppTest.java @@ -26,15 +26,12 @@ import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/GuiceWizardTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/GuiceWizardTest.java index 674c0decef04..1e31a5316ff7 100644 --- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/GuiceWizardTest.java +++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/GuiceWizardTest.java @@ -23,16 +23,16 @@ package com.iluwatar.dependency.injection; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.google.inject.AbstractModule; import com.google.inject.Guice; -import com.google.inject.Injector; import com.iluwatar.dependency.injection.utils.InMemoryAppender; +import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * Date: 12/10/15 - 8:57 PM * @@ -59,20 +59,22 @@ public void tearDown() { @Test public void testSmokeEveryThingThroughConstructor() throws Exception { - final Tobacco[] tobaccos = { - new OldTobyTobacco(), new RivendellTobacco(), new SecondBreakfastTobacco() - }; + List tobaccos = List.of( + new OldTobyTobacco(), + new RivendellTobacco(), + new SecondBreakfastTobacco() + ); - for (final Tobacco tobacco : tobaccos) { + // Verify if the wizard is smoking the correct tobacco ... + tobaccos.forEach(tobacco -> { final GuiceWizard guiceWizard = new GuiceWizard(tobacco); guiceWizard.smoke(); - - // Verify if the wizard is smoking the correct tobacco ... - assertEquals("GuiceWizard smoking " + tobacco.getClass().getSimpleName(), appender.getLastMessage()); - } + String lastMessage = appender.getLastMessage(); + assertEquals("GuiceWizard smoking " + tobacco.getClass().getSimpleName(), lastMessage); + }); // ... and nothing else is happening. - assertEquals(tobaccos.length, appender.getLogSize()); + assertEquals(tobaccos.size(), appender.getLogSize()); } /** @@ -82,30 +84,30 @@ public void testSmokeEveryThingThroughConstructor() throws Exception { @Test public void testSmokeEveryThingThroughInjectionFramework() throws Exception { - @SuppressWarnings("unchecked") - final Class[] tobaccos = new Class[]{ - OldTobyTobacco.class, RivendellTobacco.class, SecondBreakfastTobacco.class - }; - - for (final Class tobaccoClass : tobaccos) { - // Configure the tobacco in the injection framework ... - final Injector injector = Guice.createInjector(new AbstractModule() { + List> tobaccos = List.of( + OldTobyTobacco.class, + RivendellTobacco.class, + SecondBreakfastTobacco.class + ); + + // Configure the tobacco in the injection framework ... + // ... and create a new wizard with it + // Verify if the wizard is smoking the correct tobacco ... + tobaccos.forEach(tobaccoClass -> { + final var injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { bind(Tobacco.class).to(tobaccoClass); } }); - - // ... and create a new wizard with it - final GuiceWizard guiceWizard = injector.getInstance(GuiceWizard.class); + final var guiceWizard = injector.getInstance(GuiceWizard.class); guiceWizard.smoke(); - - // Verify if the wizard is smoking the correct tobacco ... - assertEquals("GuiceWizard smoking " + tobaccoClass.getSimpleName(), appender.getLastMessage()); - } + String lastMessage = appender.getLastMessage(); + assertEquals("GuiceWizard smoking " + tobaccoClass.getSimpleName(), lastMessage); + }); // ... and nothing else is happening. - assertEquals(tobaccos.length, appender.getLogSize()); + assertEquals(tobaccos.size(), appender.getLogSize()); } } diff --git a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/SimpleWizardTest.java b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/SimpleWizardTest.java index a8a584ec0115..7b11469c37c1 100644 --- a/dependency-injection/src/test/java/com/iluwatar/dependency/injection/SimpleWizardTest.java +++ b/dependency-injection/src/test/java/com/iluwatar/dependency/injection/SimpleWizardTest.java @@ -23,13 +23,13 @@ package com.iluwatar.dependency.injection; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.iluwatar.dependency.injection.utils.InMemoryAppender; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; - /** * Date: 12/10/15 - 8:26 PM * @@ -55,7 +55,7 @@ public void tearDown() { */ @Test public void testSmoke() { - final SimpleWizard simpleWizard = new SimpleWizard(); + final var simpleWizard = new SimpleWizard(); simpleWizard.smoke(); assertEquals("SimpleWizard smoking OldTobyTobacco", appender.getLastMessage()); assertEquals(1, appender.getLogSize()); diff --git a/dirty-flag/README.md b/dirty-flag/README.md index 885c7f03b5f5..31cfbae1ff40 100644 --- a/dirty-flag/README.md +++ b/dirty-flag/README.md @@ -3,10 +3,9 @@ layout: pattern title: Dirty Flag folder: dirty-flag permalink: /patterns/dirty-flag/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Game programming - Performance --- diff --git a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java index cc9a6940692a..9408904cf7af 100644 --- a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java +++ b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/App.java @@ -23,9 +23,7 @@ package com.iluwatar.dirtyflag; -import java.util.List; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,18 +59,15 @@ public class App { * Program execution point. */ public void run() { - - final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + final var executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleAtFixedRate(new Runnable() { final World world = new World(); @Override public void run() { - List countries = world.fetch(); + var countries = world.fetch(); LOGGER.info("Our world currently has the following countries:-"); - for (String country : countries) { - LOGGER.info("\t" + country); - } + countries.stream().map(country -> "\t" + country).forEach(LOGGER::info); } }, 0, 15, TimeUnit.SECONDS); // Run at every 15 seconds. } @@ -83,8 +78,7 @@ public void run() { * @param args command line args */ public static void main(String[] args) { - App app = new App(); - + var app = new App(); app.run(); } diff --git a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/DataFetcher.java b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/DataFetcher.java index cc9f2aa83813..a4efaa6a8eda 100644 --- a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/DataFetcher.java +++ b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/DataFetcher.java @@ -27,8 +27,8 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -62,24 +62,18 @@ private boolean isDirty(long fileLastModified) { * @return List of strings */ public List fetch() { - ClassLoader classLoader = getClass().getClassLoader(); - File file = new File(classLoader.getResource(filename).getFile()); + var classLoader = getClass().getClassLoader(); + var file = new File(classLoader.getResource(filename).getFile()); if (isDirty(file.lastModified())) { LOGGER.info(filename + " is dirty! Re-fetching file content..."); - - List data = new ArrayList(); - try (BufferedReader br = new BufferedReader(new FileReader(file))) { - String line; - while ((line = br.readLine()) != null) { - data.add(line); - } + try (var br = new BufferedReader(new FileReader(file))) { + return br.lines().collect(Collectors.collectingAndThen(Collectors.toList(), List::copyOf)); } catch (IOException e) { e.printStackTrace(); } - return data; } - return new ArrayList(); + return List.of(); } } diff --git a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java index 189657703e42..db60924c1a72 100644 --- a/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java +++ b/dirty-flag/src/main/java/com/iluwatar/dirtyflag/World.java @@ -47,10 +47,8 @@ public World() { * @return List of strings */ public List fetch() { - List data = df.fetch(); - + var data = df.fetch(); countries = data.isEmpty() ? countries : data; - return countries; } } diff --git a/dirty-flag/src/test/java/org/dirty/flag/AppTest.java b/dirty-flag/src/test/java/org/dirty/flag/AppTest.java index 89736036ab68..1b604898b0db 100644 --- a/dirty-flag/src/test/java/org/dirty/flag/AppTest.java +++ b/dirty-flag/src/test/java/org/dirty/flag/AppTest.java @@ -23,19 +23,15 @@ package org.dirty.flag; -import java.io.IOException; - -import org.junit.jupiter.api.Test; - import com.iluwatar.dirtyflag.App; +import org.junit.jupiter.api.Test; /** * Tests that Dirty-Flag example runs without errors. */ public class AppTest { @Test - public void test() throws IOException { - String[] args = {}; - App.main(args); + public void test() { + App.main(new String[]{}); } } diff --git a/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java b/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java index 7e0de3f8e6af..6a3274a45c12 100644 --- a/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java +++ b/dirty-flag/src/test/java/org/dirty/flag/DirtyFlagTest.java @@ -26,31 +26,26 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.List; - -import org.junit.jupiter.api.Test; - import com.iluwatar.dirtyflag.DataFetcher; +import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class DirtyFlagTest { @Test public void testIsDirty() { - DataFetcher df = new DataFetcher(); - List countries = df.fetch(); + var df = new DataFetcher(); + var countries = df.fetch(); assertFalse(countries.isEmpty()); } @Test public void testIsNotDirty() { - DataFetcher df = new DataFetcher(); + var df = new DataFetcher(); df.fetch(); - List countries = df.fetch(); + var countries = df.fetch(); assertTrue(countries.isEmpty()); } } diff --git a/double-buffer/README.md b/double-buffer/README.md index d187ee2e2a98..d5a6136f3fc0 100644 --- a/double-buffer/README.md +++ b/double-buffer/README.md @@ -3,10 +3,10 @@ layout: pattern title: Double Buffer folder: double-buffer permalink: /patterns/double-buffer/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Performance + - Game programming --- ## Intent @@ -19,11 +19,8 @@ Double buffering is a term used to describe a device that has two buffers. The u This pattern is one of those ones where you’ll know when you need it. If you have a system that lacks double buffering, it will probably look visibly wrong (tearing, etc.) or will behave incorrectly. But saying, “you’ll know when you need it” doesn’t give you much to go on. More specifically, this pattern is appropriate when all of these are true: - We have some state that is being modified incrementally. - - That same state may be accessed in the middle of modification. - - We want to prevent the code that’s accessing the state from seeing the work in progress. - - We want to be able to read the state and we don’t want to have to wait while it’s being written. ## Credits diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java index 636da3eb1d26..00aa3b114654 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/App.java @@ -23,10 +23,8 @@ package com.iluwatar.doublebuffer; -import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.tuple.MutablePair; -import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,37 +46,34 @@ public class App { */ public static void main(String[] args) { final var scene = new Scene(); - List> drawPixels = new ArrayList<>(); - Pair pixel1 = new MutablePair<>(1, 1); - Pair pixel2 = new MutablePair<>(5, 6); - Pair pixel3 = new MutablePair<>(3, 2); - drawPixels.add(pixel1); - drawPixels.add(pixel2); - drawPixels.add(pixel3); - scene.draw(drawPixels); + var drawPixels1 = List.of( + new MutablePair<>(1, 1), + new MutablePair<>(5, 6), + new MutablePair<>(3, 2) + ); + scene.draw(drawPixels1); var buffer1 = scene.getBuffer(); printBlackPixelCoordinate(buffer1); - drawPixels.clear(); - Pair pixel4 = new MutablePair<>(3, 7); - Pair pixel5 = new MutablePair<>(6, 1); - drawPixels.add(pixel4); - drawPixels.add(pixel5); - scene.draw(drawPixels); - Buffer buffer2 = scene.getBuffer(); + var drawPixels2 = List.of( + new MutablePair<>(3, 7), + new MutablePair<>(6, 1) + ); + scene.draw(drawPixels2); + var buffer2 = scene.getBuffer(); printBlackPixelCoordinate(buffer2); } private static void printBlackPixelCoordinate(Buffer buffer) { - var log = "Black Pixels: "; - Pixel[] pixels = buffer.getPixels(); + StringBuilder log = new StringBuilder("Black Pixels: "); + var pixels = buffer.getPixels(); for (var i = 0; i < pixels.length; ++i) { if (pixels[i] == Pixel.BLACK) { var y = i / FrameBuffer.WIDTH; var x = i % FrameBuffer.WIDTH; - log += " (" + x + ", " + y + ")"; + log.append(" (").append(x).append(", ").append(y).append(")"); } } - LOGGER.info(log); + LOGGER.info(log.toString()); } } diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java index aea4144dc4f7..5f683cf1ead4 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/FrameBuffer.java @@ -23,6 +23,8 @@ package com.iluwatar.doublebuffer; +import java.util.Arrays; + /** * FrameBuffer implementation class. */ @@ -49,9 +51,7 @@ public void draw(int x, int y) { @Override public void clearAll() { - for (var i = 0; i < pixels.length; ++i) { - pixels[i] = Pixel.WHITE; - } + Arrays.fill(pixels, Pixel.WHITE); } @Override diff --git a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java index 412b63b0c9ae..2c150391835b 100644 --- a/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java +++ b/double-buffer/src/main/java/com/iluwatar/doublebuffer/Scene.java @@ -57,15 +57,15 @@ public Scene() { * * @param coordinateList list of pixels of which the color should be black */ - public void draw(List> coordinateList) { + public void draw(List> coordinateList) { LOGGER.info("Start drawing next frame"); LOGGER.info("Current buffer: " + current + " Next buffer: " + next); frameBuffers[next].clearAll(); - for (Pair coordinate : coordinateList) { + coordinateList.forEach(coordinate -> { var x = coordinate.getKey(); var y = coordinate.getValue(); frameBuffers[next].draw(x, y); - } + }); LOGGER.info("Swap current and next buffer"); swap(); LOGGER.info("Finish swapping"); diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java index 6139e6bca786..eb89a4044307 100644 --- a/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/AppTest.java @@ -32,8 +32,7 @@ public class AppTest { @Test public void testMain() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java index 3f171d1d65db..2ade416cd4d5 100644 --- a/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/FrameBufferTest.java @@ -23,6 +23,7 @@ package com.iluwatar.doublebuffer; +import java.util.Arrays; import org.junit.Assert; import org.junit.Test; @@ -35,10 +36,8 @@ public class FrameBufferTest { public void testClearAll() { try { var field = FrameBuffer.class.getDeclaredField("pixels"); - Pixel[] pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; - for (int i = 0; i < pixels.length; ++i) { - pixels[i] = Pixel.WHITE; - } + var pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; + Arrays.fill(pixels, Pixel.WHITE); pixels[0] = Pixel.BLACK; var frameBuffer = new FrameBuffer(); field.setAccessible(true); @@ -54,10 +53,8 @@ public void testClearAll() { public void testClear() { try { var field = FrameBuffer.class.getDeclaredField("pixels"); - Pixel[] pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; - for (int i = 0; i < pixels.length; ++i) { - pixels[i] = Pixel.WHITE; - } + var pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; + Arrays.fill(pixels, Pixel.WHITE); pixels[0] = Pixel.BLACK; var frameBuffer = new FrameBuffer(); field.setAccessible(true); @@ -80,10 +77,8 @@ public void testDraw() { public void testGetPixels() { try { var field = FrameBuffer.class.getDeclaredField("pixels"); - Pixel[] pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; - for (int i = 0; i < pixels.length; ++i) { - pixels[i] = Pixel.WHITE; - } + var pixels = new Pixel[FrameBuffer.HEIGHT * FrameBuffer.WIDTH]; + Arrays.fill(pixels, Pixel.WHITE); pixels[0] = Pixel.BLACK; var frameBuffer = new FrameBuffer(); field.setAccessible(true); diff --git a/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java b/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java index bd1dd44d06dd..cd17d21916d2 100644 --- a/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java +++ b/double-buffer/src/test/java/com/iluwatar/doublebuffer/SceneTest.java @@ -23,12 +23,10 @@ package com.iluwatar.doublebuffer; +import java.util.ArrayList; import org.junit.Assert; import org.junit.Test; -import java.lang.reflect.Field; -import java.util.ArrayList; - /** * Scene unit tests. */ @@ -41,8 +39,8 @@ public void testGetBuffer() { var field1 = Scene.class.getDeclaredField("current"); field1.setAccessible(true); field1.set(scene, 0); - FrameBuffer[] frameBuffers = new FrameBuffer[2]; - FrameBuffer frameBuffer = new FrameBuffer(); + var frameBuffers = new FrameBuffer[2]; + var frameBuffer = new FrameBuffer(); frameBuffer.draw(0, 0); frameBuffers[0] = frameBuffer; var field2 = Scene.class.getDeclaredField("frameBuffers"); diff --git a/double-checked-locking/README.md b/double-checked-locking/README.md index d1077951a09d..64bf1522ce28 100644 --- a/double-checked-locking/README.md +++ b/double-checked-locking/README.md @@ -3,11 +3,9 @@ layout: pattern title: Double Checked Locking folder: double-checked-locking permalink: /patterns/double-checked-locking/ -categories: Concurrency +categories: Idiom tags: - - Java - - Difficulty-Beginner - - Idiom + - Performance --- ## Intent diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java index 745654796abd..fd4f71063e9f 100644 --- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java +++ b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/App.java @@ -23,9 +23,9 @@ package com.iluwatar.doublechecked.locking; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,15 +50,13 @@ public class App { * @param args command line args */ public static void main(String[] args) { - final Inventory inventory = new Inventory(1000); - ExecutorService executorService = Executors.newFixedThreadPool(3); - for (int i = 0; i < 3; i++) { - executorService.execute(() -> { - while (inventory.addItem(new Item())) { - LOGGER.info("Adding another item"); - } - }); - } + final var inventory = new Inventory(1000); + var executorService = Executors.newFixedThreadPool(3); + IntStream.range(0, 3).mapToObj(i -> () -> { + while (inventory.addItem(new Item())) { + LOGGER.info("Adding another item"); + } + }).forEach(executorService::execute); executorService.shutdown(); try { diff --git a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java index 17b47fa430d5..ae2e70d6f2ce 100644 --- a/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java +++ b/double-checked-locking/src/main/java/com/iluwatar/doublechecked/locking/Inventory.java @@ -24,7 +24,6 @@ package com.iluwatar.doublechecked.locking; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -60,8 +59,8 @@ public boolean addItem(Item item) { try { if (items.size() < inventorySize) { items.add(item); - LOGGER.info("{}: items.size()={}, inventorySize={}", Thread.currentThread(), items - .size(), inventorySize); + var thread = Thread.currentThread(); + LOGGER.info("{}: items.size()={}, inventorySize={}", thread, items.size(), inventorySize); return true; } } finally { @@ -77,7 +76,7 @@ public boolean addItem(Item item) { * @return All the items of the inventory, as an unmodifiable list */ public final List getItems() { - return Collections.unmodifiableList(items); + return List.copyOf(items); } } diff --git a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java index 76cc9820a3d7..6eac88fcd8f5 100644 --- a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java +++ b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/AppTest.java @@ -26,15 +26,12 @@ import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java index bd83cc67fa8b..e8ea7c6f860b 100644 --- a/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java +++ b/double-checked-locking/src/test/java/com/iluwatar/doublechecked/locking/InventoryTest.java @@ -23,25 +23,24 @@ package com.iluwatar.doublechecked.locking; +import static java.time.Duration.ofMillis; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTimeout; + import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.AppenderBase; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.slf4j.LoggerFactory; - import java.util.LinkedList; import java.util.List; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; - -import static java.time.Duration.ofMillis; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTimeout; -import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.stream.IntStream; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; /** * Date: 12/10/15 - 9:34 PM @@ -83,34 +82,32 @@ public void tearDown() { public void testAddItem() throws Exception { assertTimeout(ofMillis(10000), () -> { // Create a new inventory with a limit of 1000 items and put some load on the add method - final Inventory inventory = new Inventory(INVENTORY_SIZE); - final ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT); - for (int i = 0; i < THREAD_COUNT; i++) { - executorService.execute(() -> { - while (inventory.addItem(new Item())) {}; - }); - } + final var inventory = new Inventory(INVENTORY_SIZE); + final var executorService = Executors.newFixedThreadPool(THREAD_COUNT); + IntStream.range(0, THREAD_COUNT).mapToObj(i -> () -> { + while (inventory.addItem(new Item())) ; + }).forEach(executorService::execute); // Wait until all threads have finished executorService.shutdown(); executorService.awaitTermination(5, TimeUnit.SECONDS); // Check the number of items in the inventory. It should not have exceeded the allowed maximum - final List items = inventory.getItems(); + final var items = inventory.getItems(); assertNotNull(items); assertEquals(INVENTORY_SIZE, items.size()); assertEquals(INVENTORY_SIZE, appender.getLogSize()); // ... and check if the inventory size is increasing continuously - for (int i = 0; i < items.size(); i++) { - assertTrue(appender.log.get(i).getFormattedMessage().contains("items.size()=" + (i + 1))); - } + IntStream.range(0, items.size()) + .mapToObj(i -> appender.log.get(i).getFormattedMessage() + .contains("items.size()=" + (i + 1))) + .forEach(Assertions::assertTrue); }); } - private class InMemoryAppender extends AppenderBase { private List log = new LinkedList<>(); diff --git a/double-dispatch/README.md b/double-dispatch/README.md index dfc86a8270c3..22e7a72352eb 100644 --- a/double-dispatch/README.md +++ b/double-dispatch/README.md @@ -3,11 +3,9 @@ layout: pattern title: Double Dispatch folder: double-dispatch permalink: /patterns/double-dispatch/ -categories: Other +categories: Idiom tags: - - Java - - Difficulty-Intermediate - - Idiom + - Extensibility --- ## Intent diff --git a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java index 9117ede47af9..baeda1a46e6e 100644 --- a/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java +++ b/double-dispatch/src/main/java/com/iluwatar/doubledispatch/App.java @@ -57,16 +57,17 @@ public class App { */ public static void main(String[] args) { // initialize game objects and print their status - List objects = List.of( + var objects = List.of( new FlamingAsteroid(0, 0, 5, 5), new SpaceStationMir(1, 1, 2, 2), new Meteoroid(10, 10, 15, 15), - new SpaceStationIss(12, 12, 14, 14)); - objects.stream().forEach(o -> LOGGER.info(o.toString())); + new SpaceStationIss(12, 12, 14, 14) + ); + objects.forEach(o -> LOGGER.info(o.toString())); LOGGER.info(""); // collision check - objects.stream().forEach(o1 -> objects.stream().forEach(o2 -> { + objects.forEach(o1 -> objects.forEach(o2 -> { if (o1 != o2 && o1.intersectsWith(o2)) { o1.collision(o2); } @@ -74,7 +75,7 @@ public static void main(String[] args) { LOGGER.info(""); // output eventual object statuses - objects.stream().forEach(o -> LOGGER.info(o.toString())); + objects.forEach(o -> LOGGER.info(o.toString())); LOGGER.info(""); } } diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java index d2410a5b629c..67ca00c56b2a 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/AppTest.java @@ -26,15 +26,12 @@ import org.junit.jupiter.api.Test; /** - * * Application test - * */ public class AppTest { @Test public void test() { - String[] args = {}; - App.main(args); + App.main(new String[]{}); } } diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java index a22af646d87e..59f25b999ac6 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/CollisionTest.java @@ -23,13 +23,13 @@ package com.iluwatar.doubledispatch; -import java.util.Objects; - import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.Objects; + /** - * Date: 12/10/15 - 8:37 PM - * Test for Collision + * Date: 12/10/15 - 8:37 PM Test for Collision + * * @param Type of GameObject * @author Jeroen Meulemeester */ @@ -51,15 +51,14 @@ public abstract class CollisionTest { * @param otherOnFire Indicates if the other object should be burning after the collision * @param thisDamaged Indicates if the test object should be damaged after the collision * @param thisOnFire Indicates if the other object should be burning after the collision - * @param description The expected description of the collision */ void testCollision(final GameObject other, final boolean otherDamaged, final boolean otherOnFire, - final boolean thisDamaged, final boolean thisOnFire, final String description) { + final boolean thisDamaged, final boolean thisOnFire) { Objects.requireNonNull(other); Objects.requireNonNull(getTestedObject()); - final O tested = getTestedObject(); + final var tested = getTestedObject(); tested.collision(other); @@ -80,10 +79,10 @@ void testCollision(final GameObject other, final boolean otherDamaged, final boo * @param expectTargetOnFire The expected state of fire on the target object */ private void testOnFire(final GameObject target, final GameObject other, final boolean expectTargetOnFire) { - final String targetName = target.getClass().getSimpleName(); - final String otherName = other.getClass().getSimpleName(); + final var targetName = target.getClass().getSimpleName(); + final var otherName = other.getClass().getSimpleName(); - final String errorMessage = expectTargetOnFire + final var errorMessage = expectTargetOnFire ? "Expected [" + targetName + "] to be on fire after colliding with [" + otherName + "] but it was not!" : "Expected [" + targetName + "] not to be on fire after colliding with [" + otherName + "] but it was!"; @@ -99,10 +98,10 @@ private void testOnFire(final GameObject target, final GameObject other, final b * @param expectedDamage The expected state of damage on the target object */ private void testDamaged(final GameObject target, final GameObject other, final boolean expectedDamage) { - final String targetName = target.getClass().getSimpleName(); - final String otherName = other.getClass().getSimpleName(); + final var targetName = target.getClass().getSimpleName(); + final var otherName = other.getClass().getSimpleName(); - final String errorMessage = expectedDamage + final var errorMessage = expectedDamage ? "Expected [" + targetName + "] to be damaged after colliding with [" + otherName + "] but it was not!" : "Expected [" + targetName + "] not to be damaged after colliding with [" + otherName + "] but it was!"; diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/FlamingAsteroidTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/FlamingAsteroidTest.java index 312365ddbf95..8b4ff56b5e0e 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/FlamingAsteroidTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/FlamingAsteroidTest.java @@ -23,12 +23,12 @@ package com.iluwatar.doubledispatch; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + /** * Date: 12/10/15 - 11:31 PM * @@ -46,7 +46,7 @@ final FlamingAsteroid getTestedObject() { */ @Test public void testConstructor() { - final FlamingAsteroid asteroid = new FlamingAsteroid(1, 2, 3, 4); + final var asteroid = new FlamingAsteroid(1, 2, 3, 4); assertEquals(1, asteroid.getLeft()); assertEquals(2, asteroid.getTop()); assertEquals(3, asteroid.getRight()); @@ -64,8 +64,7 @@ public void testCollideFlamingAsteroid() { testCollision( new FlamingAsteroid(1, 2, 3, 4), false, true, - false, true, - "FlamingAsteroid hits FlamingAsteroid." + false, true ); } @@ -77,8 +76,7 @@ public void testCollideMeteoroid() { testCollision( new Meteoroid(1, 1, 3, 4), false, false, - false, true, - "FlamingAsteroid hits Meteoroid." + false, true ); } @@ -90,8 +88,7 @@ public void testCollideSpaceStationIss() { testCollision( new SpaceStationIss(1, 1, 3, 4), true, true, - false, true, - "FlamingAsteroid hits SpaceStationIss. SpaceStationIss is damaged! SpaceStationIss is set on fire!" + false, true ); } @@ -103,8 +100,7 @@ public void testCollideSpaceStationMir() { testCollision( new SpaceStationMir(1, 1, 3, 4), true, true, - false, true, - "FlamingAsteroid hits SpaceStationMir. SpaceStationMir is damaged! SpaceStationMir is set on fire!" + false, true ); } diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/MeteoroidTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/MeteoroidTest.java index 4ba6db816556..71f160f078ec 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/MeteoroidTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/MeteoroidTest.java @@ -23,11 +23,11 @@ package com.iluwatar.doubledispatch; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import org.junit.jupiter.api.Test; + /** * Date: 12/10/15 - 11:31 PM * @@ -45,7 +45,7 @@ final Meteoroid getTestedObject() { */ @Test public void testConstructor() { - final Meteoroid meteoroid = new Meteoroid(1, 2, 3, 4); + final var meteoroid = new Meteoroid(1, 2, 3, 4); assertEquals(1, meteoroid.getLeft()); assertEquals(2, meteoroid.getTop()); assertEquals(3, meteoroid.getRight()); @@ -63,8 +63,7 @@ public void testCollideFlamingAsteroid() { testCollision( new FlamingAsteroid(1, 1, 3, 4), false, true, - false, false, - "Meteoroid hits FlamingAsteroid." + false, false ); } @@ -76,8 +75,7 @@ public void testCollideMeteoroid() { testCollision( new Meteoroid(1, 1, 3, 4), false, false, - false, false, - "Meteoroid hits Meteoroid." + false, false ); } @@ -89,8 +87,7 @@ public void testCollideSpaceStationIss() { testCollision( new SpaceStationIss(1, 1, 3, 4), true, false, - false, false, - "Meteoroid hits SpaceStationIss. SpaceStationIss is damaged!" + false, false ); } @@ -102,8 +99,7 @@ public void testCollideSpaceStationMir() { testCollision( new SpaceStationMir(1, 1, 3, 4), true, false, - false, false, - "Meteoroid hits SpaceStationMir. SpaceStationMir is damaged!" + false, false ); } diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/RectangleTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/RectangleTest.java index d91ff0800296..ceae9b260a63 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/RectangleTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/RectangleTest.java @@ -23,12 +23,12 @@ package com.iluwatar.doubledispatch; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + /** * Unit test for Rectangle */ @@ -39,7 +39,7 @@ public class RectangleTest { */ @Test public void testConstructor() { - final Rectangle rectangle = new Rectangle(1, 2, 3, 4); + final var rectangle = new Rectangle(1, 2, 3, 4); assertEquals(1, rectangle.getLeft()); assertEquals(2, rectangle.getTop()); assertEquals(3, rectangle.getRight()); @@ -52,7 +52,7 @@ public void testConstructor() { */ @Test public void testToString() throws Exception { - final Rectangle rectangle = new Rectangle(1, 2, 3, 4); + final var rectangle = new Rectangle(1, 2, 3, 4); assertEquals("[1,2,3,4]", rectangle.toString()); } diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationIssTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationIssTest.java index d59ab118ab90..681c63b8fc08 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationIssTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationIssTest.java @@ -23,11 +23,11 @@ package com.iluwatar.doubledispatch; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import org.junit.jupiter.api.Test; + /** * Date: 12/10/15 - 11:31 PM * @@ -45,7 +45,7 @@ final SpaceStationIss getTestedObject() { */ @Test public void testConstructor() { - final SpaceStationIss iss = new SpaceStationIss(1, 2, 3, 4); + final var iss = new SpaceStationIss(1, 2, 3, 4); assertEquals(1, iss.getLeft()); assertEquals(2, iss.getTop()); assertEquals(3, iss.getRight()); @@ -63,8 +63,7 @@ public void testCollideFlamingAsteroid() { testCollision( new FlamingAsteroid(1, 1, 3, 4), false, true, - false, false, - "SpaceStationIss hits FlamingAsteroid." + false, false ); } @@ -76,8 +75,7 @@ public void testCollideMeteoroid() { testCollision( new Meteoroid(1, 1, 3, 4), false, false, - false, false, - "SpaceStationIss hits Meteoroid." + false, false ); } @@ -89,8 +87,7 @@ public void testCollideSpaceStationIss() { testCollision( new SpaceStationIss(1, 1, 3, 4), true, false, - false, false, - "SpaceStationIss hits SpaceStationIss. SpaceStationIss is damaged!" + false, false ); } @@ -102,8 +99,7 @@ public void testCollideSpaceStationMir() { testCollision( new SpaceStationMir(1, 1, 3, 4), true, false, - false, false, - "SpaceStationIss hits SpaceStationMir. SpaceStationMir is damaged!" + false, false ); } diff --git a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationMirTest.java b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationMirTest.java index 1017744ee0e8..b4e79b475858 100644 --- a/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationMirTest.java +++ b/double-dispatch/src/test/java/com/iluwatar/doubledispatch/SpaceStationMirTest.java @@ -23,11 +23,11 @@ package com.iluwatar.doubledispatch; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import org.junit.jupiter.api.Test; + /** * Date: 12/10/15 - 11:31 PM * @@ -45,7 +45,7 @@ final SpaceStationMir getTestedObject() { */ @Test public void testConstructor() { - final SpaceStationMir mir = new SpaceStationMir(1, 2, 3, 4); + final var mir = new SpaceStationMir(1, 2, 3, 4); assertEquals(1, mir.getLeft()); assertEquals(2, mir.getTop()); assertEquals(3, mir.getRight()); @@ -63,8 +63,7 @@ public void testCollideFlamingAsteroid() { testCollision( new FlamingAsteroid(1, 1, 3, 4), false, true, - false, false, - "SpaceStationMir hits FlamingAsteroid." + false, false ); } @@ -76,8 +75,7 @@ public void testCollideMeteoroid() { testCollision( new Meteoroid(1, 1, 3, 4), false, false, - false, false, - "SpaceStationMir hits Meteoroid." + false, false ); } @@ -89,8 +87,7 @@ public void testCollideSpaceStationIss() { testCollision( new SpaceStationIss(1, 1, 3, 4), true, false, - false, false, - "SpaceStationMir hits SpaceStationIss. SpaceStationIss is damaged!" + false, false ); } @@ -102,8 +99,7 @@ public void testCollideSpaceStationMir() { testCollision( new SpaceStationMir(1, 1, 3, 4), true, false, - false, false, - "SpaceStationMir hits SpaceStationMir. SpaceStationMir is damaged!" + false, false ); } diff --git a/eip-aggregator/README.md b/eip-aggregator/README.md index 2b55b4e09b4b..6138af0a82cb 100644 --- a/eip-aggregator/README.md +++ b/eip-aggregator/README.md @@ -5,9 +5,7 @@ folder: eip-aggregator permalink: /patterns/eip-aggregator/ categories: Integration tags: - - Java - - Difficulty-Intermittent - - EIP + - Enterprise Integration Pattern --- ## Intent diff --git a/eip-message-channel/README.md b/eip-message-channel/README.md index f43072f52928..8e2f5dc8f203 100644 --- a/eip-message-channel/README.md +++ b/eip-message-channel/README.md @@ -5,9 +5,7 @@ folder: eip-message-channel permalink: /patterns/eip-message-channel/ categories: Integration tags: - - Java - - EIP - - Apache Camel™ + - Enterprise Integration Pattern --- ## Intent diff --git a/eip-publish-subscribe/README.md b/eip-publish-subscribe/README.md index f9ec20fdfd24..3952913af1bd 100644 --- a/eip-publish-subscribe/README.md +++ b/eip-publish-subscribe/README.md @@ -5,9 +5,7 @@ folder: eip-publish-subscribe permalink: /patterns/eip-publish-subscribe/ categories: Integration tags: - - Java - - EIP - - Apache Camel™ + - Enterprise Integration Pattern --- ## Intent diff --git a/eip-splitter/README.md b/eip-splitter/README.md index a2eedbb38ea1..6484622295cd 100644 --- a/eip-splitter/README.md +++ b/eip-splitter/README.md @@ -5,9 +5,7 @@ folder: eip-splitter permalink: /patterns/eip-splitter/ categories: Integration tags: - - Java - - Difficulty-Intermittent - - EIP + - Enterprise Integration Pattern --- ## Intent diff --git a/eip-wire-tap/README.md b/eip-wire-tap/README.md index b4609975ebba..83b43dfd1f48 100644 --- a/eip-wire-tap/README.md +++ b/eip-wire-tap/README.md @@ -5,9 +5,7 @@ folder: eip-wire-tap permalink: /patterns/eip-wire-tap/ categories: Integration tags: - - Java - - Difficulty-Intermittent - - EIP + - Enterprise Integration Pattern --- ## Intent diff --git a/event-aggregator/README.md b/event-aggregator/README.md index 79965bce1d7a..5a8eb9685f60 100644 --- a/event-aggregator/README.md +++ b/event-aggregator/README.md @@ -5,8 +5,6 @@ folder: event-aggregator permalink: /patterns/event-aggregator/ categories: Structural tags: - - Java - - Difficulty-Beginner - Reactive --- diff --git a/event-asynchronous/README.md b/event-asynchronous/README.md index 68684e6ed87a..397d675e7c68 100644 --- a/event-asynchronous/README.md +++ b/event-asynchronous/README.md @@ -5,9 +5,7 @@ folder: event-asynchronous permalink: /patterns/event-asynchronous/ categories: Concurrency tags: - - difficulty-intermediate - - performance - - Java + - Reactive --- ## Intent diff --git a/event-driven-architecture/README.md b/event-driven-architecture/README.md index 5fcce357f76b..b0083d38bc17 100644 --- a/event-driven-architecture/README.md +++ b/event-driven-architecture/README.md @@ -5,8 +5,6 @@ folder: event-driven-architecture permalink: /patterns/event-driven-architecture/ categories: Architectural tags: - - Java - - Difficulty-Intermediate - Reactive --- diff --git a/event-queue/README.md b/event-queue/README.md index b4d7a071fefe..f0bec2638988 100644 --- a/event-queue/README.md +++ b/event-queue/README.md @@ -5,9 +5,7 @@ folder: event-queue permalink: /patterns/event-queue/ categories: Concurrency tags: - - Java - - Difficulty Intermediate - - Queue + - Game programming --- ## Intent diff --git a/event-sourcing/README.md b/event-sourcing/README.md index 9e577af6c9fe..5efbbbd020da 100644 --- a/event-sourcing/README.md +++ b/event-sourcing/README.md @@ -5,8 +5,6 @@ folder: event-sourcing permalink: /patterns/event-sourcing/ categories: Architectural tags: - - Java - - Difficulty Intermediate - Performance --- diff --git a/execute-around/README.md b/execute-around/README.md index 9af46812ebaf..677a97a6efad 100644 --- a/execute-around/README.md +++ b/execute-around/README.md @@ -3,11 +3,9 @@ layout: pattern title: Execute Around folder: execute-around permalink: /patterns/execute-around/ -categories: Other +categories: Idiom tags: - - Java - - Difficulty-Beginner - - Idiom + - Extensibility --- ## Intent @@ -25,4 +23,5 @@ Use the Execute Around idiom when * you use an API that requires methods to be called in pairs such as open/close or allocate/deallocate. ## Credits + * [Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions](http://www.amazon.com/Functional-Programming-Java-Harnessing-Expressions/dp/1937785467/ref=sr_1_1) diff --git a/extension-objects/README.md b/extension-objects/README.md index 5b0da5cf4b0f..64964a5fee37 100644 --- a/extension-objects/README.md +++ b/extension-objects/README.md @@ -5,8 +5,7 @@ folder: extension-objects permalink: /patterns/extension-objects/ categories: Behavioral tags: - - Java - - Difficulty-Intermediate + - Extensibility --- ## Intent diff --git a/facade/README.md b/facade/README.md index 89a6a32e9a1c..42000149898a 100644 --- a/facade/README.md +++ b/facade/README.md @@ -5,9 +5,8 @@ folder: facade permalink: /patterns/facade/ categories: Structural tags: - - Java - Gang Of Four - - Difficulty-Beginner + - Decoupling --- ## Intent diff --git a/factory-kit/README.md b/factory-kit/README.md index f374886d4496..6183ac87f104 100644 --- a/factory-kit/README.md +++ b/factory-kit/README.md @@ -5,9 +5,7 @@ folder: factory-kit permalink: /patterns/factory-kit/ categories: Creational tags: - - Java - - Difficulty-Beginner - - Functional + - Extensibility --- ## Intent diff --git a/factory-method/README.md b/factory-method/README.md index 37ab743933da..18cbba2e4a35 100644 --- a/factory-method/README.md +++ b/factory-method/README.md @@ -5,8 +5,7 @@ folder: factory-method permalink: /patterns/factory-method/ categories: Creational tags: - - Java - - Difficulty-Beginner + - Extensibility - Gang Of Four --- diff --git a/feature-toggle/README.md b/feature-toggle/README.md index b4ba16cb4e00..a3a76f05a67f 100644 --- a/feature-toggle/README.md +++ b/feature-toggle/README.md @@ -5,8 +5,7 @@ folder: feature-toggle permalink: /patterns/feature-toggle/ categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Extensibility --- ## Also known as diff --git a/fluentinterface/README.md b/fluentinterface/README.md index 08e1275e9155..3068468b91f0 100644 --- a/fluentinterface/README.md +++ b/fluentinterface/README.md @@ -3,11 +3,9 @@ layout: pattern title: Fluent Interface folder: fluentinterface permalink: /patterns/fluentinterface/ -categories: Other +categories: Functional tags: - - Java - - Difficulty-Intermediate - - Functional + - Reactive --- ## Intent diff --git a/flux/README.md b/flux/README.md index 43e791509d73..0a2ea0b81135 100644 --- a/flux/README.md +++ b/flux/README.md @@ -3,10 +3,9 @@ layout: pattern title: Flux folder: flux permalink: /patterns/flux/ -categories: Presentation Tier +categories: Structural tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Intent diff --git a/flyweight/README.md b/flyweight/README.md index ff2ddcfe693b..4847b828505b 100644 --- a/flyweight/README.md +++ b/flyweight/README.md @@ -5,9 +5,7 @@ folder: flyweight permalink: /patterns/flyweight/ categories: Structural tags: - - Java - Gang Of Four - - Difficulty-Intermediate - Performance --- diff --git a/front-controller/README.md b/front-controller/README.md index 3126e5e24ae7..f4a2da970e41 100644 --- a/front-controller/README.md +++ b/front-controller/README.md @@ -3,10 +3,9 @@ layout: pattern title: Front Controller folder: front-controller permalink: /patterns/front-controller/ -categories: Presentation Tier +categories: Structural tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Intent diff --git a/game-loop/README.md b/game-loop/README.md index 566ea37f35b3..f0a7eeebb412 100644 --- a/game-loop/README.md +++ b/game-loop/README.md @@ -3,10 +3,9 @@ layout: pattern title: Game Loop folder: game-loop permalink: /patterns/game-loop/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Game programming --- ## Intent diff --git a/guarded-suspension/README.md b/guarded-suspension/README.md index 28ffa9d9874c..83e6b4fdf545 100644 --- a/guarded-suspension/README.md +++ b/guarded-suspension/README.md @@ -5,8 +5,7 @@ folder: guarded-suspension permalink: /patterns/guarded-suspension/ categories: Concurrency tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent @@ -19,4 +18,5 @@ Use Guarded suspension pattern to handle a situation when you want to execute a Use Guarded Suspension pattern when the developer knows that the method execution will be blocked for a finite period of time ## Related patterns + * Balking diff --git a/half-sync-half-async/README.md b/half-sync-half-async/README.md index 4ad350d59cd9..5cfb411e58fd 100644 --- a/half-sync-half-async/README.md +++ b/half-sync-half-async/README.md @@ -5,8 +5,7 @@ folder: half-sync-half-async permalink: /patterns/half-sync-half-async/ categories: Concurrency tags: - - Java - - Difficulty-Intermediate + - Performance --- ## Intent diff --git a/hexagonal/README.md b/hexagonal/README.md index eb5ef0987e31..c478efafd727 100644 --- a/hexagonal/README.md +++ b/hexagonal/README.md @@ -6,11 +6,11 @@ permalink: /patterns/hexagonal/ pumlformat: svg categories: Architectural tags: - - Java - - Difficulty-Expert + - Decoupling --- ## Also known as + * Ports and Adapters * Clean Architecture * Onion Architecture @@ -28,6 +28,7 @@ Use Hexagonal Architecture pattern when * When it is important that the application highly maintainable and fully testable ## Tutorials + * [Build Maintainable Systems With Hexagonal Architecture](http://java-design-patterns.com/blog/build-maintainable-systems-with-hexagonal-architecture/) ## Real world examples diff --git a/intercepting-filter/README.md b/intercepting-filter/README.md index 660d67e3d916..39188810d3b7 100644 --- a/intercepting-filter/README.md +++ b/intercepting-filter/README.md @@ -5,8 +5,7 @@ folder: intercepting-filter permalink: /patterns/intercepting-filter/ categories: Behavioral tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Intent @@ -24,6 +23,7 @@ Use the Intercepting Filter pattern when * you want a modular approach to configuring pre-processing and post-processing schemes ## Tutorials + * [Introduction to Intercepting Filter Pattern in Java](https://www.baeldung.com/intercepting-filter-pattern-in-java) ## Real world examples diff --git a/interpreter/README.md b/interpreter/README.md index 6349450051a2..6a941d2e5d0a 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -5,9 +5,7 @@ folder: interpreter permalink: /patterns/interpreter/ categories: Behavioral tags: - - Java - - Gang Of Four - - Difficulty-Intermediate + - Gang of Four --- ## Intent @@ -27,6 +25,7 @@ trees. The Interpreter pattern works best when * efficiency is not a critical concern. The most efficient interpreters are usually not implemented by interpreting parse trees directly but by first translating them into another form. For example, regular expressions are often transformed into state machines. But even then, the translator can be implemented by the Interpreter pattern, so the pattern is still applicable ## Real world examples + * [java.util.Pattern](http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) * [java.text.Normalizer](http://docs.oracle.com/javase/8/docs/api/java/text/Normalizer.html) * All subclasses of [java.text.Format](http://docs.oracle.com/javase/8/docs/api/java/text/Format.html) diff --git a/iterator/README.md b/iterator/README.md index 3dfcb10858ba..61cf0291ad6c 100644 --- a/iterator/README.md +++ b/iterator/README.md @@ -5,9 +5,7 @@ folder: iterator permalink: /patterns/iterator/ categories: Behavioral tags: - - Java - - Difficulty-Beginner - - Gang Of Four + - Gang of Four --- ## Also known as diff --git a/layers/README.md b/layers/README.md index 66a5c9c321af..58c9cd828bff 100644 --- a/layers/README.md +++ b/layers/README.md @@ -6,9 +6,7 @@ permalink: /patterns/layers/ pumlformat: svg categories: Architectural tags: - - Java - - Difficulty-Intermediate - - Spring + - Decoupling --- ## Intent diff --git a/lazy-loading/README.md b/lazy-loading/README.md index 8156b3524897..997149b0343f 100644 --- a/lazy-loading/README.md +++ b/lazy-loading/README.md @@ -3,11 +3,8 @@ layout: pattern title: Lazy Loading folder: lazy-loading permalink: /patterns/lazy-loading/ -categories: Other +categories: Idiom tags: - - Java - - Difficulty-Beginner - - Idiom - Performance --- diff --git a/leader-election/README.md b/leader-election/README.md index 15f2f93415e7..e6b2428ddc55 100644 --- a/leader-election/README.md +++ b/leader-election/README.md @@ -3,10 +3,9 @@ layout: pattern title: Leader Election folder: leader-election permalink: /patterns/leader-election/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Cloud distributed --- ## Intent diff --git a/marker/README.md b/marker/README.md index 70e92480edab..a411827c3289 100644 --- a/marker/README.md +++ b/marker/README.md @@ -3,10 +3,9 @@ layout: pattern title: Marker Interface folder: marker permalink: /patterns/marker/ -categories: Other +categories: Structural tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent diff --git a/master-worker-pattern/README.md b/master-worker-pattern/README.md index 239b83fde274..876d9206cf2d 100644 --- a/master-worker-pattern/README.md +++ b/master-worker-pattern/README.md @@ -3,10 +3,9 @@ layout: pattern title: Master-Worker folder: master-worker-pattern permalink: /patterns/master-worker-pattern/ -categories: Other +categories: Concurrency tags: - - Java - - Difficulty-Intermediate + - Performance --- ## Also known as @@ -27,5 +26,6 @@ This pattern can be used when data can be divided into multiple parts, all of wh In this pattern, parallel processing is performed using a system consisting of a master and some number of workers, where a master divides the work among the workers, gets the result back from them and assimilates all the results to give final result. The only communication is between the master and the worker - none of the workers communicate among one another and the user only communicates with the master to get the required job done. The master has to maintain a record of how the divided data has been distributed, how many workers have finished their work and returned a result, and the results themselves to be able to aggregate the data correctly. ## Credits + * [https://docs.gigaspaces.com/sbp/master-worker-pattern.html] * [http://www.cs.sjsu.edu/~pearce/oom/patterns/behavioral/masterslave.htm] diff --git a/mediator/README.md b/mediator/README.md index 4e38d833c35f..e8e0fa412412 100644 --- a/mediator/README.md +++ b/mediator/README.md @@ -5,9 +5,8 @@ folder: mediator permalink: /patterns/mediator/ categories: Behavioral tags: - - Java - Gang Of Four - - Difficulty-Intermediate + - Decoupling --- ## Intent diff --git a/memento/README.md b/memento/README.md index 34555f550ce3..6dd262f9c1fb 100644 --- a/memento/README.md +++ b/memento/README.md @@ -5,9 +5,7 @@ folder: memento permalink: /patterns/memento/ categories: Behavioral tags: - - Java - - Gang Of Four - - Difficulty-Intermediate + - Gang of Four --- ## Also known as diff --git a/model-view-controller/README.md b/model-view-controller/README.md index acc3c07a96b2..c1542df04100 100644 --- a/model-view-controller/README.md +++ b/model-view-controller/README.md @@ -3,10 +3,9 @@ layout: pattern title: Model-View-Controller folder: model-view-controller permalink: /patterns/model-view-controller/ -categories: Presentation Tier +categories: Architectural tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Intent @@ -21,7 +20,7 @@ display. ## Applicability Use the Model-View-Controller pattern when -* you want to clearly separate the domain data from its user interface representation +* You want to clearly separate the domain data from its user interface representation ## Credits diff --git a/model-view-presenter/README.md b/model-view-presenter/README.md index ede8e3baeb20..e9cbe1e96263 100644 --- a/model-view-presenter/README.md +++ b/model-view-presenter/README.md @@ -3,10 +3,9 @@ layout: pattern title: Model-View-Presenter folder: model-view-presenter permalink: /patterns/model-view-presenter/ -categories: Presentation Tier +categories: Architectural tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Intent @@ -20,8 +19,8 @@ developers to build and test user interfaces. Use the Model-View-Presenter in any of the following situations -* when you want to improve the "Separation of Concerns" principle in presentation logic -* when a user interface development and testing is necessary. +* When you want to improve the "Separation of Concerns" principle in presentation logic +* When a user interface development and testing is necessary. ## Real world examples diff --git a/module/README.md b/module/README.md index 316458e0b5b0..32897adefb59 100644 --- a/module/README.md +++ b/module/README.md @@ -3,10 +3,9 @@ layout: pattern title: Module folder: module permalink: /patterns/module/ -categories: Creational Pattern +categories: Structural tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent diff --git a/monad/README.md b/monad/README.md index cf751929c200..3da976d23158 100644 --- a/monad/README.md +++ b/monad/README.md @@ -3,11 +3,9 @@ layout: pattern title: Monad folder: monad permalink: /patterns/monad/ -categories: Other +categories: Functional tags: - - Java - - Difficulty-Expert - - Functional + - Reactive --- ## Intent @@ -26,8 +24,8 @@ return - that takes plain type object and returns this object wrapped in a monad Use the Monad in any of the following situations -* when you want to chain operations easily -* when you want to apply each function regardless of the result of any of them +* When you want to chain operations easily +* When you want to apply each function regardless of the result of any of them ## Credits diff --git a/monostate/README.md b/monostate/README.md index 93cf6a45bfa7..790fb1f6d395 100644 --- a/monostate/README.md +++ b/monostate/README.md @@ -5,8 +5,7 @@ folder: monostate permalink: /patterns/monostate/ categories: Creational tags: - - Java - - Difficulty-Beginner + - Instantiation --- ## Also known as @@ -27,9 +26,9 @@ Use the Monostate pattern when ## Typical Use Case -* the logging class -* managing a connection to a database -* file manager +* The logging class +* Managing a connection to a database +* File manager ## Real world examples diff --git a/multiton/README.md b/multiton/README.md index 105dd9d91944..4387cf7acab3 100644 --- a/multiton/README.md +++ b/multiton/README.md @@ -5,8 +5,7 @@ folder: multiton permalink: /patterns/multiton/ categories: Creational tags: - - Java - - Difficulty-Beginner + - Instantiation --- ## Also known as diff --git a/mute-idiom/README.md b/mute-idiom/README.md index 7df0ae1106b1..4d860dbef4db 100644 --- a/mute-idiom/README.md +++ b/mute-idiom/README.md @@ -3,11 +3,9 @@ layout: pattern title: Mute Idiom folder: mute-idiom permalink: /patterns/mute-idiom/ -categories: Other +categories: Idiom tags: - - Java - - Difficulty-Beginner - - Idiom + - Decoupling --- ## Intent diff --git a/mutex/README.md b/mutex/README.md index 14b465a60622..43ed8d94732d 100644 --- a/mutex/README.md +++ b/mutex/README.md @@ -5,13 +5,13 @@ folder: mutex permalink: /patterns/mutex/ categories: Concurrency tags: - - Java - - Difficulty-Intermediate + - Decoupling --- ## Also known as -Mutual Exclusion Lock -Binary Semaphore + +* Mutual Exclusion Lock +* Binary Semaphore ## Intent Create a lock which only allows a single thread to access a resource at any one instant. @@ -22,8 +22,8 @@ Create a lock which only allows a single thread to access a resource at any one ## Applicability Use a Mutex when -* you need to prevent two threads accessing a critical section at the same time -* concurrent access to a resource could lead to a race condition +* You need to prevent two threads accessing a critical section at the same time +* Concurrent access to a resource could lead to a race condition ## Credits diff --git a/naked-objects/README.md b/naked-objects/README.md index 3d3cdaab981d..bb38c81f27b7 100644 --- a/naked-objects/README.md +++ b/naked-objects/README.md @@ -5,8 +5,7 @@ folder: naked-objects permalink: /patterns/naked-objects/ categories: Architectural tags: - - Java - - Difficulty-Expert + - Decoupling --- ## Intent @@ -20,9 +19,9 @@ everything else is autogenerated by the framework. ## Applicability Use the Naked Objects pattern when -* you are prototyping and need fast development cycle -* an autogenerated user interface is good enough -* you want to automatically publish the domain as REST services +* You are prototyping and need fast development cycle +* An autogenerated user interface is good enough +* You want to automatically publish the domain as REST services ## Real world examples diff --git a/null-object/README.md b/null-object/README.md index 1be72a1b747b..d0a6f530dc5a 100644 --- a/null-object/README.md +++ b/null-object/README.md @@ -5,8 +5,7 @@ folder: null-object permalink: /patterns/null-object/ categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Extensibility --- ## Intent @@ -25,7 +24,8 @@ Object is very predictable and has no side effects: it does nothing. ## Applicability Use the Null Object pattern when -* you want to avoid explicit null checks and keep the algorithm elegant and easy to read. +* You want to avoid explicit null checks and keep the algorithm elegant and easy to read. ## Credits + * [Pattern Languages of Program Design](http://www.amazon.com/Pattern-Languages-Program-Design-Coplien/dp/0201607344/ref=sr_1_1) diff --git a/object-mother/README.md b/object-mother/README.md index bd4c14e1ce40..4c1a04ae2c02 100644 --- a/object-mother/README.md +++ b/object-mother/README.md @@ -5,8 +5,7 @@ folder: object-mother permalink: /patterns/object-mother/ categories: Creational tags: - - Java - - Difficulty-Beginner + - Instantiation --- ## Object Mother @@ -19,13 +18,11 @@ Define a factory of immutable content with separated builder and factory interfa Use the Object Mother pattern when * You want consistent objects over several tests -* you want to reduce code for creation of objects in tests -* every test should run with fresh data +* You want to reduce code for creation of objects in tests +* Every test should run with fresh data ## Credits * [Answer by David Brown](http://stackoverflow.com/questions/923319/what-is-an-objectmother) to the stackoverflow question: [What is an ObjectMother?](http://stackoverflow.com/questions/923319/what-is-an-objectmother) - * [c2wiki - Object Mother](http://c2.com/cgi/wiki?ObjectMother) - * [Nat Pryce - Test Data Builders: an alternative to the Object Mother pattern](http://www.natpryce.com/articles/000714.html) diff --git a/object-pool/README.md b/object-pool/README.md index f6b80539b3b4..efbf692ae1b8 100644 --- a/object-pool/README.md +++ b/object-pool/README.md @@ -5,8 +5,7 @@ folder: object-pool permalink: /patterns/object-pool/ categories: Creational tags: - - Java - - Difficulty-Beginner + - Game programming - Performance --- @@ -22,5 +21,5 @@ are in use and which are available. ## Applicability Use the Object Pool pattern when -* the objects are expensive to create (allocation cost) -* you need a large number of short-lived objects (memory fragmentation) +* The objects are expensive to create (allocation cost) +* You need a large number of short-lived objects (memory fragmentation) diff --git a/observer/README.md b/observer/README.md index 12a0a4677e84..7b31c7450746 100644 --- a/observer/README.md +++ b/observer/README.md @@ -5,8 +5,6 @@ folder: observer permalink: /patterns/observer/ categories: Behavioral tags: - - Java - - Difficulty-Beginner - Gang Of Four - Reactive --- @@ -25,13 +23,13 @@ automatically. ## Applicability Use the Observer pattern in any of the following situations -* when an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently -* when a change to one object requires changing others, and you don't know how many objects need to be changed -* when an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don't want these objects tightly coupled +* When an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently +* When a change to one object requires changing others, and you don't know how many objects need to be changed +* When an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don't want these objects tightly coupled ## Typical Use Case -* changing in one object leads to a change in other objects +* Changing in one object leads to a change in other objects ## Real world examples diff --git a/page-object/README.md b/page-object/README.md index 13586e0644ba..159cda6d1a51 100644 --- a/page-object/README.md +++ b/page-object/README.md @@ -3,10 +3,9 @@ layout: pattern title: Page Object folder: page-object permalink: /patterns/page-object/ -categories: Testing +categories: Structural tags: -- Java -- Difficulty-Intermediate +- Decoupling --- ## Intent diff --git a/partial-response/README.md b/partial-response/README.md index ebec3d97a54d..7894ca2ea376 100644 --- a/partial-response/README.md +++ b/partial-response/README.md @@ -3,12 +3,9 @@ layout: pattern title: Partial Response folder: partial-response permalink: /patterns/partial-response/ -categories: Architectural +categories: Behavioral tags: - - Java - - KISS - - YAGNI - - Difficulty-Beginner + - Decoupling --- ## Intent diff --git a/pipeline/README.md b/pipeline/README.md index 2afa6da9aa10..bc8f9399a928 100644 --- a/pipeline/README.md +++ b/pipeline/README.md @@ -5,9 +5,7 @@ folder: pipeline permalink: /patterns/pipeline/ categories: Behavioral tags: - - Java - - Functional - - Difficulty-Intermediate + - Decoupling --- ## Intent @@ -19,13 +17,13 @@ Allows processing of data in a series of stages by giving in an initial input an ## Applicability Use the Pipeline pattern when you want to -* execute individual stages that yields a final value -* add readability to complex sequence of operations by providing a fluent builder as an interface -* improve testability of code since stages will most likely be doing a single thing, complying to the [Single Responsibility Principle (SRP)](https://java-design-patterns.com/principles/#single-responsibility-principle) +* Execute individual stages that yields a final value +* Add readability to complex sequence of operations by providing a fluent builder as an interface +* Improve testability of code since stages will most likely be doing a single thing, complying to the [Single Responsibility Principle (SRP)](https://java-design-patterns.com/principles/#single-responsibility-principle) ## Typical Use Case -* implement stages and execute them in an ordered manner +* Implement stages and execute them in an ordered manner ## Real world examples diff --git a/poison-pill/README.md b/poison-pill/README.md index a4f8420864aa..7fd152891008 100644 --- a/poison-pill/README.md +++ b/poison-pill/README.md @@ -3,10 +3,9 @@ layout: pattern title: Poison Pill folder: poison-pill permalink: /patterns/poison-pill/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Intermediate + - Cloud distributed - Reactive --- @@ -20,7 +19,7 @@ graceful shutdown for separate distributed consumption process. ## Applicability Use the Poison Pill idiom when -* need to send signal from one thread/process to another to terminate +* Need to send signal from one thread/process to another to terminate ## Real world examples diff --git a/priority-queue/README.md b/priority-queue/README.md index 37a6e908d901..c8d1f7773cb9 100644 --- a/priority-queue/README.md +++ b/priority-queue/README.md @@ -5,8 +5,7 @@ folder: priority-queue permalink: /patterns/priority-queue/ categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent diff --git a/private-class-data/README.md b/private-class-data/README.md index 7937697c22cc..20e34328522e 100644 --- a/private-class-data/README.md +++ b/private-class-data/README.md @@ -3,11 +3,9 @@ layout: pattern title: Private Class Data folder: private-class-data permalink: /patterns/private-class-data/ -categories: Other +categories: Idiom tags: - - Java - - Difficulty-Beginner - - Idiom + - Data access --- ## Intent @@ -21,4 +19,4 @@ attributes by encapsulating them in single Data object. ## Applicability Use the Private Class Data pattern when -* you want to prevent write access to class data members +* You want to prevent write access to class data members diff --git a/producer-consumer/README.md b/producer-consumer/README.md index 12147af42016..eb0275aaf9c0 100644 --- a/producer-consumer/README.md +++ b/producer-consumer/README.md @@ -5,9 +5,6 @@ folder: producer-consumer permalink: /patterns/producer-consumer/ categories: Concurrency tags: - - Java - - Difficulty-Intermediate - - I/O - Reactive --- @@ -22,5 +19,5 @@ Producer Consumer Design pattern is a classic concurrency pattern which reduces ## Applicability Use the Producer Consumer idiom when -* decouple system by separate work in two process produce and consume. -* addresses the issue of different timing require to produce work or consuming work +* Decouple system by separate work in two process produce and consume. +* Addresses the issue of different timing require to produce work or consuming work diff --git a/promise/README.md b/promise/README.md index 3eb5efcb6f12..cf3d96c88b00 100644 --- a/promise/README.md +++ b/promise/README.md @@ -5,10 +5,7 @@ folder: promise permalink: /patterns/promise/ categories: Concurrency tags: - - Java - - Functional - Reactive - - Difficulty-Intermediate --- ## Also known as @@ -27,9 +24,9 @@ in a synchronous way. Promise pattern is applicable in concurrent programming when some work needs to be done asynchronously and: -* code maintainability and readability suffers due to callback hell. -* you need to compose promises and need better error handling for asynchronous tasks. -* you want to use functional style of programming. +* Code maintainability and readability suffers due to callback hell. +* You need to compose promises and need better error handling for asynchronous tasks. +* You want to use functional style of programming. ## Real world examples diff --git a/property/README.md b/property/README.md index 60d82434edf8..2eb684dd397d 100644 --- a/property/README.md +++ b/property/README.md @@ -5,8 +5,7 @@ folder: property permalink: /patterns/property/ categories: Creational tags: - - Java - - Difficulty-Beginner + - Instantiation --- ## Intent @@ -19,7 +18,7 @@ objects as parents. ## Applicability Use the Property pattern when -* when you like to have objects with dynamic set of fields and prototype inheritance +* When you like to have objects with dynamic set of fields and prototype inheritance ## Real world examples diff --git a/prototype/README.md b/prototype/README.md index fe796183cb89..1cbe6724479b 100644 --- a/prototype/README.md +++ b/prototype/README.md @@ -5,9 +5,8 @@ folder: prototype permalink: /patterns/prototype/ categories: Creational tags: - - Java - Gang Of Four - - Difficulty-Beginner + - Instantiation --- ## Intent @@ -68,10 +67,10 @@ System.out.println(cloned.getName()); // Dolly ## Applicability Use the Prototype pattern when a system should be independent of how its products are created, composed and represented; and -* when the classes to instantiate are specified at run-time, for example, by dynamic loading -* to avoid building a class hierarchy of factories that parallels the class hierarchy of products -* when instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state -* when object creation is expensive compared to cloning +* When the classes to instantiate are specified at run-time, for example, by dynamic loading +* To avoid building a class hierarchy of factories that parallels the class hierarchy of products +* When instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state +* When object creation is expensive compared to cloning ## Real world examples diff --git a/proxy/README.md b/proxy/README.md index e94ebfbc67c0..b5fae677de1c 100644 --- a/proxy/README.md +++ b/proxy/README.md @@ -5,9 +5,8 @@ folder: proxy permalink: /patterns/proxy/ categories: Structural tags: - - Java - Gang Of Four - - Difficulty-Beginner + - Decoupling --- ## Also known as @@ -130,6 +129,7 @@ are several common situations in which the Proxy pattern is applicable * Count references to an object ## Tutorials + * [Controlling Access With Proxy Pattern](http://java-design-patterns.com/blog/controlling-access-with-proxy-pattern/) ## Real world examples diff --git a/queue-load-leveling/README.md b/queue-load-leveling/README.md index f965448b2ffd..3674e74135ba 100644 --- a/queue-load-leveling/README.md +++ b/queue-load-leveling/README.md @@ -3,10 +3,9 @@ layout: pattern title: Queue based load leveling folder: queue-load-leveling permalink: /patterns/queue-load-leveling/ -categories: Other +categories: Concurrency tags: - - Java - - Difficulty-Intermediate + - Decoupling - Performance --- diff --git a/reactor/README.md b/reactor/README.md index e18595656ed7..9e66708dd73a 100644 --- a/reactor/README.md +++ b/reactor/README.md @@ -6,9 +6,8 @@ permalink: /patterns/reactor/ pumlformat: svg categories: Concurrency tags: - - Java - - Difficulty-Expert - - I/O + - Performance + - Reactive --- ## Intent @@ -20,9 +19,9 @@ The Reactor design pattern handles service requests that are delivered concurren ## Applicability Use Reactor pattern when -* a server application needs to handle concurrent service requests from multiple clients. -* a server application needs to be available for receiving requests from new clients even when handling older client requests. -* a server must maximize throughput, minimize latency and use CPU efficiently without blocking. +* A server application needs to handle concurrent service requests from multiple clients. +* A server application needs to be available for receiving requests from new clients even when handling older client requests. +* A server must maximize throughput, minimize latency and use CPU efficiently without blocking. ## Real world examples diff --git a/reader-writer-lock/README.md b/reader-writer-lock/README.md index 30cbc0dc5d0a..d5f1d9d12ddc 100644 --- a/reader-writer-lock/README.md +++ b/reader-writer-lock/README.md @@ -5,9 +5,6 @@ folder: reader-writer-lock permalink: /patterns/reader-writer-lock/ categories: Concurrency tags: - - Java - - Difficulty-Intermediate - - I/O - Performance --- @@ -29,5 +26,4 @@ Application need to increase the performance of resource synchronize for multip ## Credits * [Readers–writer lock](https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock) - -* [Readers–writers_problem](https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem) \ No newline at end of file +* [Readers–writers_problem](https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem) diff --git a/repository/README.md b/repository/README.md index 400e37eb0d64..b500d2efd870 100644 --- a/repository/README.md +++ b/repository/README.md @@ -3,11 +3,9 @@ layout: pattern title: Repository folder: repository permalink: /patterns/repository/ -categories: Persistence Tier +categories: Architectural tags: - - Java - - Difficulty-Intermediate - - Spring + - Data access --- ## Intent @@ -23,10 +21,10 @@ querying is utilized. ## Applicability Use the Repository pattern when -* the number of domain objects is large -* you want to avoid duplication of query code -* you want to keep the database querying code in single place -* you have multiple data sources +* The number of domain objects is large +* You want to avoid duplication of query code +* You want to keep the database querying code in single place +* You have multiple data sources ## Real world examples diff --git a/resource-acquisition-is-initialization/README.md b/resource-acquisition-is-initialization/README.md index 3591cf915b02..02b28c4a1afb 100644 --- a/resource-acquisition-is-initialization/README.md +++ b/resource-acquisition-is-initialization/README.md @@ -3,11 +3,9 @@ layout: pattern title: Resource Acquisition Is Initialization folder: resource-acquisition-is-initialization permalink: /patterns/resource-acquisition-is-initialization/ -categories: Other +categories: Idiom tags: - - Java - - Difficulty-Beginner - - Idiom + - Data access --- ## Intent @@ -19,4 +17,4 @@ Resource Acquisition Is Initialization pattern can be used to implement exceptio ## Applicability Use the Resource Acquisition Is Initialization pattern when -* you have resources that must be closed in every condition +* You have resources that must be closed in every condition diff --git a/retry/README.md b/retry/README.md index 59958403c79a..27325331de08 100644 --- a/retry/README.md +++ b/retry/README.md @@ -3,10 +3,8 @@ layout: pattern title: Retry folder: retry permalink: /patterns/retry/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Expert - Performance --- @@ -151,4 +149,5 @@ You can view Microsoft's article [here](https://docs.microsoft.com/en-us/azure/a * Operations maintenance ## Related Patterns + * [Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html) diff --git a/role-object/README.md b/role-object/README.md index e5378afdec39..424c64cda69b 100644 --- a/role-object/README.md +++ b/role-object/README.md @@ -5,9 +5,7 @@ folder: role-object permalink: /patterns/role-object/ categories: Structural tags: - - Java - - Difficulty-Medium - - Handle Body Pattern + - Extensibility --- ## Also known as @@ -23,12 +21,14 @@ individual objects, different contexts are kept separate and system configuratio ## Applicability Use the Role Object pattern, if: -- you want to handle a key abstraction in different contexts and you do not want to put the resulting context specific interfaces into the same class interface. -- you want to handle the available roles dynamically so that they can be attached and removed on demand, that is at runtime, rather than fixing them statically at compile-time. -- you want to treat the extensions transparently and need to preserve the logical object identity of the resultingobject conglomerate. -- you want to keep role/client pairs independent from each other so that changes to a role do not affect clients that are not interested in that role. + +- You want to handle a key abstraction in different contexts and you do not want to put the resulting context specific interfaces into the same class interface. +- You want to handle the available roles dynamically so that they can be attached and removed on demand, that is at runtime, rather than fixing them statically at compile-time. +- You want to treat the extensions transparently and need to preserve the logical object identity of the resultingobject conglomerate. +- You want to keep role/client pairs independent from each other so that changes to a role do not affect clients that are not interested in that role. ## Credits + - [Hillside - Role object pattern](https://hillside.net/plop/plop97/Proceedings/riehle.pdf) - [Role object](http://wiki.c2.com/?RoleObject) -- [Fowler - Dealing with roles](https://martinfowler.com/apsupp/roles.pdf) \ No newline at end of file +- [Fowler - Dealing with roles](https://martinfowler.com/apsupp/roles.pdf) diff --git a/saga/README.md b/saga/README.md index bfb39461a8a8..50aeb7d7375f 100644 --- a/saga/README.md +++ b/saga/README.md @@ -3,12 +3,9 @@ layout: pattern title: Saga folder: saga permalink: /patterns/saga/ -categories: Behavioral +categories: Concurrency tags: - - Java - - Difficulty-Expert - - Idiom - - Distributed communication + - Cloud distributed --- ## Also known as @@ -40,10 +37,12 @@ This orchestrator can also be though of as a Saga Manager. ## Applicability Use the Saga pattern, if: + - you need to perform a group of operations related to different microservices atomically - you need to rollback changes in different places in case of failure one of the operation - you need to take care of data consistency in different places including different databases - you can not use 2PC(two phase commit) ## Credits -- [Pattern: Saga](https://microservices.io/patterns/data/saga.html) \ No newline at end of file + +- [Pattern: Saga](https://microservices.io/patterns/data/saga.html) diff --git a/semaphore/README.md b/semaphore/README.md index a59d7b398f57..be882e04a781 100644 --- a/semaphore/README.md +++ b/semaphore/README.md @@ -5,8 +5,7 @@ folder: semaphore permalink: /patterns/semaphore/ categories: Concurrency tags: - - Java - - Difficulty-Intermediate + - Performance --- ## Also known as @@ -25,8 +24,8 @@ is called a binary semaphore. ## Applicability Use a Semaphore when -* you have a pool of resources to allocate to different threads -* concurrent access to a resource could lead to a race condition +* You have a pool of resources to allocate to different threads +* Concurrent access to a resource could lead to a race condition ## Credits diff --git a/servant/README.md b/servant/README.md index 67470b678dbc..85ad6872d58d 100644 --- a/servant/README.md +++ b/servant/README.md @@ -3,10 +3,9 @@ layout: pattern title: Servant folder: servant permalink: /patterns/servant/ -categories: Structural +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent @@ -20,7 +19,8 @@ this behavior in the common parent class - it is defined once in the Servant. ## Applicability Use the Servant pattern when -* when we want some objects to perform a common action and don't want to define this action as a method in every class. +* When we want some objects to perform a common action and don't want to define this action as a method in every class. ## Credits + * [Let's Modify the Objects-First Approach into Design-Patterns-First](http://edu.pecinovsky.cz/papers/2006_ITiCSE_Design_Patterns_First.pdf) diff --git a/serverless/README.md b/serverless/README.md index 46e646f069b3..c33c034e6ce7 100644 --- a/serverless/README.md +++ b/serverless/README.md @@ -5,8 +5,7 @@ folder: serverless permalink: /patterns/serverless/ categories: Architectural tags: - - Java - - Difficulty-Intermediate + - Cloud distributed --- ## Serverless @@ -126,6 +125,7 @@ dependencies of the function. ## Run example in local # Pre-requisites + * Node.js v6.5.0 or later. * Serverless CLI v1.9.0 or later. You can run npm install -g serverless to install it. * An AWS account. If you don't already have one, you can sign up for a free trial that includes 1 million free Lambda requests per month. @@ -139,6 +139,7 @@ dependencies of the function. Based on the configuration in `serverless.yml` serverless framework creates following resources + * CloudFormation stack for S3 (ServerlessDeploymentBucket) * IAM Role (IamRoleLambdaExecution) * CloudWatch (log groups) @@ -199,4 +200,4 @@ curl -X GET \ * [serverless docs](https://serverless.com/framework/docs/) * [Serverless Architectures](https://martinfowler.com/articles/serverless.html) -* [Serverless Black Belt](https://youtu.be/oQFORsso2go) \ No newline at end of file +* [Serverless Black Belt](https://youtu.be/oQFORsso2go) diff --git a/service-layer/README.md b/service-layer/README.md index 9abb6294a531..b2b61a17a466 100644 --- a/service-layer/README.md +++ b/service-layer/README.md @@ -5,8 +5,7 @@ folder: service-layer permalink: /patterns/service-layer/ categories: Architectural tags: - - Java - - Difficulty-Intermediate + - Data access --- ## Intent @@ -23,8 +22,8 @@ its business logic. The Service Layer fulfills this role. ## Applicability Use the Service Layer pattern when -* you want to encapsulate domain logic under API -* you need to implement multiple interfaces with common logic and data +* You want to encapsulate domain logic under API +* You need to implement multiple interfaces with common logic and data ## Credits diff --git a/service-locator/README.md b/service-locator/README.md index 0be75f11710a..16c10f4de97c 100644 --- a/service-locator/README.md +++ b/service-locator/README.md @@ -3,10 +3,9 @@ layout: pattern title: Service Locator folder: service-locator permalink: /patterns/service-locator/ -categories: Structural +categories: Architectural tags: - - Java - - Difficulty-Beginner + - Game programming - Performance --- @@ -29,9 +28,9 @@ improves the performance of application to great extent. ## Typical Use Case -* when network hits are expensive and time consuming -* lookups of services are done quite frequently -* large number of services are being used +* When network hits are expensive and time consuming +* Lookups of services are done quite frequently +* Large number of services are being used ## Consequences diff --git a/sharding/README.md b/sharding/README.md index aeeb71828fdb..2ee465401668 100644 --- a/sharding/README.md +++ b/sharding/README.md @@ -3,10 +3,10 @@ layout: pattern title: Sharding folder: sharding permalink: /patterns/sharding/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Performance + - Cloud distributed --- ## Intent diff --git a/singleton/README.md b/singleton/README.md index d82f7d862f87..8c145f1df8be 100644 --- a/singleton/README.md +++ b/singleton/README.md @@ -5,9 +5,7 @@ folder: singleton permalink: /patterns/singleton/ categories: Creational tags: - - Java - - Gang Of Four - - Difficulty-Beginner + - Gang of Four --- ## Intent @@ -54,14 +52,14 @@ assertEquals(enumIvoryTower1, enumIvoryTower2); // true ## Applicability Use the Singleton pattern when -* there must be exactly one instance of a class, and it must be accessible to clients from a well-known access point -* when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code +* There must be exactly one instance of a class, and it must be accessible to clients from a well-known access point +* When the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code ## Typical Use Case -* the logging class -* managing a connection to a database -* file manager +* The logging class +* Managing a connection to a database +* File manager ## Real world examples diff --git a/spatial-partition/README.md b/spatial-partition/README.md index 5206708bcdbd..8484de876ce0 100644 --- a/spatial-partition/README.md +++ b/spatial-partition/README.md @@ -3,10 +3,10 @@ layout: pattern title: Spatial Partition folder: spatial-partition permalink: /patterns/spatial-partition/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Intermediate + - Performance + - Game programming --- ## Intent @@ -48,9 +48,11 @@ In our implementation, we use the Quadtree data structure which will reduce the ## Applicability This pattern can be used: + * When you need to keep track of a large number of objects' positions, which are getting updated every frame. * When it is acceptable to trade memory for speed, since creating and updating data structure will use up extra memory. ## Credits + * [Game Programming Patterns/Spatial Partition](http://gameprogrammingpatterns.com/spatial-partition.html) by Bob Nystrom * [Quadtree tutorial](https://www.youtube.com/watch?v=OJxEcs0w_kE) by Daniel Schiffman diff --git a/specification/README.md b/specification/README.md index 8c32a7875149..d5e7edf20bed 100644 --- a/specification/README.md +++ b/specification/README.md @@ -5,9 +5,7 @@ folder: specification permalink: /patterns/specification/ categories: Behavioral tags: - - Java - - Difficulty-Beginner - - Searching + - Data access --- ## Also known as diff --git a/state/README.md b/state/README.md index 726d842ae38d..d41b75df1bb3 100644 --- a/state/README.md +++ b/state/README.md @@ -5,9 +5,7 @@ folder: state permalink: /patterns/state/ categories: Behavioral tags: - - Java - - Difficulty-Intermediate - - Gang Of Four + - Gang of Four --- ## Also known as @@ -23,8 +21,8 @@ changes. The object will appear to change its class. ## Applicability Use the State pattern in either of the following cases -* an object's behavior depends on its state, and it must change its behavior at run-time depending on that state -* operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects. +* An object's behavior depends on its state, and it must change its behavior at run-time depending on that state +* Operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects. ## Real world examples diff --git a/step-builder/README.md b/step-builder/README.md index b4394496d138..3fdbf49f447d 100644 --- a/step-builder/README.md +++ b/step-builder/README.md @@ -5,8 +5,7 @@ folder: step-builder permalink: /patterns/step-builder/ categories: Creational tags: - - Java - - Difficulty-Intermediate + - Instantiation --- ## Intent diff --git a/strategy/README.md b/strategy/README.md index b6f41c02712a..4c6f889e151a 100644 --- a/strategy/README.md +++ b/strategy/README.md @@ -5,9 +5,7 @@ folder: strategy permalink: /patterns/strategy/ categories: Behavioral tags: - - Java - - Difficulty-Beginner - - Gang Of Four + - Gang of Four --- ## Also known as @@ -24,12 +22,13 @@ that use it. ## Applicability Use the Strategy pattern when -* many related classes differ only in their behavior. Strategies provide a way to configure a class either one of many behaviors -* you need different variants of an algorithm. for example, you might define algorithms reflecting different space/time trade-offs. Strategies can be used when these variants are implemented as a class hierarchy of algorithms -* an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures -* a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class +* Many related classes differ only in their behavior. Strategies provide a way to configure a class either one of many behaviors +* You need different variants of an algorithm. for example, you might define algorithms reflecting different space/time trade-offs. Strategies can be used when these variants are implemented as a class hierarchy of algorithms +* An algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures +* A class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class ## Tutorial + * [Strategy Pattern Tutorial](https://www.journaldev.com/1754/strategy-design-pattern-in-java-example-tutorial) ## Credits diff --git a/subclass-sandbox/README.md b/subclass-sandbox/README.md index 8fb0342792d1..311166d12975 100644 --- a/subclass-sandbox/README.md +++ b/subclass-sandbox/README.md @@ -3,10 +3,9 @@ layout: pattern title: Subclass Sandbox folder: subclass-sandbox permalink: /patterns/subclass-sandbox/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Game programming --- ## Intent @@ -19,13 +18,10 @@ The subclass sandbox pattern describes a basic idea, while not having a lot of d The Subclass Sandbox pattern is a very simple, common pattern lurking in lots of codebases, even outside of games. If you have a non-virtual protected method laying around, you’re probably already using something like this. Subclass Sandbox is a good fit when: - You have a base class with a number of derived classes. - - The base class is able to provide all of the operations that a derived class may need to perform. - - There is behavioral overlap in the subclasses and you want to make it easier to share code between them. - - You want to minimize coupling between those derived classes and the rest of the program. ## Credits -* [Game Programming Patterns - Subclass Sandbox]([http://gameprogrammingpatterns.com/subclass-sandbox.html](http://gameprogrammingpatterns.com/subclass-sandbox.html)) \ No newline at end of file +* [Game Programming Patterns - Subclass Sandbox]([http://gameprogrammingpatterns.com/subclass-sandbox.html](http://gameprogrammingpatterns.com/subclass-sandbox.html)) diff --git a/template-method/README.md b/template-method/README.md index b1ad04fb63e5..668d6e28c9d5 100644 --- a/template-method/README.md +++ b/template-method/README.md @@ -5,9 +5,7 @@ folder: template-method permalink: /patterns/template-method/ categories: Behavioral tags: - - Java - - Difficulty-Beginner - - Gang Of Four + - Gang of Four --- ## Intent @@ -22,17 +20,21 @@ To make sure that subclasses don’t override the template method, the template ## Applicability The Template Method pattern should be used -* to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary -* when common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is good example of "refactoring to generalize" as described by Opdyke and Johnson. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations -* to control subclasses extensions. You can define a template method that calls "hook" operations at specific points, thereby permitting extensions only at those points + +* To implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary +* When common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is good example of "refactoring to generalize" as described by Opdyke and Johnson. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations +* To control subclasses extensions. You can define a template method that calls "hook" operations at specific points, thereby permitting extensions only at those points ## Tutorial + * [Template-method Pattern Tutorial](https://www.journaldev.com/1763/template-method-design-pattern-in-java) ## Real world examples + * [javax.servlet.GenericServlet.init](https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/GenericServlet.html#init--): Method `GenericServlet.init(ServletConfig config)` calls the parameterless method `GenericServlet.init()` which is intended to be overridden in subclasses. Method `GenericServlet.init(ServletConfig config)` is the template method in this example. ## Credits + * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) diff --git a/thread-pool/README.md b/thread-pool/README.md index 445fba07bdc0..0e125176d0dc 100644 --- a/thread-pool/README.md +++ b/thread-pool/README.md @@ -5,8 +5,6 @@ folder: thread-pool permalink: /patterns/thread-pool/ categories: Concurrency tags: - - Java - - Difficulty-Intermediate - Performance --- @@ -23,4 +21,4 @@ and eliminating the latency of creating new threads. ## Applicability Use the Thread Pool pattern when -* you have a large number of short-lived tasks to be executed in parallel +* You have a large number of short-lived tasks to be executed in parallel diff --git a/throttling/README.md b/throttling/README.md index ad0361f3914d..12090c5e30b0 100644 --- a/throttling/README.md +++ b/throttling/README.md @@ -5,8 +5,7 @@ folder: throttling permalink: /patterns/throttling/ categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Performance --- ## Intent @@ -18,5 +17,5 @@ Ensure that a given client is not able to access service resources more than the ## Applicability The Throttling pattern should be used: -* when a service access needs to be restricted to not have high impacts on the performance of the service. -* when multiple clients are consuming the same service resources and restriction has to be made according to the usage per client. +* When a service access needs to be restricted to not have high impacts on the performance of the service. +* When multiple clients are consuming the same service resources and restriction has to be made according to the usage per client. diff --git a/tls/README.md b/tls/README.md index ac4aa249048b..3700795a03e4 100644 --- a/tls/README.md +++ b/tls/README.md @@ -3,11 +3,9 @@ layout: pattern title: Thread Local Storage folder: tls permalink: /patterns/tls/ -pumlid: -categories: Concurrency +categories: Idiom tags: - - Java - - Difficulty-Intermediate + - Performance --- ## Intent @@ -19,5 +17,5 @@ Securing variables global to a thread against being spoiled by other threads. Th ## Applicability Use the Thread Local Storage in any of the following situations -* when you use class variables in your Callable / Runnable object that are not read-only and you use the same Callable instance in more than one thread running in parallel. -* when you use static variables in your Callable / Runnable object that are not read-only and more than one instances of the Callable / Runnable may run in parallel threads. +* When you use class variables in your Callable / Runnable object that are not read-only and you use the same Callable instance in more than one thread running in parallel. +* When you use static variables in your Callable / Runnable object that are not read-only and more than one instances of the Callable / Runnable may run in parallel threads. diff --git a/tolerant-reader/README.md b/tolerant-reader/README.md index 5ba0fd09f0b9..c60e757073df 100644 --- a/tolerant-reader/README.md +++ b/tolerant-reader/README.md @@ -5,8 +5,7 @@ folder: tolerant-reader permalink: /patterns/tolerant-reader/ categories: Integration tags: - - Java - - Difficulty-Beginner + - Decoupling --- ## Intent @@ -21,7 +20,7 @@ changes, the readers must not break. ## Applicability Use the Tolerant Reader pattern when -* the communication schema can evolve and change and yet the receiving side should not break +* The communication schema can evolve and change and yet the receiving side should not break ## Credits diff --git a/trampoline/README.md b/trampoline/README.md index 77b4daa7b7c0..2356e87153bd 100644 --- a/trampoline/README.md +++ b/trampoline/README.md @@ -5,10 +5,7 @@ folder: trampoline permalink: /patterns/trampoline/ categories: Behavioral tags: - - Java - - Difficulty-Intermediate - Performance - - Recursion --- ## Intent @@ -31,14 +28,17 @@ Use the Trampoline pattern when * For interleaving the execution of two or more functions on the same thread. ## Known uses(real world examples) + * Trampoline refers to using reflection to avoid using inner classes, for example in event listeners. The time overhead of a reflection call is traded for the space overhead of an inner class. Trampolines in Java usually involve the creation of a GenericListener to pass events to an outer class. ## Tutorials + * [Trampolining: a practical guide for awesome Java Developers](https://medium.com/@johnmcclean/trampolining-a-practical-guide-for-awesome-java-developers-4b657d9c3076) * [Trampoline in java ](http://mindprod.com/jgloss/trampoline.html) ## Credits + * [library 'cyclops-react' uses the pattern](https://github.com/aol/cyclops-react) diff --git a/twin/README.md b/twin/README.md index cc7198ff431a..ed70768922af 100644 --- a/twin/README.md +++ b/twin/README.md @@ -3,14 +3,13 @@ layout: pattern title: Twin folder: twin permalink: /patterns/twin/ -categories: Creational +categories: Structural tags: - - Java - - Difficulty-Intermediate + - Extensibility --- ## Intent - Twin pattern is a design pattern which provides a standard solution to simulate multiple +Twin pattern is a design pattern which provides a standard solution to simulate multiple inheritance in java ## Class diagram @@ -19,8 +18,8 @@ inheritance in java ## Applicability Use the Twin idiom when -* to simulate multiple inheritance in a language that does not support this feature. -* to avoid certain problems of multiple inheritance such as name clashes. +* To simulate multiple inheritance in a language that does not support this feature. +* To avoid certain problems of multiple inheritance such as name clashes. ## Credits diff --git a/typeobjectpattern/README.md b/typeobjectpattern/README.md index 4cc49e9b7ac4..a5a193c54e0b 100644 --- a/typeobjectpattern/README.md +++ b/typeobjectpattern/README.md @@ -3,10 +3,10 @@ layout: pattern title: Type-Object folder: typeobjectpattern permalink: /patterns/typeobjectpattern/ -categories: Game Programming Patterns/Behavioral Patterns +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Game programming + - Extensibility --- ## Intent @@ -23,10 +23,12 @@ Using the type-object pattern, instead of creating many classes inheriting from ## Applicability This pattern can be used when: + * We don’t know what types we will need up front. * We want to be able to modify or add new types without having to recompile or change code. * Only difference between the different 'types' of objects is the data, not the behaviour. ## Credits + * [Game Programming Patterns/Type Object](http://gameprogrammingpatterns.com/type-object.html) by Robert Nystrom * [http://www.cs.sjsu.edu/~pearce/modules/patterns/analysis/top.htm] diff --git a/unit-of-work/README.md b/unit-of-work/README.md index a7c9112203c4..21f653b7df34 100644 --- a/unit-of-work/README.md +++ b/unit-of-work/README.md @@ -6,10 +6,7 @@ permalink: /patterns/unit-of-work/ categories: Architectural tags: - - Java - - KISS - - YAGNI - - Difficulty-Beginner + - Data access --- ## Intent diff --git a/update-method/README.md b/update-method/README.md index 73c5fe358c41..1404f2c52155 100644 --- a/update-method/README.md +++ b/update-method/README.md @@ -3,10 +3,9 @@ layout: pattern title: Update Method folder: update-method permalink: /patterns/update-method/ -categories: Other +categories: Behavioral tags: - - Java - - Difficulty-Beginner + - Game programming --- ## Intent @@ -28,9 +27,7 @@ However, if the game is more abstract and the moving pieces are less like living Update methods work well when: - Your game has a number of objects or systems that need to run simultaneously. - - Each object’s behavior is mostly independent of the others. - - The objects need to be simulated over time. ## Credits diff --git a/value-object/README.md b/value-object/README.md index 4fa384037de1..ee6d7143bfe0 100644 --- a/value-object/README.md +++ b/value-object/README.md @@ -5,8 +5,7 @@ folder: value-object permalink: /patterns/value-object/ categories: Creational tags: - - Java - - Difficulty-Beginner + - Instantiation --- ## Intent @@ -20,7 +19,7 @@ equal when they have the same value, not necessarily being the same object. ## Applicability Use the Value Object when -* you need to measure the objects' equality based on the objects' value +* You need to measure the objects' equality based on the objects' value ## Real world examples diff --git a/visitor/README.md b/visitor/README.md index f7a1dc17a87a..382752610a87 100644 --- a/visitor/README.md +++ b/visitor/README.md @@ -5,9 +5,7 @@ folder: visitor permalink: /patterns/visitor/ categories: Behavioral tags: - - Java - - Difficulty-Intermediate - - Gang Of Four + - Gang of Four --- ## Intent @@ -21,9 +19,9 @@ of the elements on which it operates. ## Applicability Use the Visitor pattern when -* an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes -* many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them -* the classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes +* An object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes +* Many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them +* The classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes ## Real world examples