DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Spring Boot - Microservice- JaxRS Jersey - HATEOAS - JerseyTest - Integration
  • Upgrade Guide To Spring Boot 3.0 for Spring Data JPA and Querydsl
  • Spring Data: Data Auditing Using JaVers and MongoDB
  • JobRunr and Spring Data

Trending

  • How to Format Articles for DZone
  • Stateless vs Stateful Stream Processing With Kafka Streams and Apache Flink
  • From Fragmentation to Focus: A Data-First, Team-First Framework for Platform-Driven Organizations
  • Transforming AI-Driven Data Analytics with DeepSeek: A New Era of Intelligent Insights
  1. DZone
  2. Coding
  3. Frameworks
  4. Remembering Clean Architecture

Remembering Clean Architecture

Before picking a framework or a language, agree with your team on architecture. This sample Spring Boot app walks through a refactoring focusing on clean architecture.

By 
Mahan Hashemizadeh user avatar
Mahan Hashemizadeh
·
May. 19, 17 · Tutorial
Likes (39)
Comment
Save
Tweet
Share
30.6K Views

Join the DZone community and get the full member experience.

Join For Free

As developers, we can spend considerable periods of time debating and advocating various languages and frameworks.

Irrespective of the pros and cons of a particular language or framework, if the architecture isn’t clear and agreed upon from the beginning, then interest in building new and the ability to maintain existing functionality diminishes. 

Basically, the pride that went into creating it wanes, and what was once fun to work on is now a burden.

Does the loose structure of Fig.1 below seem familiar?

It led me to ask the following questions:

What is the intent of this application? How is that intent fulfilled? Why are there so many packages at the root level?

Image title

Fig. 1

The answers to the above can certainly be found, but it comes across that things were added after the fact without really knowing where they are meant to go.

This seems like a case where the architecture wasn’t clear from the beginning and, as the application grew, it became further unclear.

There is no clear separation between what the application does and how it does it.

Begin With a Clean Architecture

Before even selecting which language or framework to use, determine and agree upon the architecture.

Robert C. Martin and others have provided great material on this subject, and I am going to share my understanding.

Before I even started refactoring the code, I first decided upon the architecture (see Fig. 2 below).

Image title

Fig. 2

See this example repository on GitHub for the intent of each module.

Refactor to a Cleaner Architecture

Core

Image title

The usecase implements the interfaces in the boundary.enter package and uses the ones in boundary.exit.

Depends on: This module has no dependency on any other module. It is also framework agnostic.

Periphery

Data

This module contains the repositories that retrieve or edit data in the database.

It implements the interfaces defined in the boundary.exit package, meaning that this module has a direct dependency on core.

Depends on: core

Web

This module contains the controllers (e.g. REST API).

This module uses the adapter module to communicate with the core, meaning that it has no direct dependency on the core.

Depends on: adapter

Adapter

Image title

My original intention of the adapter was to handle all the communication with the core, hence nothing in the periphery would ever depend directly on the core.

However as described above, the data module in the periphery does not use the adapter, it’s only used by the web module (converts the domain objects into the api that the web module expects).

The reason is that I didn’t want any framework knowledge inside the adapter module, and since I am using Spring Data in my data module, there isn’t a way to use the data module without making the adapter Spring Data aware.

Depends on: core

Configuration

Image title

This module glues everything together.

It contains the MainApplication (in this case a Spring Boot application), all the Spring @Configuration files and the resources needed to make the application work.

Depends on: adapter, core, data, and web

Other Improvements

During the refactoring, I detected that some of the tests were actually integration tests and that they no longer had a home inside any of these new modules.

As a result, I moved all these tests to a new integration-test module.

Summary

Although there is no definitive answer on how to architect a software solution, I feel that agreeing upon a clean architecture up front will pay dividends.

Above I have described my journey towards a cleaner architecture and, as an aid, I have created a sample application on GitHub to demonstrate it.

Architecture Spring Framework Data (computing) application Spring Data integration test Framework Robert C. Martin Spring Boot Web Protocols

Opinions expressed by DZone contributors are their own.

Related

  • Spring Boot - Microservice- JaxRS Jersey - HATEOAS - JerseyTest - Integration
  • Upgrade Guide To Spring Boot 3.0 for Spring Data JPA and Querydsl
  • Spring Data: Data Auditing Using JaVers and MongoDB
  • JobRunr and Spring Data

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!