Code Monkey home page Code Monkey logo

stock-handling's Introduction

Stock Handling · Build Status Quality Gate Status Coverage Maintainability Rating

A simple product stocking control application made in Java using Spring Boot.

Basic Architecture

I've decided to use some concepts from DDD and Hexagonal Arcuitecture to develop the application. It allows me to use the Inversion Control principle at the architectural level. The benefits are:

  • Dependencies go outside in, so the core application is normally decoupled from frameworks and libs.
  • Adapters are plugable structures, so you can use different implementations for each port, e.g.: an adapter to implement an in memory data structure to be used in tests and a database accessing a real database for production.
  • Tests are easier to implement
  • Ports can isolate the core application from receiving domain data directly from the entry adapters, like data from a controller. It need to send data as simple classes just to deliver the necessary data to the application. So, the received data can be used to create domain objects to execute the application's use cases.
  • It makes the application's use cases more explicit

Ports & Adapters

Ports

Ports are interfaces of communication between the application core and the outside world. Ports that are used by the outside world to communicate with the application are called entry ports. A Rest Controller that need to communicate with the core application needs to interact through an entry port, for example, to update a user profile. The port implementation code is kept inside the application. Another kind of port is the ones that are used by the application to comunicate to the world outside. They are aled exit ports. When the application needs to persist some data, it uses a port to communicate with a persistence adapter responsible for persisting the data.

Adapter

We have two kinds of adapters: Drivers (in) and Driven (out). Drivers are the ones that call the application core. The Driver adapter is the agent that starts the interaction. E.g.: Rest Controllers

Driven adapters are the ones that the application core call when it needs to interact with the outside world. In this case, the action originates from the applpication. E.g: JPA Persistence adapter

The main motivation to use this architecture is keeping my application core isolated from frameworks code.

The source code is organized by feature as follows:

com
    └── breno
        └── projects
            └── stockhandling
                ├── DataLoader.java
                ├── DemoApplication.java
                ├── shared
                │   ├── adapter
                │   ├── application
                │   └── utils
                ├── statistics
                │   ├── adapter
                │   ├── application
                │   └── domain
                └── stock
                    ├── adapter
                    ├── application
                    └── model

Each module has 3 packages:

model

It's the domain model. Classes on this module keep the business rules related to each concept

application

Above the domain model, the application is responsible for keeping the domain isolated from the outside world and coordinating the use cases execution.

Outside world communication is granted though ports, interfaces that need to be implement as adapters.

adapter

Adapters implement ports defined by the application. The injection of those objects is done by de IoC container.

Data Structures

Some classes represents just a way to transfer data from one layer to another. We can call them DTOs. Normally they are immutable and have no behaviors. They must be considered just a data strcture. When delivered to the application, those objects are converted into domain objects.

The App Modules

Stock

├── adapter
│   ├── in
│   │   └── api
│   │       ├── exception
│   │       │   ├── IfMatchETagNotPresent.java
│   │       │   ├── InvalidIfMatchEtagException.java
│   │       │   └── StockApiExceptionHandler.java
│   │       ├── GetStockController.java
│   │       ├── helpers
│   │       │   ├── ETagStringCreator.java
│   │       │   └── HashGenerator.java
│   │       ├── request
│   │       │   └── UpdateStockRequest.java
│   │       ├── response
│   │       │   └── GetStockResponse.java
│   │       └── UpdateStockController.java
│   └── out
│       └── persistence
│           └── jpa
│               ├── StockEntity.java
│               ├── StockPersistenceAdapter.java
│               └── StockRepository.java
├── application
│   ├── port
│   │   ├── in
│   │   │   ├── GetStockQuery.java
│   │   │   ├── UpdateStockCommand.java
│   │   │   └── UpdateStockUseCase.java
│   │   └── out
│   │       ├── LoadStockPort.java
│   │       ├── NotifyStatisticsMediatorPort.java
│   │       ├── StockUpdatedData.java
│   │       └── UpdateStockStatePort.java
│   └── service
│       ├── GetStockService.java
│       └── UpdateStockService.java
└── model
    ├── exception
    │   ├── FutureStockTimestampException.java
    │   └── InvalidStockQuantityException.java
    └── Stock.java

Following the CQRS pattern, this module separates Commands, operations that are task centric and change data, but return nothing, from Queries, operations for returning data, but never changing them.

Statistics

├── adapter
│   ├── in
│   │   └── api
│   │       ├── GetStatisticsController.java
│   │       └── response
│   │           ├── AvailableProductDto.java
│   │           ├── GetStatisticsResponse.java
│   │           └── ProductSellsDto.java
│   └── out
│       └── persistence
│           └── mongo
│               ├── ProductStatisticsDocument.java
│               ├── ProductStatisticsPersistenceAdapter.java
│               ├── ProductStatisticsRepository.java
│               └── StockUpdateEvent.java
├── application
│   ├── port
│   │   ├── in
│   │   │   ├── LoadStatisticsQuery.java
│   │   │   ├── TopStatistics.java
│   │   │   ├── UpdateStockStatisticsCommand.java
│   │   │   └── UpdateStockStatisticsUseCase.java
│   │   └── out
│   │       ├── LoadProductStatisticsPort.java
│   │       ├── LoadStatisticsPort.java
│   │       └── UpdateStockStatisticsStatePort.java
│   └── service
│       ├── LoadStatisticsService.java
│       └── UpdateStockStatisticsService.java
└── domain
    ├── ProductStatistics.java
    ├── ProductStatisticsSummarized.java
    ├── StatisticsRangeFilterType.java
    └── StockEvent.java

Spring is responsible for wiring dependencies and Spring Boot is responsible for providing necessary configurations to make the app run.

Getting Started

Clone the repo into your current working dir:

git clone https://github.com/francbreno/stock-handling.git

Go to the cloned project dir

cd stock-handling

Prerequisites

You just need Java 8 or higher to run the application. Check your current installation version using the following command:

java -version

You can get a new Java version from Oracle here.

Installing

You can download the dependencies using the embedded Maven

./mvnw clean install

You can run and debug this application application as you would any other Java program.

Before running the application, make sure you have the ports 8282 (Server) and 37017 (Embedded MongoDB) free. You can change them in the application.properties file.

Running the tests

Just use the maven wrapper

./mvnw clean test

You can also run with your regular Maven Installation

mvn clean test

Built With

  • Spring Boot - The web framework used
  • Maven - Dependency Management
  • Junit Jupiter - Use to execute unit and integrations tests
  • Lombok - Used to reduce Java source code verbosity and eliminate boilerplate code
  • Embedded MongoDB - Use to store product stock statistics data
  • H2 - Used to keep product stock's last data

Authors

License

This project is licensed under the MIT License - see the LICENSE.md file for details

stock-handling's People

Contributors

francbreno avatar

Watchers

James Cloos avatar  avatar

stock-handling's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.