Keep project code honest by naming which layer owns each dependency.

boundaries When dependencies are described explicitly, it is easier to keep domain code separate from adapters and tools.

Dependency Boundaries

dependency
dependency_boundaries.rb
Replay: real traced execution (multi-file project)
dependency = "json"
layer = case dependency
when "json"
  "serialization"
when "net/http"
  "adapter"
when "minitest"
  "test"
else
  "unknown"
end

allowed_in_domain = layer == "serialization"
review_needed = !allowed_in_domain

puts "dependency=#{dependency}"
puts "layer=#{layer}"
puts "allowed_in_domain=#{allowed_in_domain}"
puts "review_needed=#{review_needed}"
dependency = "net/http"
layer = case dependency
when "json"
  "serialization"
when "net/http"
  "adapter"
when "minitest"
  "test"
else
  "unknown"
end

allowed_in_domain = layer == "serialization"
review_needed = !allowed_in_domain

puts "dependency=#{dependency}"
puts "layer=#{layer}"
puts "allowed_in_domain=#{allowed_in_domain}"
puts "review_needed=#{review_needed}"
dependency = "minitest"
layer = case dependency
when "json"
  "serialization"
when "net/http"
  "adapter"
when "minitest"
  "test"
else
  "unknown"
end

allowed_in_domain = layer == "serialization"
review_needed = !allowed_in_domain

puts "dependency=#{dependency}"
puts "layer=#{layer}"
puts "allowed_in_domain=#{allowed_in_domain}"
puts "review_needed=#{review_needed}"
  1. dependency ← json, layer ← serialization, allowed_in_domain ← true

    1dependency→ json = "json"  #@dependency="net/http", "minitest"2layer→ serialization = case dependencyjson3when "json"4  "serialization"5when "net/http"6  "adapter"7when "minitest"8  "test"9else10  "unknown"11end1213allowed_in_domain→ true = layerserialization == "serialization"14review_needed→ false = !allowed_in_domaintrue1516puts "dependency=#{dependencyjson}"17puts "layer=#{layerserialization}"18puts "allowed_in_domain=#{allowed_in_domaintrue}"19puts "review_needed=#{review_neededfalse}"
    outputdependency=json
    layer=serialization
    allowed_in_domain=true
    review_needed=false
  1. dependency ← net/http, layer ← adapter, allowed_in_domain ← false

    1dependency→ net/http = "net/http"2layer→ adapter = case dependencynet/http3when "json"4  "serialization"5when "net/http"6  "adapter"7when "minitest"8  "test"9else10  "unknown"11end1213allowed_in_domain→ false = layeradapter == "serialization"14review_needed→ true = !allowed_in_domainfalse1516puts "dependency=#{dependencynet/http}"17puts "layer=#{layeradapter}"18puts "allowed_in_domain=#{allowed_in_domainfalse}"19puts "review_needed=#{review_neededtrue}"
    outputdependency=net/http
    layer=adapter
    allowed_in_domain=false
    review_needed=true
  1. dependency ← minitest, layer ← test, allowed_in_domain ← false

    1dependency→ minitest = "minitest"2layer→ test = case dependencyminitest3when "json"4  "serialization"5when "net/http"6  "adapter"7when "minitest"8  "test"9else10  "unknown"11end1213allowed_in_domain→ false = layertest == "serialization"14review_needed→ true = !allowed_in_domainfalse1516puts "dependency=#{dependencyminitest}"17puts "layer=#{layertest}"18puts "allowed_in_domain=#{allowed_in_domainfalse}"19puts "review_needed=#{review_neededtrue}"
    outputdependency=minitest
    layer=test
    allowed_in_domain=false
    review_needed=true