Skip to main content

Scaffolding

Introduction to DDD


Our intention is to orient our project development strategy to something like the Domain-Driven Design (DDD). DDD is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts. To further reading about the subject, I would recommend you the following interesting articles:

What is Module?


This concept of Module somehow represents the key domains of the application's business. These modules are the most important parts or sections of the application. They are meant to live on their own, independently of their siblings' modules to exist. A well-implemented modular architecture should be able to easily remove or integrate modules to the application. And with just a few configurations should be working fine. These modules could interact with each other to share some information, but we should be really careful about these situations to avoid over coupling them together.

Moving the explanation to a more practical representation, and specifically to our implementation in React, a module is going to have a main component that is going to be its entry point. This component could also have its own .container file to connect to the Redux store, its own .styles file to stylish the component itself.

Besides, a module could present the following folders:

  • components: this folder is going to contain all the components that are only used within the module. If your component is imported by some other module, consider adding the component to a shared folder.

  • store:  if the module's component or any of the components within the components needs to interact with the Redux store, then within this folder we are going to create a specific sliced reducer, the actions, the selectors, the thunks and the types required for those behaviors.

  • services: this folder will contain all the services that are consumed only by this module in particular

  • helpers: this folder is going to contain all the helper functions used within the module itself.

  • constants: this folder is going to contain all the files that export constants variables that are used within the module itself.

  • types: this folder is going to contain all the files that have the definitions for the Typescript types of the module.

  • Interfaces: this folder is going to contain all the interfaces for typescript of the module.

  • DTOs: this folder is going to contain all the DTO files of the module.

Can a module be consumed by more than one module?


Yes! Of course, it can! Let's take a table module as an example. We could have built a Table component in a way that can be reused by any of the modules, supporting all the different features that are required to be able to customize a table in each of the implementations.

What's the difference between a module and a shared component?


One could think the Table module for example, as a shared component instead, and directly create the component and its children components within a module called "shared". But that's exactly the key where you can differentiate a module from a shared component. The last one is just one single component, don't need from some other components either the store to live on its own. A module needs to interact with the store, needs to render multiple children components, maybe needs to have helpers functions or also its own constants and types.

What should be included in the "core" module?


You can think it of like:

  • "It should be everything that is "core" for the application to live."
  • "Every business definition that is consumed by more than one module, should be placed within the core module."

It is really, really easy to fall in the temptation of adding something to the core module. This module shouldn't be the first place that comes to mind when we don't know where to locate some logic, file, function, etc. Instead, it should be the last one, it should be determined by if some module needs to use something from some other module, and as said in the section "What is Module?", modules shouldn't be importing stuff from their siblings. So, this is the moment, this is the point, where we should move those  constants, that helpers file, those messages to the core module and make both modules consume from there.