liveBook · Manning

Separation of concerns

As explained in Functional Design and Architecture: Examples in Haskell

Separation of concerns is a design principle that isolates distinct responsibilities so they can be understood and changed independently.

When application logic directly performs effects, tests become dependent on shared state and execution order. Separation of concerns keeps responsibilities and effects apart so each part can be understood, replaced, and tested independently. section 15.1.1 section 15.2.1

A practical boundary hides every external subsystem behind an interface. Business logic depends on those interfaces rather than concrete effects, allowing implementations to be replaced without rewriting the logic. section 15.2.1

A separated design follows these constraints:

  • Hide each external service behind an interface. section 15.2.1
  • Keep business logic free of bare effects and interface-bypassing hacks. section 15.2.1
  • Provide mock or stub implementations for testing. section 15.2.1
  • Give each test one responsibility and keep tests independent. section 15.1.1

Contained effects versus an intruding effect

A labyrinth generator expressed through a language interface can contain random-number effects within that boundary. A direct IO version can hide an unrelated destructive command alongside the intended work, making the behavior harder to control and test. section 15.2.1

Listing 2.6 A possible free monadic scenario
script :: Language ()                #1
script = do                          #2
  readThermometer "Garage"
  readThermometer "Near the road"
  readThermometer "House"
  readBarometer "Garage"
  readBarometer "House"
  reportTemperature
  reportAtmospherePressure
  clearData

Browse a declarative thermometer-and-barometer script whose interpreters can vary independently from the application scenario. section 2.2.3

How Functional Design and Architecture: Examples in Haskell covers it

How deep it goes
Descends from subsystem boundaries to interface rules, mocks, test independence, and hidden-effect risks.
Examples
Uses sensor-reporting scripts, labyrinth generation, mock implementations, and independent Hspec tests.
What it assumes
Assumes familiarity with application logic and effects while defining interfaces, mocks, and test independence explicitly.
What you can do after
Diagnose testability problems and apply interfaces, mocks, and controlled effects to isolate business logic.
How it connects
Connects free monads, interfaces, business logic, mocking, white-box testing, and functional or object-oriented programming.

Also explained in

Compare how 22 books explain separation of concerns →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Design and Architecture: Examples in Haskell. The section links point to the parts of the book it draws on.