java-design-patterns
java-design-patterns copied to clipboard
Functional core, imperative shell pattern
Description
The Functional Core Imperative Shell (FCIS) design pattern aims to segregate the purely functional part of the code (Functional Core) from the side-effect-laden part (Imperative Shell). This separation enhances testability, maintainability, and robustness by isolating side effects and minimizing their scope.
Main Elements of the Pattern:
-
Functional Core:
- Pure functions without side effects.
- Deterministic outputs based on inputs.
- Contains the business logic of the application.
- Facilitates easy unit testing.
-
Imperative Shell:
- Encapsulates side effects such as I/O operations, database access, and API calls.
- Interfaces with the outside world.
- Manages state changes and interactions.
- Bridges the Functional Core with the real-world environment.
Implementation Steps:
- Identify and extract the business logic into pure functions.
- Encapsulate side-effect operations within dedicated modules.
- Define clear interfaces between the Functional Core and Imperative Shell.
- Write unit tests for the Functional Core functions.
- Ensure integration tests cover interactions within the Imperative Shell.
References
- Functional Core, Imperative Shell - Gary Bernhardt
- Building Modern Architectures: Functional Core, Imperative Shell - Albert Llousas
- Functional Core Imperative Shell - Kenneth Lange
- A Look at the Functional Core and Imperative Shell Pattern - SSENSE Tech
Acceptance Criteria
- The project codebase should have a clear separation between the Functional Core and the Imperative Shell.
- All business logic should reside in pure functions within the Functional Core, with appropriate unit tests.
- All side-effect operations should be encapsulated in the Imperative Shell, with integration tests to ensure correct interactions.
Hi @iluwatar ! I would like to look into this design pattern.
Thanks @inkfin, go ahead