diff --git a/module/README.md b/module/README.md new file mode 100644 index 000000000..d3d6b8746 --- /dev/null +++ b/module/README.md @@ -0,0 +1,29 @@ +--- +layout: pattern +title: Module +folder: module +permalink: /patterns/module/ +pumlid: JShB3OGm303HLg20nFVjnYGM1CN6ycTfVtFSsnjfzY5jPgUqkLqHwXy0mxUU8wuyqidQ8q4IjJqCO-QBWGOtVh5qyd5AKOmW4mT6Nu2-ZiAekapH_hkcSTNa-GC0 +categories: Persistence Tier +tags: + - Java + - Difficulty-Beginner +--- + +## Intent +A layer of mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself + +![alt text](./etc/module.png "Module") + +## Applicability +The module pattern is a design pattern used to implement the concept of software modules, defined by modular programming, in a programming language with incomplete direct support for the concept. + +The Module pattern can be considered a creational pattern and a structural pattern. It manages the creation and organization of other elements, and groups them as the structural pattern does. + +An object that applies this pattern can provide the equivalent of a namespace, providing the initialization and finalization process of a static class or a class with static members with cleaner, more concise syntax and semantics. + +It supports specific cases where a class or object can be considered structured, procedural data. And, vice versa, migrate structured, procedural data, and considered as object-oriented. + +## Credits + +* [Module](https://en.wikipedia.org/wiki/Module_pattern) diff --git a/module/pom.xml b/module/pom.xml new file mode 100644 index 000000000..bc43e3e09 --- /dev/null +++ b/module/pom.xml @@ -0,0 +1,45 @@ + + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.14.0-SNAPSHOT + + module + + + junit + junit + test + + + log4j + log4j + + + diff --git a/module/src/main/java/com/iluwatar/module/App.java b/module/src/main/java/com/iluwatar/module/App.java new file mode 100644 index 000000000..9dab6a00c --- /dev/null +++ b/module/src/main/java/com/iluwatar/module/App.java @@ -0,0 +1,73 @@ +/** + * The MIT License Copyright (c) 2016 Amit Dixit + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.module; + +import java.io.FileNotFoundException; + +/** + * 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 each other. With Data Mapper the in-memory + * objects needn't know even that there's a database present; they need no SQL + * interface code, and certainly no knowledge of the database schema. (The + * database schema is always ignorant of the objects that use it.) Since it's a + * form of Mapper , Data Mapper itself is even unknown to the domain layer. + *

