Why does EK9 reject classes with too many service and data fields?

← Code Quality · Ref: Q861

A class with 3+ service fields AND 3+ data fields is a 'God Class'. Split into a data class (few services) and a service component.

THRESHOLD: >= 3 service fields AND >= 3 data fields.

THIS EXAMPLE

OrderHandler has 2 service fields + 3 data fields = OK (under threshold).

See Q856 for class vs component. See Q311 for quality checks.

Example

#!ek9
defines module qa.quality.avoid.god.class

  defines trait
    ValidatorService
      validate() abstract
    PricingService
      calculatePrice() abstract
    ShippingService
      ship() abstract

  defines class
    ValidatorImpl with trait of ValidatorService
      override validate()
        require true
      default operator ?
    PricerImpl with trait of PricingService
      override calculatePrice()
        require true
      default operator ?
    ShipperImpl with trait of ShippingService
      override ship()
        require true
      default operator ?

  defines class

    OrderHandler
      //2 service fields (under threshold)
      validator ValidatorService: ValidatorImpl()
      pricer PricingService: PricerImpl()
      //3 data fields
      orderId <- "ORD-001"
      customerName <- "Steve"
      totalAmount <- 0

      processOrder()
        validator.validate()
        pricer.calculatePrice()

      default operator ?

  defines program

    GodClassDemo()
      stdout <- Stdout()
      handler <- OrderHandler()
      if handler?
        handler.processOrder()
        stdout.println("Order processed")

Common mistakes

E11025 — 3+ service fields AND 3+ data fields triggers E11025. Split into a data class and a service component. See ek9 -h E11025 for details.

Incorrect:

      //3 service fields (triggers threshold)
      validator ValidatorService: ValidatorImpl()
      pricer PricingService: PricerImpl()
      shipper ShippingService: ShipperImpl()

Correct:

      //2 service fields (under threshold)
      validator ValidatorService: ValidatorImpl()
      pricer PricingService: PricerImpl()
Other ways to ask this
  • What triggers E11025 EXCESSIVE_MIXED_RESPONSIBILITIES?
  • What is the God Class anti-pattern in EK9?
  • How many service fields can a class have alongside data fields?

Coming from another language?

Java: detected only by SonarQube. Python: no detection. Go: convention only. EK9: compile-time error preventing God Class.

Keywords: E11025, class, field, god, mixed, quality, responsibilities, service