E11014: low cohesion - class has disconnected method groups, consider splitting
What went wrong
Your class is doing too many unrelated things. Methods don't work together - they're strangers sharing an office. (LCOM4 metric)
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 761 (What is the LCOM4 cohesion limit and how do I stay within...)
Rationale
- LCOM4 counts "connected components" (method groups)
- Methods are connected if they share field access
- Score of 1 = perfect (all methods work together)
- Thresholds: CLASS=8, COMPONENT=10
Refactoring pattern
Before: BigClass with groups A, B, C (LCOM4=3) After: ClassA (LCOM4=1), ClassB (LCOM4=1), ClassC (LCOM4=1)
Coordinator uses ClassA, ClassB, ClassC
How to fix it
- Identify disconnected method groups (use different fields)
- Create new class for each group (one responsibility per class)
- Move fields and methods together
- Use composition if original class needs to coordinate
Common causes
- Too many responsibilities in one class
- Methods accumulated without refactoring
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E11014: low cohesion - class has disconnected method groups, consider splitting
#!ek9 defines module error.e11014.bad defines class LowCohesionClass //9 separate fields - each used by only one method field1 as Integer: 1 field2 as Integer: 2 field3 as Integer: 3 field4 as Integer: 4 field5 as Integer: 5 field6 as Integer: 6 field7 as Integer: 7 field8 as Integer: 8 field9 as Integer: 9 //9 methods - each uses only one field, creating 9 disconnected components //LCOM4 = 9 > 8 (class threshold) method1() <- rtn as Integer: field1 method2() <- rtn as Integer: field2 method3() <- rtn as Integer: field3 method4() <- rtn as Integer: field4 method5() <- rtn as Integer: field5 method6() <- rtn as Integer: field6 method7() <- rtn as Integer: field7 method8() <- rtn as Integer: field8 method9() <- rtn as Integer: field9 //Custom isSet that only accesses field1 - doesn't connect other methods override operator ? as pure <- rtn as Boolean: field1?
Fixed: Split the class so each one keeps the data its methods use together
#!ek9 defines module error.e11014.good defines class Counter count as Integer: 0 step as Integer: 1 current() <- rtn as Integer: count increment() count += step reset() count: 0 step: 1 default operator ?
Questions and answers
These Q&A entries show E11014 and its fix: