Design And Create Modules on Code Base

Petros Koulianos ๐Ÿ’€โ˜ ๐Ÿ‘ฝ
4 min readSep 20, 2022

Why we need and how to create modules in a code base

Working on a code base where business logic and other functionalities are scattered is at least a frustrating situation for software developers.

Modules are a solution to keep things clean and separated in a code base such as a well-organized warehouse with products.

๐ŸŒŠLetโ€™s deep dive into modules

Characteristics of a Module

Modules have clear characteristics that must follow :

  • Bounded Context Every module has a clear bounded context that encapsulates all the functionalities. For example a module with User as a bounded context, will encapsulate and expose all the functionalities of the User.
  • High Cohesion A module with a well-defined bounded context has all its close related code very close
  • Low Coupling A module must have few or zero dependencies
  • High Reusability By nature, a module is designed to be reusable
  • Information Hiding Modules have to expose only the necessary information and hide all other data that consumers donโ€™t need
  • Less effort for refactoring and migrations In cases that we need to refactor or we need to migrate a module is way easier because all the consumers-client depend on the module interface
Code Base With Modules

Interface and Model Consistency

Every module has to expose a bunch of different classes, functions, and data (models).

These functionalities and models are the stable contract that other modules will consume, and interact with.

All the inner logic must be encapsulated and hidden.

The best practice is to expose all module functionalities with an interface and all consumers will interact with it.

This approach is known as the Dependency Inversion Principle (DIP).

With DIP we can create loosely coupling modules

Modules with DIP

For example, in the above pic case if the Blog module needs to get the info for a User the Blog module doesnโ€™t know where the user data is located and how itโ€™s retrieved. The result is that we have eliminated the data and implementation logic coupling between the 2 modules.

Structuring

We can build a well-structured module in 3 steps :

  1. Create the main interface that will expose all the module functionality
  2. Create all the module inner logic behind the interface
  3. Create the data store (database access, HTTP requests, IO operations, etc), the data store must be independent between the modules
Structure of a Module

Communication between modules

Synchronous

Synchronous communication between modules is when a module-a call directly a function on a module-b

Sync Communication of modules

Asynchronous

Asynchronous communication between modules is when modules communicate with events and a publish-subscribe system (aka message bus).

The publish-subscribe system can be :

  • Built into the code base
  • Implemented with an out-of-process system like Redis, Kafka, RabbitMQ, etc
Async Communication of modules

Types Of Modules

We can have 2 types of modules :

  • Domain base modules these types of modules offers business logic and support all domain use cases
  • Infrastructure modules these types of modules donโ€™t have any business logic and support all the app operations
Module Types

Benefits of using modules on the code base

โœ… A more Clean Architecture

โœ… Higher DX

โœ… High cohesion at code base level

โœ… Low coupling at code base level

โœ… Easier to refactor functionalities

โœ… Easier to migrate to a microservices architecture

โœ… Separation of concerns โ€” Single Responsibility

โœ… Encapsulation of failures at a module level

--

--

Petros Koulianos ๐Ÿ’€โ˜ ๐Ÿ‘ฝ

Software Engineer ๐Ÿ‘ฝ | Building applications for health industry | Work with JavaScript, Typescript, PHP | My Newsletter๐Ÿ“ฉ at petran.substack.com