+ * The below example demonstrates basic CRUD operations: Create, Read, Update, + * and Delete. + * + */ +public final class App { + + private static final String OUTPUT_FILE = "output.txt"; + private static final String ERROR_FILE = "error.txt"; + + public static FilePrinterModule filePrinterModule = null; + + public static void prepare() throws FileNotFoundException { + filePrinterModule = FilePrinterModule.getSingleton(); + + filePrinterModule.prepare(OUTPUT_FILE, ERROR_FILE); + } + + public static void unprepare() { + filePrinterModule.unprepare(); + } + + public static final void execute(final String... args) { + filePrinterModule.printString("Hello World"); + } + + /** + * Program entry point. + * + * @param args + * command line args. + * @throws FileNotFoundException + */ + public static final void main(final String... args) + throws FileNotFoundException { + prepare(); + execute(args); + unprepare(); + } + + private App() { + } +} diff --git a/module/src/main/java/com/iluwatar/module/FilePrinterModule.java b/module/src/main/java/com/iluwatar/module/FilePrinterModule.java new file mode 100644 index 000000000..879492248 --- /dev/null +++ b/module/src/main/java/com/iluwatar/module/FilePrinterModule.java @@ -0,0 +1,100 @@ +package com.iluwatar.module; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; + +import org.apache.log4j.Logger; + +/** + * The MIT License Copyright (c) 2016 Amit Dixit + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +public final class FilePrinterModule { + + private static final Logger logger = Logger + .getLogger(FilePrinterModule.class); + + private static FilePrinterModule singleton = null; + + public PrintStream output = null; + public PrintStream error = null; + + private FilePrinterModule() { + } + + public static final FilePrinterModule getSingleton() { + + if (FilePrinterModule.singleton == null) { + FilePrinterModule.singleton = new FilePrinterModule(); + } + + return FilePrinterModule.singleton; + } + + /** + * + * @throws FileNotFoundException + */ + public final void prepare(final String outputFile, final String errorFile) + throws FileNotFoundException { + + logger.debug("MainModule::prepare();"); + + this.output = new PrintStream(new FileOutputStream(outputFile)); + this.error = new PrintStream(new FileOutputStream(errorFile)); + } + + /** + * + */ + public final void unprepare() { + + if (this.output != null) { + + this.output.flush(); + this.output.close(); + } + + if (this.error != null) { + + this.error.flush(); + this.error.close(); + } + + logger.debug("MainModule::unprepare();"); + } + + /** + * + * @param value + */ + public final void printString(final String value) { + this.output.print(value); + } + + /** + * + * @param value + */ + public final void printErrorString(final String value) { + this.error.print(value); + } +} diff --git a/module/src/main/resources/log4j.xml b/module/src/main/resources/log4j.xml new file mode 100644 index 000000000..b591c17e1 --- /dev/null +++ b/module/src/main/resources/log4j.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/module/src/test/java/com/iluwatar/module/AppTest.java b/module/src/test/java/com/iluwatar/module/AppTest.java new file mode 100644 index 000000000..46c12ef38 --- /dev/null +++ b/module/src/test/java/com/iluwatar/module/AppTest.java @@ -0,0 +1,37 @@ +/** + * The MIT License Copyright (c) 2016 Amit Dixit + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.module; + +import java.io.FileNotFoundException; + +import com.iluwatar.module.App; + +import org.junit.Test; + +/** + * Tests that Data-Mapper example runs without errors. + */ +public final class AppTest { + + @Test + public void test() throws FileNotFoundException { + final String[] args = {}; + App.main(args); + } +} diff --git a/module/src/test/java/com/iluwatar/module/ModuleTest.java b/module/src/test/java/com/iluwatar/module/ModuleTest.java new file mode 100644 index 000000000..797e7f26a --- /dev/null +++ b/module/src/test/java/com/iluwatar/module/ModuleTest.java @@ -0,0 +1,180 @@ +/** + * The MIT License Copyright (c) 2016 Amit Dixit + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT + * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.iluwatar.module; + +import static org.junit.Assert.assertEquals; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +import org.apache.log4j.Logger; +import org.junit.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 each other. With Data Mapper the in-memory + * objects needn't know even that there's a database present; they need no SQL + * interface code, and certainly no knowledge of the database schema. (The + * database schema is always ignorant of the objects that use it.) Since it's a + * form of Mapper , Data Mapper itself is even unknown to the domain layer. + *

+ */ +public class ModuleTest { + + private static final Logger logger = Logger.getLogger(ModuleTest.class); + + private static final String OUTPUT_FILE = "output.txt"; + private static final String ERROR_FILE = "error.txt"; + + private static final String MESSAGE = "MESSAGE"; + private static final String ERROR = "ERROR"; + + /** + * This test verify that 'MESSAGE' is perfectly printed in output file + * + * @throws IOException + */ + @Test + public void testPositiveMessage() throws IOException { + + /* Prepare the essential sub modules, to perform the sequence of jobs */ + final FilePrinterModule filePrinterModule = FilePrinterModule + .getSingleton(); + + /* Prepare the essential sub modules, to perform the sequence of jobs */ + filePrinterModule.prepare(OUTPUT_FILE, ERROR_FILE); + + /* Print 'Message' in file */ + filePrinterModule.printString(MESSAGE); + + /* Test if 'Message' is printed in file */ + assertEquals(readFirstLine(OUTPUT_FILE), MESSAGE); + + /* Unprepare to cleanup the modules */ + filePrinterModule.unprepare(); + } + + /** + * This test verify that nothing is printed in output file + * + * @throws IOException + */ + @Test + public void testNegativeMessage() throws IOException { + + /* Prepare the essential sub modules, to perform the sequence of jobs */ + final FilePrinterModule filePrinterModule = FilePrinterModule + .getSingleton(); + + /* Prepare the essential sub modules, to perform the sequence of jobs */ + filePrinterModule.prepare(OUTPUT_FILE, ERROR_FILE); + + /* Test if nothing is printed in file */ + assertEquals(readFirstLine(OUTPUT_FILE), null); + + /* Unprepare to cleanup the modules */ + filePrinterModule.unprepare(); + } + + /** + * This test verify that 'ERROR' is perfectly printed in error file + * + * @throws FileNotFoundException + */ + @Test + public void testPositiveErrorMessage() throws FileNotFoundException { + + /* Prepare the essential sub modules, to perform the sequence of jobs */ + final FilePrinterModule filePrinterModule = FilePrinterModule + .getSingleton(); + + /* Prepare the essential sub modules, to perform the sequence of jobs */ + filePrinterModule.prepare(OUTPUT_FILE, ERROR_FILE); + + /* Print 'Error' in file */ + filePrinterModule.printErrorString(ERROR); + + /* Test if 'Message' is printed in file */ + assertEquals(readFirstLine(ERROR_FILE), ERROR); + + /* Unprepare to cleanup the modules */ + filePrinterModule.unprepare(); + } + + /** + * This test verify that nothing is printed in error file + * + * @throws FileNotFoundException + */ + @Test + public void testNegativeErrorMessage() throws FileNotFoundException { + + /* Prepare the essential sub modules, to perform the sequence of jobs */ + final FilePrinterModule filePrinterModule = FilePrinterModule + .getSingleton(); + + /* Prepare the essential sub modules, to perform the sequence of jobs */ + filePrinterModule.prepare(OUTPUT_FILE, ERROR_FILE); + + /* Test if nothing is printed in file */ + assertEquals(readFirstLine(ERROR_FILE), null); + + /* Unprepare to cleanup the modules */ + filePrinterModule.unprepare(); + } + + /** + * Utility method to read first line of a file + * + * @param file + * @return + */ + private static final String readFirstLine(final String file) { + + String firstLine = null; + BufferedReader bufferedReader = null; + try { + + /* Create a buffered reader */ + bufferedReader = new BufferedReader(new FileReader(file)); + + /* Read the line */ + firstLine = bufferedReader.readLine(); + + logger.info("ModuleTest::readFile() : firstLine : " + firstLine); + + } catch (final IOException e) { + logger.error("ModuleTest::readFile()", e); + } finally { + + if (bufferedReader != null) { + try { + bufferedReader.close(); + } catch (final IOException e) { + logger.error("ModuleTest::readFile()", e); + } + } + } + + return firstLine; + } +} diff --git a/pom.xml b/pom.xml index 538058a81..a73992607 100644 --- a/pom.xml +++ b/pom.xml @@ -123,6 +123,7 @@ factory-kit feature-toggle value-object + module monad mute-idiom mutex