E11015: excessive efferent coupling - depends on too many types

Category: E11xxx Code quality and IR analysis · Reported in phase: PRE_IR_CHECKS · Classification: EXCESSIVE_EFFERENT_COUPLING · All error codes

What went wrong

Your class depends on too many other types. "Efferent" (Ce) means outgoing - how many types YOUR class reaches out to.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 762 (What is the efferent coupling limit and how do I stay wit...)

Rationale

  • Ce (Efferent Coupling) counts external type dependencies
  • Excludes: built-in types (Integer, String, List, etc.)
  • Thresholds: CLASS=12, COMPONENT=15, SERVICE=15, TRAIT=8, FUNCTION=8

[REFACTORING PATTERN (Facade)] Before: OrderProcessor depends on 15 services (Ce=15) After: a PaymentHandler wraps PaymentService, FraudService and TaxService; a FulfillmentHandler wraps InventoryService and ShippingService; OrderProcessor depends on the handlers alone (Ce=3).

How to fix it

  1. Group related dependencies by purpose
  2. Create "handler" or "facade" classes for each group
  3. This class now depends on handlers, not individual types

Common causes

  • Too many dependencies accumulated over time
  • Missing abstraction layer

See also

  • E11015: coupling (too many dependencies) (this error)
  • E11014: cohesion (unrelated methods in one class)
  • E11016: module coupling (external module dependencies)

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E11015: excessive efferent coupling - depends on too many types

#!ek9
defines module error.e11015.bad

  //Define 9 helper types to create coupling
  defines record
    TypeA
      mainValue as Integer: 0
      default operator ?
    TypeB
      mainValue as Integer: 0
      default operator ?
    TypeC
      mainValue as Integer: 0
      default operator ?
    TypeD
      mainValue as Integer: 0
      default operator ?
    TypeE
      mainValue as Integer: 0
      default operator ?
    TypeF
      mainValue as Integer: 0
      default operator ?
    TypeG
      mainValue as Integer: 0
      default operator ?
    TypeH
      mainValue as Integer: 0
      default operator ?
    TypeI
      mainValue as Integer: 0
      default operator ?

  defines function

    TooManyDependencies()
      ->
        a as TypeA
        b as TypeB
        c as TypeC
        d as TypeD
        e as TypeE
        f as TypeF
        g as TypeG
        h as TypeH
      <-
        result as TypeI?

      //Use all parameters to avoid dead code warnings
      require a? and b? and c? and d?
      require e? and f? and g? and h?
      result :=? TypeI()

Fixed: Group the values that travel together into one record

#!ek9
defines module error.e11015.good

  defines record

    Order
      item as String: String()
      quantity as Integer: 0

      default operator ?

    Shipping
      address as String: String()
      express as Boolean: false

      default operator ?

    Receipt
      summary as String: String()

      default operator ?

  defines function

    fewerDependencies()
      ->
        order as Order
        shipping as Shipping
      <- result as Receipt?

      require order? and shipping?
      result :=? Receipt()

Questions and answers

These Q&A entries show E11015 and its fix: