What is the LCOM4 cohesion limit and how do I stay within it?

← Code Quality · Ref: Q761

EK9 measures class cohesion using LCOM4 (Lack of Cohesion of Methods version 4). It builds a graph of method-to-field relationships — methods sharing at least one field are connected. The number of disconnected subgraphs is the LCOM4 score.

THRESHOLDS

- Class: max LCOM4 of 8 (E11014)
- Service: max LCOM4 of 10
- Component: max LCOM4 of 10

WHAT LCOM4 MEASURES

LCOM4 = 1 means perfect cohesion — all methods work together through shared fields. LCOM4 = 8 means 8 groups of methods that don't share any fields. Above the threshold, the class is doing too many unrelated things.

THIS EXAMPLE

The InventoryTracker class below has exactly 8 disconnected method groups (LCOM4 = 8), which is the maximum allowed for a class. Each method group accesses only its own field. Adding a 9th unrelated method would trigger E11014.

HOW TO FIX HIGH LCOM4

1. Extract each disconnected group into its own focused class
2. Add methods that bridge groups by accessing multiple fields
3. Consider if the class has a single clear purpose

See Q310 for code quality overview. See Q314 for cohesion and coupling details. See Q696 for complexity limits.

Example

defines module qa.codequality.lcom4boundary

  defines class

    <?-
      This class has exactly 8 disconnected method groups (LCOM4 = 8).
      Each method accesses only one unique field.
      No method shares a field with another method.
      This is exactly at the class threshold — it compiles.
      Adding a 9th unrelated method/field pair would trigger E11014.
    -?>
    InventoryTracker
      field1 Integer: 1
      field2 Integer: 2
      field3 Integer: 3
      field4 Integer: 4
      field5 Integer: 5
      field6 Integer: 6
      field7 Integer: 7
      field8 Integer: 8

      method1()
        <- rtn Integer := field1

      method2()
        <- rtn Integer := field2

      method3()
        <- rtn Integer := field3

      method4()
        <- rtn Integer := field4

      method5()
        <- rtn Integer := field5

      method6()
        <- rtn Integer := field6

      method7()
        <- rtn Integer := field7

      method8()
        <- rtn Integer := field8

      override operator ? as pure
        <- rtn Boolean := field1?

  defines program

    Lcom4BoundaryDemo()
      stdout <- Stdout()
      tracker <- InventoryTracker()
      stdout.println($tracker.method1())
      stdout.println($tracker.method8())

Common mistakes

E11014 — Adding field9 and method9 creates a 9th disconnected method group (method9 accesses only field9). LCOM4 goes from 8 to 9, exceeding the class threshold of 8. Extract unrelated methods into separate classes. See ek9 -h E11014 for details.

Incorrect:

      field8 Integer: 8
      field9 Integer: 9

      method9()
        <- rtn Integer := field9

      method1()

Correct:

      field8 Integer: 8

      method1()
Other ways to ask this
  • What triggers E11014 low cohesion?
  • What is the LCOM4 threshold for classes?
  • How does EK9 measure class cohesion?
  • Why does EK9 limit disconnected method groups?

Coming from another language?

Java: SonarQube measures LCOM but only as advisory metric. C#: NDepend reports LCOM informational only. Python: no cohesion analysis. Go: no cohesion measurement. Kotlin: Detekt does not measure LCOM. EK9: LCOM4 > 8 is a compiler error — class won't compile.

Keywords: threshold, split, cohesion, method, class, E11014, field, boundary, quality, metric, LCOM4, disconnect