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
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
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
Join us today at 1 PM EST: "3-Step Approach to Comprehensive Runtime Application Security"
Save your seat
  1. DZone
  2. Data Engineering
  3. Data
  4. Migrating From Monolith to Modular — Part 1

Migrating From Monolith to Modular — Part 1

This series exploring the challenges of migrating from a monolithic to a modular architecture like microservices starts with an overview of the problem: identifying the modules.

Mike Swainston-Rainford user avatar by
Mike Swainston-Rainford
·
Aug. 20, 18 · Opinion
Like (7)
Save
Tweet
Share
11.19K Views

Join the DZone community and get the full member experience.

Join For Free

This is the first post in a series that will explore the challenges of migrating a monolithic code base to a modular architecture.

If you type "migrate monolith" or "refactor monolith" into a search bar, the resulting pages of links have a significant bias towards migrating a monolith to microservices. Chris Richardson's post Refactoring a Monolith into Microservices is a good example of the strategy-based approach to migration that is suggested by a number of authors. His strategy number 3 is "Extract Services:"

"The third refactoring strategy is to turn existing modules within the monolith into standalone microservices. Each time you extract a module and turn it into a service, the monolith shrinks. Once you have converted enough modules, the monolith will cease to be a problem. Either it disappears entirely or it becomes small enough that it is just another service."

The problem with this is it assumes the modules within the monolith are obvious, which is, more often than not, not the case. The hardest problem for many, if not most, organizations migrating to microservices is identifying and extracting modules.

Typing "monolith java 9 module" in the search bar returns numerous links to information about Java 9 modules. But, in amongst the general knowledge, you will find "Modules vs. Microservices" and "Modules or Microservices." The first is a link to the O'Reilly site and the book Java 9 Modularity by Sander Mak. The second is a link to his slide presentation in which he argues the case for Java 9 modules providing the modularity benefits inherent in microservices without the upheaval they inflict on organization and process. He opens his presentations with a confession that he likes building monoliths, then qualifies this to modular monoliths. He makes a compelling argument for the value of modular monolith over microservices. In any case, modular monolith seems to be a prerequisite of micro-services, as Martin Fowler suggests in "Monolith First."

Of course, some organizations can only dream about Java 9 and microservices. Applications that are old enough to have reached their teens (or even early twenties!) are clearly core to the organization and its business. Such applications are likely to have been under continuous development. The team will have cycled several times over the years, contributing to varied styles of implementation. Whatever the architectural vision was at the start of the project, it is unlikely to help today's team understand the code. Failed architectural initiatives and incomplete technology migrations contribute to the mountain of technical debt that inevitably builds under the pressure for functional change. The code base becomes a tangle of inter-dependencies with little, if any, regard for interfaces and segregation. Ironically, such applications probably have the most to gain from migration to a modular architecture. But where to start when "everything depends on everything else"?

Whatever the desired end state, the challenge is the same: given a monolith of tangled code, how can it be transformed into a modular structure? The business will invariably prevent a Big Bang — such a transformation almost always needs to be carried out incrementally.

Which leads to a simple strategy:

Transform the Monolith Through Incremental Extraction of Modules

Paraphrasing Chris Richardson:

"Each time you extract code into a module, the monolith shrinks. Once you have extracted enough modules, the monolith will cease to be a problem. Either it disappears entirely or it becomes small enough that it is just another module."

Whether the end goal is Java 9 modules or microservices doesn't matter. The module extraction strategy applies in either case. In fact, they don't need to be a part of the transformation. Either technology can help to enforce strong encapsulation and well-defined interfaces, but that can be achieved using dependency analysis tools like Structure101 Studio and Structure101 Workspace, avoiding the added complexity of a technology migration on top of the structural one.

The Devil Is in the Dependencies

Sander Mak describes the 3 tenets of modularity as strong encapsulation, well-defined interfaces, and explicit dependencies. The key to successful extraction of a module is making explicit the inbound and outbound dependencies of the code being extracted. Only then can they be analyzed, managed, and refactored to comply with the intended architecture. The degree of tangling within the code being moved doesn't matter. It is the module-level dependencies that are the focus of the extraction. Indeed, moving code from one module to another can introduce tangles into an otherwise acyclic dependency structure.

Consider the simple package structure below that is organized into a layered structure diagram. The arrows show the dependencies between the packages rolled up from the contained classes. The packages and their dependencies form a directed acyclic graph (DAG). There are no tangles in this structure.

However, extracting the package codeforextraction to a separate module creates a tangle, as shown below. The dotted line indicates a dependency cycle between the modules.

This module-level cycle means that the code cannot be built by a framework such as Maven. It would fail on finding the cyclic dependency during parsing of the pom.xml files. The dependencies causing the cycle need to be removed before the code can be extracted to the new module. Doing so can be a complex and time-consuming refactoring exercise.

This series of posts describes how Structure101 Studio and Structure101 Workspace can be used to:

  • Identify candidates for extraction
  • Size and scope the refactoring effort
  • Communicate the intended architecture to the wider team
  • Monitor removal of violating dependencies (and guard against new ones)

The next post uses a simple example to illustrate the approach, follow on posts will delve into more common and harder problems.

microservice Dependency

Published at DZone with permission of Mike Swainston-Rainford. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Fraud Detection With Apache Kafka, KSQL, and Apache Flink
  • How Do the Docker Client and Docker Servers Work?
  • Real-Time Stream Processing With Hazelcast and StreamNative
  • Java Development Trends 2023

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: