-
Notifications
You must be signed in to change notification settings - Fork 1
Application Design
On this page we will cover a little about why BNCore is designed the way it is. Please note, the design is constantly evolving as we discover new challenges and new patterns.
In web application design, the most popular design pattern is called MVC
; Model, View, Controller. In short, it splits the logic of the most important parts of the application into three separate pieces. Models are your data, views display the data in the browser, and controllers control the logic.
Similarly, there are three main pieces of BNCore. They are mostly the same, but we add a "Service" layer and combine the Controllers and Views into one, due to the nature of Minecraft programming.
- Models
- Control the data
- Services
- Provide an interface with the data
- Control the common logic
- Controllers
- Command handlers, event listeners, etc
- Handle the views, user experience and front-end logic
Splitting up the application into these pieces allow us to create patterns (e.g. commands framework and services pattern), centralize logic, and overall improve the organization of our application.
When we need an object to store data in memory and use in our logic, we create a model. Usually a very simple POJO.
We use Lombok to enhance our models. Most of our POJOs just have the @Data
annotation on the class which creates constructors, getters and setters for us.
NOTE: You will need to install the Lombok plugin in Intellij to gain access to Lombok's features while developing.
Our service layer has two jobs:
- Work with data
- Database queries should never be run outside of a service.
- Provide utilities relating to the data and feature
- Calculations, common logic, etc. If it could be used by more than one process (e.g. controller and/or listener and/or public API), it belongs in a service.
All services should extend the BaseService
for helper methods and access to the database.
IMPORTANT: When using a service, ALWAYS create a new instance. The same service should never be used for multiple unrelated processes, especially asynchronously.
Data persistence is a huge part of Bear Nation's core, and we use the anti-ORM library Norm (Not-ORM) to help us interface with our database. A simple service layer was designed to enable the controllers (commands, listeners, etc) to use the data available through Norm.
ORM stands for Object-Relational Mapping. In simple and relevant terms, an ORM library creates a relationship between your database and your java objects. It helps load the data into your object, and deposit it back into the database.
When creating a model that will be stored persistently, a database table is created mirroring object's properties in the bearnation
database. Norm then handles the relationship between the two.
This blog post from the original developer of Norm explains why a "Micro-ORM" is, in some cases, a better approach.
For more information on Norm, please read the official documentation.
We run a modified version, but the differences are minimal.
In BNCore, our controllers are a composite of multiple different pieces that make up the "front-end". This is where everything that a user interacts with directly happens, most notably commands and event listeners. Controllers ask the services for data and common logic, and control the entire user experience.
If we create a public API, it would also be considered a controller.