A comprehensive Java-based in-memory database management system demonstrating the practical implementation of 7 Design Patterns from all three GoF categories (Creational, Structural, and Behavioral).
This project implements a fully functional in-memory database engine that supports:
- Table creation and management
- CRUD operations (Create, Read, Update, Delete)
- Complex query conditions
- Data validation
- Logging system
- Table cloning
- Multiple iteration strategies
For a comprehensive walkthrough of the system, including a deep dive into the Design Patterns implementation and a live demonstration of the database operations, watch the video here:
π Watch the Project Presentation
- Location:
Logger/Informer.java,Logger/LogManager.java,Logger/WriterLogger.java - Purpose: Ensures only one instance of critical system components exists
- Implementation:
LogManager logger = LogManager.getInstance(); Informer informer = Informer.getInformer(); WriterLogger writer = WriterLogger.getLogger();
- Benefits:
- Controlled access to single instance
- Thread-safe implementation (synchronized)
- Lazy initialization
- Prevents multiple logger instances causing conflicts
- Location:
builder/TableBuilder.java - Purpose: Constructs complex Table objects step-by-step with a fluent API
- Implementation:
TableBuilder builder = new TableBuilder(); Table table = builder.build("Users", columns);
- Benefits:
- Separates object construction from representation
- Provides clear and readable table creation process
- Allows flexible table configuration
- Location:
Clone/TableClone.java,models/Table.java - Purpose: Creates deep copies of Table objects without depending on concrete classes
- Implementation:
Table clonedTable = originalTable.clone();
- Benefits:
- Efficient object duplication
- Independent copies (changes don't affect original)
- Preserves schema and data integrity
- Location:
Condition/package - Purpose: Builds hierarchical condition trees for complex queries
- Implementation:
Condition simple1 = new SimpleCondition("age", ">", 18); Condition simple2 = new SimpleCondition("name", "==", "Sara"); Condition composite = new AndCondition(List.of(simple1, simple2));
- Benefits:
- Treats individual and composite conditions uniformly
- Enables complex logical expressions (AND, OR)
- Easy to extend with new condition types
- Location:
DataOperations/package - Purpose: Encapsulates all database operations as objects with uniform execution flow
- Classes:
AbstractOperation- Base commandInsertOperation,UpdateOperation,DeleteOperationQueryOperation,CreateTable,RemoveTable
- Implementation:
AbstractOperation operation = new InsertOperation(db, "Users", rows); List<Row> result = operation.run();
- Benefits:
- Uniform validation β execution β result flow
- Easy to add new operations
- Supports logging and undo functionality
- Location:
Logger/package - Purpose: Implements a reactive logging system that responds to data changes
- Components:
IObserver- Observer interfaceIInformer- Subject interfaceLogManager- Concrete observerInformer- Concrete subject (Singleton)WriterLogger- File logger (Singleton)
- Implementation:
LogManager logger = LogManager.getInstance(); Informer.getInformer().attach(logger); // Automatically logs all data operations
- Benefits:
- Loose coupling between operations and logging
- Easy to add new observers
- Centralized event notification
- Location:
Iteration/package - Purpose: Allows dynamic selection of row iteration algorithms
- Strategies:
ByIncomeIteration- Returns rows in insertion orderByColumnIteration- Returns rows sorted by columnByConditionIteration- Returns filtered rows by condition
- Implementation:
Iiteration strategy = new ByColumnIteration("age"); List<Row> sorted = db.iterate("Users", strategy);
- Benefits:
- Interchangeable algorithms at runtime
- Clean separation of iteration logic
- Easy to add new iteration strategies
Design Patterns Project/
βββ src/
β βββ main/
β β βββ java/
β β βββ builder/ # Builder Pattern
β β βββ Clone/ # Prototype Pattern
β β βββ Condition/ # Composite Pattern
β β βββ DataOperations/ # Command Pattern
β β βββ Logger/ # Observer Pattern
β β βββ Iteration/ # Strategy Pattern
β β βββ models/ # Core data models
β β βββ Validation/ # Validation logic
β βββ test/
β βββ java/ # JUnit tests
βββ junit-platform-console-standalone-1.9.3.jar
βββ run-tests.bat
βββ pom.xml
- Java JDK 11 or higher
- Download: Oracle JDK or Adoptium
- JUnit 5 (included in project)
-
Ensure Java is installed:
java -version javac -version
-
Navigate to project directory:
cd "Design Patterns Project"
-
Run the test script:
run-tests.bat
This will:
- Compile all source files
- Compile test files
- Run all JUnit tests
- Display results
# Compile source files
javac -d out src\main\java\models\*.java src\main\java\Clone\*.java src\main\java\Condition\*.java src\main\java\DataOperations\*.java src\main\java\Logger\*.java src\main\java\Validation\*.java src\main\java\Iteration\*.java src\main\java\builder\*.java
# Compile test files
javac -cp "out;junit-platform-console-standalone-1.9.3.jar" -d out src\test\java\*.java
# Run tests
java -jar junit-platform-console-standalone-1.9.3.jar --class-path out --scan-class-path- Open the project folder
- Right-click on
src/test/javaβ Run 'All Tests'
- Import as Maven project
- Right-click on project β Run As β JUnit Test
- Install Java Extension Pack
- Open project folder
- Click Run Tests in Testing panel
mvn clean test- β Create and manage tables with typed columns
- β Insert, update, delete, and query rows
- β Complex condition queries (AND, OR, comparison operators)
- β Schema validation
- β Deep table cloning
- β Automatic logging of all operations
- β Multiple iteration strategies
STRINGINTEGERFLOATBOOLEANDATECHARACTER
// Create database
DataBase db = new DataBase("MyDB");
// Define columns
List<Column> columns = List.of(
new Column("id", DataType.INTEGER),
new Column("name", DataType.STRING),
new Column("age", DataType.INTEGER)
);
// Create table
db.createTable("Users", columns);Row row = new Row();
row.setValue("id", 1);
row.setValue("name", "Sara");
row.setValue("age", 25);
db.insertIntoTable("Users", List.of(row));// Simple condition
Condition condition = new SimpleCondition("age", ">", 18);
List<Row> adults = db.query(condition, "Users");
// Complex condition
Condition cond1 = new SimpleCondition("age", ">", 18);
Condition cond2 = new SimpleCondition("name", "==", "Sara");
Condition combined = new AndCondition(List.of(cond1, cond2));
List<Row> result = db.query(combined, "Users");Row oldRow = existingRow;
Row newRow = new Row();
newRow.setValue("id", 1);
newRow.setValue("name", "Sara Updated");
newRow.setValue("age", 26);
db.updateTable("Users", List.of(oldRow), List.of(newRow));db.deleteFromTable("Users", List.of(rowToDelete));Table original = db.getTable("Users");
Table cloned = original.clone();// Sort by column
Iiteration sortStrategy = new ByColumnIteration("age");
List<Row> sorted = db.iterate("Users", sortStrategy);
// Filter by condition
Iiteration filterStrategy = new ByConditionIteration(condition, schema);
List<Row> filtered = db.iterate("Users", filterStrategy);The project includes comprehensive JUnit tests:
InsertOperationTest- Tests data insertionUpdateOperationTest- Tests data updatesDeleteOperationTest- Tests data deletionQueryOperationTest- Tests query operationsCreateTableTest- Tests table creationCloneTableTest- Tests table cloning
All operations are automatically logged to log.txt with timestamps:
[LOG] [2026-03-09 00:18:52] Inserting rows into table: Users
[LOG] [2026-03-09 00:18:52] Deleted 2 rows from Users
[LOG] [2026-03-09 00:18:52] Updating rows into table: Students
- SOLID Principles
- Separation of Concerns
- Clean Code
- DRY (Don't Repeat Yourself)
- Single Responsibility Principle
Design Patterns Project - In-Memory Data Engine
This project is for educational purposes.