Overgeneralization

Written by

in

Description

In order to assure that components provide the greatest extent of reusability, they must be flexibly applicable. This generalization can be overdone though, which will result in overgeneralization. It will become more flexible than it actually needs to be.

Context

Derived from: “Ambiguous Interface”
A service offers a single and very general operation instead of allocating its provided functionality. Sometimes combined with Bloated Service.

Cause

May easily appear in systems, where interactions are not explicitly modeled and multiple services exchange event messages on a regular basis.

Consequences

Not only does this smell lead to additional development work, it also makes using the components more difficult. Analyzability and understandability are reduced, because a service does not allocate all its provided functionality in a clear manner. Therefore, a user has to analyze this element before using it.

Detection

In the ArchiMate modeling language, we can detect this Smell by searching for components that perform many functions and communicate with various services but publish only one service exposed by an interface.

Solution

This problem can be tackled by moving the always identical user modifications into the component. Otherwise, split the single generic operation into multiple more specialized operations to allow for more suitable applications.

Example

Interface with a single operation that needs further information as input in order to yield the desired result. Overgeneralization (Ambiguous Interface) appears specifically in publish-subscribe patterns. In ArchiMate, detecting this Smell involves identifying components that perform numerous functions and interact with various services but expose only one service through an interface.

Cypher query

MATCH (i)-[r1:CompositionRelationship]-(c) <br /> MATCH (c)-[r2:RealizationRelationship]-(s) <br /> WITH c, COUNT(s) AS exposedServiceCnt, COUNT(i) AS interfaceCnt <br /> WHERE exposedServiceCnt=1 AND interfaceCnt=1 <br /> MATCH (c)-[r:AssociationRelationship|AssignmentRelationship]-(f) <br /> WITH c, COUNT (f) AS functionOrServiceCnt <br /> where functionOrServiceCnt > $functionOrServiceCnt <br /> MATCH p = (c)-[r:AssociationRelationship|AssignmentRelationship|RealizationRelationship|CompositionRelationship]-(f) <br /> RETURN p

Cypher count query

MATCH (i)-[r1:CompositionRelationship]-(c) <br /> MATCH (c)-[r2:RealizationRelationship]-(s) <br /> WITH c, COUNT(s) AS exposedServiceCnt, COUNT(i) AS interfaceCnt <br /> WHERE exposedServiceCnt=1 AND interfaceCnt=1 <br /> MATCH (c)-[r:AssociationRelationship|AssignmentRelationship]-(f) <br /> WITH c, COUNT (f) AS functionOrServiceCnt <br /> where functionOrServiceCnt > $functionOrServiceCnt <br /> MATCH p = (c)-[r:AssociationRelationship|AssignmentRelationship|RealizationRelationship|CompositionRelationship]-(f) <br /> RETURN count (distinct c)

Diagram

Diagram for Overgeneralization

Tags

microservices, soa, business, application, technology, ambiguity, within elements

Query parameters

[
    {
        "name": "functionOrServiceCnt",
        "type": "number",
        "default": 3,
        "description": "Permitted number of functions that performed by the overgeneralized componennt."
    }
]

Related smells

All smells