HackerTube 中文?
Software boundaries and change →

Does splitting code actually split its dependencies?

Start with a rule that sends an email. Separate deciding from doing, then inspect layers, objects and abstractions: which parts must still change together when the rule changes?

Questions in this reading · 9
  1. Where should a business rule end?
  2. Where do side effects belong?
  3. Can you isolate side effects in the language you already use?
  4. What should cross a module boundary?
  5. Do separate layers really separate concerns?
  6. Can small components still be tightly coupled?
  7. Is removing duplication worth another abstraction?
  8. What makes an object useful?
  9. When is it time to stop coding and rethink the problem?

Where should a business rule end?

Separating independent concerns becomes concrete in a functional core: compute the decision from values, then let another layer carry out its effects.

Compare original passages and timestamps · 2
start seeing interconnections between things that could be independent
"Simple Made Easy" - Rich Hickey (2011) · ▶ 59:28–59:32
an imperative shell that surrounds the functional core.
Ruby Conf 12 - Boundaries by Gary Bernhardt · ▶ 14:48–14:54

Where do side effects belong?

Overwatch concentrates side effects on one side of an interaction. A functional core similarly leaves database access and email to its surrounding shell.

Compare original passages and timestamps · 2
all major behavioral side effects are localized to that call side
Overwatch Gameplay Architecture and Netcode · ▶ 18:20–18:26
an imperative shell that surrounds the functional core.
Ruby Conf 12 - Boundaries by Gary Bernhardt · ▶ 14:48–14:54

Can you isolate side effects in the language you already use?

Separate a decision from the code that reads a database or sends mail. The boundary depends on how data flows, and can be introduced within an existing language.

Compare original passages and timestamps · 2
no language features are required to program this style
Why Isn't Functional Programming the Norm? – Richard Feldman · ▶ 36:07–36:18
the expired users class makes all the decisions and the sweeper class has all the dependencies.
Ruby Conf 12 - Boundaries by Gary Bernhardt · ▶ 15:28–15:38

What should cross a module boundary?

Values have meanings that callers can inspect independently. A boundary that passes values makes decisions easier to exercise without setting up the surrounding infrastructure.

Compare original passages and timestamps · 2
values are immutable right and values are semantically transparent
The Value of Values with Rich Hickey · ▶ 10:43–10:54
we now have values as boundaries.
Ruby Conf 12 - Boundaries by Gary Bernhardt · ▶ 10:17–10:24

Do separate layers really separate concerns?

Placing code in different layers leaves the underlying concepts free to depend on each other. Trace which changes still require coordinated edits.

Compare original passages and timestamps · 2
it's a mistake to put optionality in aggregate definitions
Maybe Not - Rich Hickey · ▶ 30:36–31:48
don't associate simplicity with partitioning and stratification, right?
"Simple Made Easy" - Rich Hickey (2011) · ▶ 34:50–35:20

Can small components still be tightly coupled?

Changing component size and changing how components communicate are separate decisions. Passing a value can remove a dependency on a synchronous call.

Compare original passages and timestamps · 2
make smaller things
RailsConf 2014 - All the Little Things by Sandi Metz · ▶ 0:54–0:58
we now have values as boundaries.
Ruby Conf 12 - Boundaries by Gary Bernhardt · ▶ 10:17–10:24

Is removing duplication worth another abstraction?

Metz weighs the cost of a wrong abstraction against repeated code. Ousterhout asks how much capability a module hides behind a simple interface.

Compare original passages and timestamps · 2
It is far cheaper to keep duplication than it is to have to mess with the wrong abstraction.
RailsConf 2014 - All the Little Things by Sandi Metz · ▶ 14:52–14:59
very simple interface with a very large amount of functionality underneath it
A Philosophy of Software Design | John Ousterhout | Talks at Google · ▶ 14:24–14:29

What makes an object useful?

Compare refactoring a pricing rule into small objects with the cost of coordinating objects that carry mutable state. A class boundary alone says little about how its users interact.

Compare original passages and timestamps · 2
make smaller things
RailsConf 2014 - All the Little Things by Sandi Metz · ▶ 0:54–0:58
the problem is really not classes per se
Object-Oriented Programming is Bad · ▶ 1:37–1:42

When is it time to stop coding and rethink the problem?

Look for concerns that have become intertwined. Stepping away to reconsider the problem can reveal which of those dependencies really belong together.

Compare original passages and timestamps · 2
start seeing interconnections between things that could be independent
"Simple Made Easy" - Rich Hickey (2011) · ▶ 59:28–59:32
most of the big problems we have with software are problems of misconception
Hammock Driven Development - Rich Hickey · ▶ 4:27–4:36

Try it on your own example

Trace one rule change before deciding where the module boundary belongs.