Description
Two or more abstractions with highly similar functionality exist.
Context
Derived from: “Duplicated Code”
Don’t Repeat Yourself! While Microservices usually follow a “share nothing” philosophy, reuse is a common theme in SOA. Service normalization and consolidation are therefore frequent activities in an SOA to reduce the level of duplication. In Microservices on the other, you consciously allow duplication to exist up to a certain degree, because it reduces coupling and dependencies in your system.
Cause
Duplication usually occurs when multiple architects are working on different parts of the same architecture at the same time. Since they’re working on different tasks, they may be unaware their colleague has already defined similar components that could be repurposed for their own needs. There’s also more subtle duplication, when specific parts look different but actually perform the same job. This kind of duplication can be hard to find and fix. Sometimes duplication is purposeful. When rushing to meet deadlines and the existing architecture is “almost right” for the job, novice architects may not be able to resist the temptation of copying and pasting the relevant elements. And in some cases, the developer is simply too lazy to de-clutter.
Consequences
Duplicated functionality reduces the level of reuse and may confuse service consumers that cannot identify the service or operation they need. Moreover, if this common functionality changes, it needs to change in all duplicated locations, therefore causing higher maintenance efforts. A culture of “build and expose” may form where the enterprise becomes a mess of services all attempting to do the same thing.
Detection
Services or operations with similar or identical names and/or message parameters may exist in your system. If the ratio of similar words to the total number of words in the names exceeds 0.75 the smell is detected.
Solution
Consolidate the duplicate functionality into a single service. If necessary, raise the level of abstraction. Be aware though that this increases coupling in the system and may make the consolidated service a bottleneck or single point of failure.
Cypher query
MATCH p1=(a) , p2=(b) <br /> where a<>b and a.ClassName = b.ClassName <br /> and apoc.text.jaroWinklerDistance (a.name, b.name) < $score <br /> UNWIND [p1,p2] as p <br /> RETURN pTags
soa, business, application, technology, ambiguity, The Dispensables, within elements, automatic detection
Query parameters
[
{
"name": "score",
"type": "range",
"default": 0.4,
"min": 0,
"max": 1,
"step": 0.1,
"description": "Score from 0 to 1. 0 = exact match and 1 = no similarity."
}
]Related smells
- Stovepipe System (relates)
- Combinatorial Explosion (relates)
- Incomplete Abstraction (follows)