Cyclic Dependency

Written by

in

Description

This smell arises when two or more abstractions depend on each other directly or indirectly (creating a tight coupling between the abstractions). A cyclic chain of calls between abstractions exists.

Context

Derived from: “Cyclic Dependency” or “Circular Dependency”
A special form of Cyclic Dependency is sometimes exhibited with specializations. A subtype has an obvious dependency on its supertype. However, when the supertype also depends on the subtype (for instance, by having an explicit reference to the subtype), it results in a cyclic dependency.

Cause

Hard to visualize indirect dependencies.

Consequences

Abstractions involved in a cyclic dependency can be harder to maintain or reuse, as they are more strongly coupled.

Detection

Abstractions depend on each other in a cyclic interaction pattern, e.g. A depends on B, B depends on C, and C depends back on A. So check all reachable elements for the original element to detect cycles. We set ten as the default maximum value for filtering cyclic paths. That is, the query looks for a cyclic path with at most ten edges between nodes. The relation length is set as a query parameter and enterprise architects can modify the default value based on their model size. However, setting a very large value as hop degree may impact the query performance.

Solution

Resolve the cycles by e.g. relocating functionality (merging) or use an intermediary element.

Example

A depends on B, B on C and C on A

Cypher query

MATCH (m) WITH collect(m) as nodes CALL apoc.nodes.cycles(nodes, {maxDepth: $maxDepth}) YIELD path RETURN path as p

Diagram

Diagram for Cyclic Dependency

Aliases

Circular Dependency

Tags

soa, microservices, business, application, technology, The Couplers, between elements, automatic detection

Query parameters

[
    {
        "name": "maxDepth",
        "type": "number",
        "default": 10,
        "description": "The max length of cyclic path between elements."
    }
]

Related smells

All smells