Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Monolith to Modular — Part 3: Managing Violations

DZone's Guide to

Monolith to Modular — Part 3: Managing Violations

Learn how to manage dependencies that cause violations when extracting your monolithic codebase to microservices architecture.

Free Resource

Record growth in microservices is disrupting the operational landscape. Read the Global Microservices Trends report to learn more.

Dependencies that violate your target module structure need to be resolved before code can be extracted from the monolith into the new module.

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

Series links:

In our previous post, we described the simplest “Extract Module” scenario, in which the new module has no dependencies on the remaining monolith. This post describes the scenario where the proposed new module and remaining monolith are mutually dependent. The Levelized Structure Diagram below illustrates this. 

Image title

There is a circular dependency between the monolith and the new module that has to be resolved before code can be moved into the new module (build systems don’t like module cycles). 

Resolving the cycle requires identification of the dependencies that violate the target architecture. More specifically identifying the code that causes the violations and then refactoring to remove it.

Identifying the violating dependencies requires

  1. An Action List that captures the steps to create the new module and move its content.

  2. A Structure Specification that shows the new module in the target architecture.

  3. A Dependency Breakout that lists the code causing the violations.

The Action List identifies the classes that are being extracted. In this example, there are just four actions in the list:

Image title

The violations will either be dependencies from the monolith into the code being moved or the other way around. It depends on how the target architecture positions the new module.

Which is why we need the Structure Specification. It specifies the relationship between the monolith and the new module. We can't use the Levelized Structure Diagram because it layers the modules based on the current dependencies and that might not be what we want as a target architecture.

If the monolith is dependent on the new module then any dependencies on the monolith from the code being extracted are the violations. These are shown as a dotted arrow in the Structure Specification diagrams below.

Image title

If the new module is to be dependent on the monolith, the violations are reversed.

Image title

The Dependency Breakout is a detailed list of all the contributing code constructs that cause the violations. The breakout for the new-module dependency on the monolith is shown below.

Image title

This breakout is a list of the code that needs refactoring to resolve the violations. Unlike the class moves in the Action List, the violating dependencies can be resolved incrementally.

When all the violations have been removed, the last task is to create the module and move the code into it from the monolith. The developer making these final changes can follow the Action List step by step to implement the module creation and class moves.

In the next post, we will describe how the violating dependencies can be used to build a backlog of work for planning and estimation.

You can see a worked example of Extract Module in this blog post. If you are interested in seeing how your software project looks in Structure101 Studio or Workspace, download a free trial.

Learn why microservices are breaking traditional APM tools that were built for monoliths.

Topics:
microservices ,tutorial ,monolith ,modularization ,software architecture

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}