Hacker News new | ask | show | jobs
by tel 4425 days ago
This is nice and drives home something particularly important to me. In Parnas' quote he suggests modularizing such that "things that change together stay together". I think this is highly sensible. Another way of saying it is that your APIs should be fixed.

But often this gets conflated in OO because objects are the hearth of modularization (via encapsulation) along with state and interaction and any number of other things.

---

As a comparison point, you might examine ML modules. They look a bit like this

    module counter(X)
      count : X -> Int
      incr  : X -> X
and they specify nothing more than the fact that some unknown type X satisfies the interface `(count, incr)`. We can then create a concrete implementation of such a counter

    incCounter : counter
    incCounter = structure(Int)
      count n = n
      incr n = n + 1
The incCounter internally uses `Int` to represent `X`, but externally it's completely impossible to tell. This means that modules define exactly two things: encapsulation and interface.

---

So why does this fall down in OO? Because objects lend themselves to being thought of as entities which move through time and space in a stateful fashion. This means you're also likely to encapsulate differences of entity without regard for how they might change together or apart.

Returning to Parnas' quote: it's a bad idea to decompose into modules based on a flowchart. Flowcharts allow you to emphasize the entities of your system, but they are not demonstrating the boundaries of change.

So you can probably get better OO design by being clear when you're using objects as entities (and thus perhaps you do not need encapsulation at all!) and when you're using them as modules. Once this distinction is made it can be clear when objects will derive from flowcharts and when objects will derive from selections of choices made by people.