From e498c25675856e00a8c122be5e01bf390f748a72 Mon Sep 17 00:00:00 2001 From: Tao <66189688+tao-sun2@users.noreply.github.com> Date: Tue, 18 May 2021 03:06:35 +0800 Subject: [PATCH] feature: #1319 add table module pattern (#1742) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * modify table module pattern * fix code smells * resolve conversation Co-authored-by: tao-sun2 Co-authored-by: Ilkka Seppälä --- pom.xml | 1 + table-module/README.md | 134 ++++++++++++++++++ table-module/etc/table-module.urm.png | Bin 0 -> 77337 bytes table-module/etc/table-module.urm.puml | 38 +++++ table-module/pom.xml | 73 ++++++++++ .../java/com/iluwatar/tablemodule/App.java | 81 +++++++++++ .../java/com/iluwatar/tablemodule/User.java | 23 +++ .../iluwatar/tablemodule/UserTableModule.java | 96 +++++++++++++ .../com/iluwatar/tablemodule/AppTest.java | 16 +++ .../tablemodule/UserTableModuleTest.java | 78 ++++++++++ .../com/iluwatar/tablemodule/UserTest.java | 131 +++++++++++++++++ 11 files changed, 671 insertions(+) create mode 100644 table-module/README.md create mode 100644 table-module/etc/table-module.urm.png create mode 100644 table-module/etc/table-module.urm.puml create mode 100644 table-module/pom.xml create mode 100644 table-module/src/main/java/com/iluwatar/tablemodule/App.java create mode 100644 table-module/src/main/java/com/iluwatar/tablemodule/User.java create mode 100644 table-module/src/main/java/com/iluwatar/tablemodule/UserTableModule.java create mode 100644 table-module/src/test/java/com/iluwatar/tablemodule/AppTest.java create mode 100644 table-module/src/test/java/com/iluwatar/tablemodule/UserTableModuleTest.java create mode 100644 table-module/src/test/java/com/iluwatar/tablemodule/UserTest.java diff --git a/pom.xml b/pom.xml index 1b8f30e92..8173972bd 100644 --- a/pom.xml +++ b/pom.xml @@ -225,6 +225,7 @@ active-object model-view-viewmodel composite-entity + table-module presentation lockable-object diff --git a/table-module/README.md b/table-module/README.md new file mode 100644 index 000000000..318a2694d --- /dev/null +++ b/table-module/README.md @@ -0,0 +1,134 @@ +--- +layout: pattern +title: Table Module +folder: table-module +permalink: /patterns/table-module/ +categories: Structural +tags: + - Data access +--- +## Intent +Table Module organizes domain logic with one class per table in the database, and a single instance of a class contains the various procedures that will act on the data. + +## Explanation + +Real world example + +> When dealing with a user system, we need some operations on the user table. We can use the table module pattern in this scenario. We can create a class named UserTableModule and initialize a instance of that class to handle the business logic for all rows in the user table. + +In plain words + +> A single instance that handles the business logic for all rows in a database table or view. + +Programmatic Example + +In the example of the user system, we need to deal with the domain logic of user login and user registration. We can use the table module pattern and create an instance of the class `UserTableModule` to handle the business logic for all rows in the user table. + +Here is the basic `User` entity. + +```java +@Setter +@Getter +@ToString +@EqualsAndHashCode +@AllArgsConstructor +public class User { + private int id; + private String username; + private String password; +} +``` + +Here is the `UserTableModule` class. + +```java +public class UserTableModule { + private final DataSource dataSource; + private Connection connection = null; + private ResultSet resultSet = null; + private PreparedStatement preparedStatement = null; + + public UserTableModule(final DataSource userDataSource) { + this.dataSource = userDataSource; + } + + /** + * Login using username and password. + * + * @param username the username of a user + * @param password the password of a user + * @return the execution result of the method + * @throws SQLException if any error + */ + public int login(final String username, final String password) throws SQLException { + // Method implementation. + + } + + /** + * Register a new user. + * + * @param user a user instance + * @return the execution result of the method + * @throws SQLException if any error + */ + public int registerUser(final User user) throws SQLException { + // Method implementation. + } +} +``` + +In the class `App`, we use an instance of the `UserTableModule` to handle user login and registration. + +```java +// Create data source and create the user table. +final var dataSource = createDataSource(); +createSchema(dataSource); +userTableModule = new UserTableModule(dataSource); + +//Initialize two users. +var user1 = new User(1, "123456", "123456"); +var user2 = new User(2, "test", "password"); + +//Login and register using the instance of userTableModule. +userTableModule.registerUser(user1); +userTableModule.login(user1.getUsername(), user1.getPassword()); +userTableModule.login(user2.getUsername(), user2.getPassword()); +userTableModule.registerUser(user2); +userTableModule.login(user2.getUsername(), user2.getPassword()); + +deleteSchema(dataSource); +``` + +The program output: + +```java +12:22:13.095 [main] INFO com.iluwatar.tablemodule.UserTableModule - Register successfully! +12:22:13.117 [main] INFO com.iluwatar.tablemodule.UserTableModule - Login successfully! +12:22:13.128 [main] INFO com.iluwatar.tablemodule.UserTableModule - Fail to login! +12:22:13.136 [main] INFO com.iluwatar.tablemodule.UserTableModule - Register successfully! +12:22:13.144 [main] INFO com.iluwatar.tablemodule.UserTableModule - Login successfully! +``` + +## Class diagram + +![](./etc/table-module.urm.png "table module") + +## Applicability + +Use the Table Module Pattern when + +- Domain logic is simple and data is in tabular form. +- The application only uses a few shared common table-oriented data structures. + +## Related patterns + +- [Transaction Script](https://java-design-patterns.com/patterns/transaction-script/) + +- Domain Model + +## Credits + +* [Table Module Pattern](http://wiki3.cosc.canterbury.ac.nz/index.php/Table_module_pattern) +* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0321127420&linkId=18acc13ba60d66690009505577c45c04) +* [Architecture patterns: domain model and friends](https://inviqa.com/blog/architecture-patterns-domain-model-and-friends) \ No newline at end of file diff --git a/table-module/etc/table-module.urm.png b/table-module/etc/table-module.urm.png new file mode 100644 index 0000000000000000000000000000000000000000..9c4bc0b189dba5c86aeddf9235946135019added GIT binary patch literal 77337 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 literal 0 HcmV?d00001 diff --git a/table-module/etc/table-module.urm.puml b/table-module/etc/table-module.urm.puml new file mode 100644 index 000000000..6cf75797f --- /dev/null +++ b/table-module/etc/table-module.urm.puml @@ -0,0 +1,38 @@ +@startuml +package com.iluwatar.tablemodule { + class App { + - DB_URL : String {static} + - LOGGER : Logger {static} + - App() + - createDataSource() : DataSource {static} + - createSchema(dataSource : DataSource) {static} + - deleteSchema(dataSource : DataSource) {static} + + main(args : String[]) {static} + } + class User { + - id : int + - password : String + - username : String + + User(id : int, username : String, password : String) + # canEqual(other : Object) : boolean + + equals(o : Object) : boolean + + getId() : int + + getPassword() : String + + getUsername() : String + + hashCode() : int + + setId(id : int) + + setPassword(password : String) + + setUsername(username : String) + + toString() : String + } + class UserTableModule { + + CREATE_SCHEMA_SQL : String {static} + + DELETE_SCHEMA_SQL : String {static} + - LOGGER : Logger {static} + - dataSource : DataSource + + UserTableModule(userDataSource : DataSource) + + login(username : String, password : String) : int + + registerUser(user : User) : int + } +} +@enduml \ No newline at end of file diff --git a/table-module/pom.xml b/table-module/pom.xml new file mode 100644 index 000000000..eae698c09 --- /dev/null +++ b/table-module/pom.xml @@ -0,0 +1,73 @@ + + + + + java-design-patterns + com.iluwatar + 1.25.0-SNAPSHOT + + 4.0.0 + + table-module + + + + com.h2database + h2 + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.mockito + mockito-core + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.tablemodule.App + + + + + + + + + + diff --git a/table-module/src/main/java/com/iluwatar/tablemodule/App.java b/table-module/src/main/java/com/iluwatar/tablemodule/App.java new file mode 100644 index 000000000..7b22666e0 --- /dev/null +++ b/table-module/src/main/java/com/iluwatar/tablemodule/App.java @@ -0,0 +1,81 @@ +package com.iluwatar.tablemodule; + +import java.sql.SQLException; +import javax.sql.DataSource; + +import lombok.extern.slf4j.Slf4j; +import org.h2.jdbcx.JdbcDataSource; + + +/** + * Table Module pattern is a domain logic pattern. + * In Table Module a single class encapsulates all the domain logic for all + * records stored in a table or view. It's important to note that there is no + * translation of data between objects and rows, as it happens in Domain Model, + * hence implementation is relatively simple when compared to the Domain + * Model pattern. + * + *

In this example we will use the Table Module pattern to implement register + * and login methods for the records stored in the user table. The main + * method will initialise an instance of {@link UserTableModule} and use it to + * handle the domain logic for the user table.

+ */ +@Slf4j +public final class App { + private static final String DB_URL = "jdbc:h2:~/test"; + + /** + * Private constructor. + */ + private App() { + + } + + /** + * Program entry point. + * + * @param args command line args. + * @throws SQLException if any error occurs. + */ + public static void main(final String[] args) throws SQLException { + // Create data source and create the user table. + final var dataSource = createDataSource(); + createSchema(dataSource); + var userTableModule = new UserTableModule(dataSource); + + // Initialize two users. + var user1 = new User(1, "123456", "123456"); + var user2 = new User(2, "test", "password"); + + // Login and register using the instance of userTableModule. + userTableModule.registerUser(user1); + userTableModule.login(user1.getUsername(), user1.getPassword()); + userTableModule.login(user2.getUsername(), user2.getPassword()); + userTableModule.registerUser(user2); + userTableModule.login(user2.getUsername(), user2.getPassword()); + + deleteSchema(dataSource); + } + + private static void deleteSchema(final DataSource dataSource) + throws SQLException { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + statement.execute(UserTableModule.DELETE_SCHEMA_SQL); + } + } + + private static void createSchema(final DataSource dataSource) + throws SQLException { + try (var connection = dataSource.getConnection(); + var statement = connection.createStatement()) { + statement.execute(UserTableModule.CREATE_SCHEMA_SQL); + } + } + + private static DataSource createDataSource() { + var dataSource = new JdbcDataSource(); + dataSource.setURL(DB_URL); + return dataSource; + } +} diff --git a/table-module/src/main/java/com/iluwatar/tablemodule/User.java b/table-module/src/main/java/com/iluwatar/tablemodule/User.java new file mode 100644 index 000000000..ac307d450 --- /dev/null +++ b/table-module/src/main/java/com/iluwatar/tablemodule/User.java @@ -0,0 +1,23 @@ +package com.iluwatar.tablemodule; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + + +/** + * A user POJO that represents the data that will be read from the data source. + */ +@Setter +@Getter +@ToString +@EqualsAndHashCode +@AllArgsConstructor +public class User { + private int id; + private String username; + private String password; + +} diff --git a/table-module/src/main/java/com/iluwatar/tablemodule/UserTableModule.java b/table-module/src/main/java/com/iluwatar/tablemodule/UserTableModule.java new file mode 100644 index 000000000..f1a4d0444 --- /dev/null +++ b/table-module/src/main/java/com/iluwatar/tablemodule/UserTableModule.java @@ -0,0 +1,96 @@ +package com.iluwatar.tablemodule; + +import java.sql.ResultSet; +import java.sql.SQLException; +import javax.sql.DataSource; + +import lombok.extern.slf4j.Slf4j; + + +/** + * This class organizes domain logic with the user table in the + * database. A single instance of this class contains the various + * procedures that will act on the data. + */ +@Slf4j +public class UserTableModule { + /** + * Public element for creating schema. + */ + public static final String CREATE_SCHEMA_SQL = + "CREATE TABLE IF NOT EXISTS USERS (ID NUMBER, USERNAME VARCHAR(30) " + + "UNIQUE,PASSWORD VARCHAR(30))"; + /** + * Public element for deleting schema. + */ + public static final String DELETE_SCHEMA_SQL = "DROP TABLE USERS IF EXISTS"; + private final DataSource dataSource; + + + /** + * Public constructor. + * + * @param userDataSource the data source in the database + */ + public UserTableModule(final DataSource userDataSource) { + this.dataSource = userDataSource; + } + + + /** + * Login using username and password. + * + * @param username the username of a user + * @param password the password of a user + * @return the execution result of the method + * @throws SQLException if any error + */ + public int login(final String username, final String password) + throws SQLException { + var sql = "select count(*) from USERS where username=? and password=?"; + ResultSet resultSet = null; + try (var connection = dataSource.getConnection(); + var preparedStatement = + connection.prepareStatement(sql) + ) { + var result = 0; + preparedStatement.setString(1, username); + preparedStatement.setString(2, password); + resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + result = resultSet.getInt(1); + } + if (result == 1) { + LOGGER.info("Login successfully!"); + } else { + LOGGER.info("Fail to login!"); + } + return result; + } finally { + if (resultSet != null) { + resultSet.close(); + } + } + } + + /** + * Register a new user. + * + * @param user a user instance + * @return the execution result of the method + * @throws SQLException if any error + */ + public int registerUser(final User user) throws SQLException { + var sql = "insert into USERS (username, password) values (?,?)"; + try (var connection = dataSource.getConnection(); + var preparedStatement = + connection.prepareStatement(sql) + ) { + preparedStatement.setString(1, user.getUsername()); + preparedStatement.setString(2, user.getPassword()); + var result = preparedStatement.executeUpdate(); + LOGGER.info("Register successfully!"); + return result; + } + } +} diff --git a/table-module/src/test/java/com/iluwatar/tablemodule/AppTest.java b/table-module/src/test/java/com/iluwatar/tablemodule/AppTest.java new file mode 100644 index 000000000..cafae7cdb --- /dev/null +++ b/table-module/src/test/java/com/iluwatar/tablemodule/AppTest.java @@ -0,0 +1,16 @@ +package com.iluwatar.tablemodule; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +/** + * Tests that the table module example runs without errors. + */ +class AppTest { + + @Test + void shouldExecuteWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); + } +} diff --git a/table-module/src/test/java/com/iluwatar/tablemodule/UserTableModuleTest.java b/table-module/src/test/java/com/iluwatar/tablemodule/UserTableModuleTest.java new file mode 100644 index 000000000..86685f58d --- /dev/null +++ b/table-module/src/test/java/com/iluwatar/tablemodule/UserTableModuleTest.java @@ -0,0 +1,78 @@ +package com.iluwatar.tablemodule; + +import org.h2.jdbcx.JdbcDataSource; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import javax.sql.DataSource; +import java.sql.DriverManager; +import java.sql.SQLException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class UserTableModuleTest { + private static final String DB_URL = "jdbc:h2:~/test"; + + private static DataSource createDataSource() { + var dataSource = new JdbcDataSource(); + dataSource.setURL(DB_URL); + return dataSource; + } + + @BeforeEach + void setUp() throws SQLException { + try (var connection = DriverManager.getConnection(DB_URL); + var statement = connection.createStatement()) { + statement.execute(UserTableModule.DELETE_SCHEMA_SQL); + statement.execute(UserTableModule.CREATE_SCHEMA_SQL); + } + } + + @AfterEach + void tearDown() throws SQLException { + try (var connection = DriverManager.getConnection(DB_URL); + var statement = connection.createStatement()) { + statement.execute(UserTableModule.DELETE_SCHEMA_SQL); + } + } + + @Test + void loginShouldFail() throws SQLException { + var dataSource = createDataSource(); + var userTableModule = new UserTableModule(dataSource); + var user = new User(1, "123456", "123456"); + assertEquals(0, userTableModule.login(user.getUsername(), + user.getPassword())); + } + + @Test + void loginShouldSucceed() throws SQLException { + var dataSource = createDataSource(); + var userTableModule = new UserTableModule(dataSource); + var user = new User(1, "123456", "123456"); + userTableModule.registerUser(user); + assertEquals(1, userTableModule.login(user.getUsername(), + user.getPassword())); + } + + @Test + void registerShouldFail() throws SQLException { + var dataSource = createDataSource(); + var userTableModule = new UserTableModule(dataSource); + var user = new User(1, "123456", "123456"); + userTableModule.registerUser(user); + assertThrows(SQLException.class, () -> { + userTableModule.registerUser(user); + }); + } + + @Test + void registerShouldSucceed() throws SQLException { + var dataSource = createDataSource(); + var userTableModule = new UserTableModule(dataSource); + var user = new User(1, "123456", "123456"); + assertEquals(1, userTableModule.registerUser(user)); + } +} \ No newline at end of file diff --git a/table-module/src/test/java/com/iluwatar/tablemodule/UserTest.java b/table-module/src/test/java/com/iluwatar/tablemodule/UserTest.java new file mode 100644 index 000000000..669d86035 --- /dev/null +++ b/table-module/src/test/java/com/iluwatar/tablemodule/UserTest.java @@ -0,0 +1,131 @@ +package com.iluwatar.tablemodule; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class UserTest { + @Test + void testCanEqual() { + assertFalse((new User(1, "janedoe", "iloveyou")) + .canEqual("Other")); + } + + @Test + void testCanEqual2() { + var user = new User(1, "janedoe", "iloveyou"); + assertTrue(user.canEqual(new User(1, "janedoe", + "iloveyou"))); + } + + @Test + void testEquals1() { + var user = new User(1, "janedoe", "iloveyou"); + assertNotEquals("42", user); + } + + @Test + void testEquals2() { + var user = new User(1, "janedoe", "iloveyou"); + assertEquals(user, new User(1, "janedoe", + "iloveyou")); + } + + @Test + void testEquals3() { + var user = new User(123, "janedoe", "iloveyou"); + assertNotEquals(user, new User(1, "janedoe", + "iloveyou")); + } + + @Test + void testEquals4() { + var user = new User(1, null, "iloveyou"); + assertNotEquals(user, new User(1, "janedoe", + "iloveyou")); + } + + @Test + void testEquals5() { + var user = new User(1, "iloveyou", "iloveyou"); + assertNotEquals(user, new User(1, "janedoe", + "iloveyou")); + } + + @Test + void testEquals6() { + var user = new User(1, "janedoe", "janedoe"); + assertNotEquals(user, new User(1, "janedoe", + "iloveyou")); + } + + @Test + void testEquals7() { + var user = new User(1, "janedoe", null); + assertNotEquals(user, new User(1, "janedoe", + "iloveyou")); + } + + @Test + void testEquals8() { + var user = new User(1, null, "iloveyou"); + assertEquals(user, new User(1, null, + "iloveyou")); + } + + @Test + void testEquals9() { + var user = new User(1, "janedoe", null); + assertEquals(user, new User(1, "janedoe", + null)); + } + + @Test + void testHashCode1() { + assertEquals(-1758941372, (new User(1, "janedoe", + "iloveyou")).hashCode()); + + } + + @Test + void testHashCode2() { + assertEquals(-1332207447, (new User(1, null, + "iloveyou")).hashCode()); + } + + @Test + void testHashCode3() { + assertEquals(-426522485, (new User(1, "janedoe", + null)).hashCode()); + } + + @Test + void testSetId() { + var user = new User(1, "janedoe", "iloveyou"); + user.setId(2); + assertEquals(2, user.getId()); + } + + @Test + void testSetPassword() { + var user = new User(1, "janedoe", "tmp"); + user.setPassword("iloveyou"); + assertEquals("iloveyou", user.getPassword()); + } + + @Test + void testSetUsername() { + var user = new User(1, "tmp", "iloveyou"); + user.setUsername("janedoe"); + assertEquals("janedoe", user.getUsername()); + } + + @Test + void testToString() { + var user = new User(1, "janedoe", "iloveyou"); + assertEquals(String.format("User(id=%s, username=%s, password=%s)", + user.getId(), user.getUsername(), user.getPassword()), + user.toString()); + } +} +