diff --git a/pom.xml b/pom.xml index e7fd2e4b3f87cebfab7286289f6c3fcb647482dd..86cefa13386a8d7fa2c3c092127969a65f82178b 100644 --- a/pom.xml +++ b/pom.xml @@ -195,6 +195,7 @@ strangler arrange-act-assert transaction-script + registry filterer factory separated-interface diff --git a/registry/README.md b/registry/README.md new file mode 100644 index 0000000000000000000000000000000000000000..699c133182633d258578db01f277f8ba74ac2c28 --- /dev/null +++ b/registry/README.md @@ -0,0 +1,86 @@ +--- +layout: pattern +title: Registry +folder: registry +permalink: /patterns/registry/ +categories: Creational +tags: + - Instantiation +--- + +## Intent +Stores the objects of a single class and provide a global point of access to them. +Similar to Multiton pattern, only difference is that in a registry there is no restriction on the number of objects. + +## Explanation + +In Plain Words + +> Registry is a well-known object that other objects can use to find common objects and services. + +**Programmatic Example** +Below is a `Customer` Class + +```java +public class Customer { + + private final String id; + private final String name; + + public Customer(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + +} +``` + +This registry of the `Customer` objects is `CustomerRegistry` +```java +public final class CustomerRegistry { + + private static final CustomerRegistry instance = new CustomerRegistry(); + + public static CustomerRegistry getInstance() { + return instance; + } + + private final Map customerMap; + + private CustomerRegistry() { + customerMap = new ConcurrentHashMap<>(); + } + + public Customer addCustomer(Customer customer) { + return customerMap.put(customer.getId(), customer); + } + + public Customer getCustomer(String id) { + return customerMap.get(id); + } + +} +``` + +## Class diagram +![Registry](./etc/registry.png) + +## Applicability +Use Registry pattern when + +* client wants reference of some object, so client can lookup for that object in the object's registry. + +## Consequences +Large number of bulky objects added to registry would result in a lot of memory consumption as objects in the registry are not garbage collected. + +## Credits +* https://www.martinfowler.com/eaaCatalog/registry.html +* https://wiki.c2.com/?RegistryPattern diff --git a/registry/etc/registry.png b/registry/etc/registry.png new file mode 100644 index 0000000000000000000000000000000000000000..6c1c5b986d72cb33d1806c8d43ebc4a31e4927c9 Binary files /dev/null and b/registry/etc/registry.png differ diff --git a/registry/etc/registry.urm.puml b/registry/etc/registry.urm.puml new file mode 100644 index 0000000000000000000000000000000000000000..77c6441fe6886fe8a03bac862bae9e0ad2a22e03 --- /dev/null +++ b/registry/etc/registry.urm.puml @@ -0,0 +1,21 @@ +@startuml +package com.iluwatar.registry { + class App { + - LOGGER : Logger {static} + + App() + + main(args : String[]) {static} + } + class Customer { + - id : String + - name : String + + getId() : String + + getName() : String + + toString() : String + } + class CustomerRegistry { + + addCustomer(customer : Customer) + + getCustomer(id : String) + } +} +Customer --> "-addCustomer" CustomerRegistry +@enduml diff --git a/registry/pom.xml b/registry/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..852bcacfd73ce9aaf630c90427f14a636889567d --- /dev/null +++ b/registry/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + + com.iluwatar + java-design-patterns + 1.24.0-SNAPSHOT + + registry + + + + org.junit.jupiter + junit-jupiter-engine + test + + + junit + junit + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.registry.App + + + + + + + + + + diff --git a/registry/src/main/java/com/iluwatar/registry/App.java b/registry/src/main/java/com/iluwatar/registry/App.java new file mode 100644 index 0000000000000000000000000000000000000000..a593ce5cc15b50b50348acb6c1a76d0f6469d2cc --- /dev/null +++ b/registry/src/main/java/com/iluwatar/registry/App.java @@ -0,0 +1,27 @@ +package com.iluwatar.registry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class App { + + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + /** + * Program entry point. + * + * @param args command line args + */ + public static void main(String[] args) { + CustomerRegistry customerRegistry = CustomerRegistry.getInstance(); + var john = new Customer("1", "John"); + customerRegistry.addCustomer(john); + + var julia = new Customer("2", "Julia"); + customerRegistry.addCustomer(julia); + + LOGGER.info("John {}", customerRegistry.getCustomer("1")); + LOGGER.info("Julia {}", customerRegistry.getCustomer("2")); + } + +} diff --git a/registry/src/main/java/com/iluwatar/registry/Customer.java b/registry/src/main/java/com/iluwatar/registry/Customer.java new file mode 100644 index 0000000000000000000000000000000000000000..354999fdf2ce5e91ad7b4e9c9c352a51070bedf5 --- /dev/null +++ b/registry/src/main/java/com/iluwatar/registry/Customer.java @@ -0,0 +1,28 @@ +package com.iluwatar.registry; + +public class Customer { + + private final String id; + private final String name; + + public Customer(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "Customer{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/registry/src/main/java/com/iluwatar/registry/CustomerRegistry.java b/registry/src/main/java/com/iluwatar/registry/CustomerRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..406d616c678c80c2ca4f4f5f4108ffc580841f2f --- /dev/null +++ b/registry/src/main/java/com/iluwatar/registry/CustomerRegistry.java @@ -0,0 +1,28 @@ +package com.iluwatar.registry; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public final class CustomerRegistry { + + private static final CustomerRegistry instance = new CustomerRegistry(); + + public static CustomerRegistry getInstance() { + return instance; + } + + private final Map customerMap; + + private CustomerRegistry() { + customerMap = new ConcurrentHashMap<>(); + } + + public Customer addCustomer(Customer customer) { + return customerMap.put(customer.getId(), customer); + } + + public Customer getCustomer(String id) { + return customerMap.get(id); + } + +} diff --git a/registry/src/test/java/com/iluwatar/registry/CustomerRegistryTest.java b/registry/src/test/java/com/iluwatar/registry/CustomerRegistryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2919390b9270fbfb351afea95f68c9b907fa2582 --- /dev/null +++ b/registry/src/test/java/com/iluwatar/registry/CustomerRegistryTest.java @@ -0,0 +1,44 @@ +package com.iluwatar.registry; + +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.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class CustomerRegistryTest { + + private static CustomerRegistry customerRegistry; + + @BeforeAll + public static void setUp() { + customerRegistry = CustomerRegistry.getInstance(); + } + + @Test + public void shouldBeAbleToAddAndQueryCustomerObjectFromRegistry() { + Customer john = new Customer("1", "john"); + Customer julia = new Customer("2", "julia"); + + customerRegistry.addCustomer(john); + customerRegistry.addCustomer(julia); + + Customer customerWithId1 = customerRegistry.getCustomer("1"); + assertNotNull(customerWithId1); + assertEquals("1", customerWithId1.getId()); + assertEquals("john", customerWithId1.getName()); + + Customer customerWithId2 = customerRegistry.getCustomer("2"); + assertNotNull(customerWithId2); + assertEquals("2", customerWithId2.getId()); + assertEquals("julia", customerWithId2.getName()); + } + + @Test + public void shouldReturnNullWhenQueriedCustomerIsNotInRegistry() { + Customer customerWithId5 = customerRegistry.getCustomer("5"); + assertNull(customerWithId5); + } + +}