Right now, the application we're looking at consists of a domain module, containing the Person object, and a functionality module, containing everything else.
Let's refactor the application so that it looks like this:
Here we have a highly modulerized application. Normally, you wouldn't have the PersonOpenAction in its own module, but here I'm doing it that way just to prove that it's possible. Since the PersonOpenAction listens for the current PersonNode and then gets the Openable from the PersonNode, and calls "open" on it, which in this case opens the PersonEditorTopComponent, it could be argued that the Node, EditorTopComponent, and Action should all be found in the same module.
On the other hand, separating them in this way means that it's easier to find where each is defined. And one set of engineers could be working on the editor window, while others work on the node hierarchy, in their own workspaces, i.e., in separated modules. Also, and even more usefully, the viewer and editor windows are now found in separate modules, without any dependencies on each other. Both depend on the domain module, while the viewer also depends on the model module, since that's where the node hierarchy is found, and the model module depends on the editor module, since the Openable implementation on the Node references the editor window.
In short, modularity is what you make of it. Further considerations can be read below: