For example, I’m working on a system that uses extraction rules to pull data from web pages. I have a simple browser that caches pages when you intend to use them for extraction. The Extractor is passed a reference the cached page. Where does this message come from? The PageCacher originally. But how does the Extractor end up with it?
The Extractor is told by the AgentBuilder. The AgentBuilder is a module that learns rules for getting info off of pages. It also is able to apply those rules using the Extractor. When AgentBuilder is asked to extract data, you can tell it which page you want to use. If you don’t pick out any page in particular, it assumes you’re interested in the page that is currently being displayed in the browser. So, AgentBuilder asks the browser (called WebTracker) to cache the current page. WebTracker accomplishes this by asking the BrowserPanel. The BrowserPanel can’t be bothered by such trivial requests so it asks its BrowserPanelController for help. (I believe Kodak owns this idea.) The controller can’t cache pages. So it asks the PageCacher to do the caching. The PageCacher now returns the path to the BrowserPanelController which returns it to the BrowserPanel which returns it to the WebTracker which passes it over a socket to the AgentBuilder which gives the info to the Extractor.
Not bad. If, on the other hand, AgentBuilder had been explicitly told where to find the cache, that message would have come from the WebApplicationManager which would be handling a request made by the InterpretationManager. The IM is the hub for all of the higher brain functions of our system including speech and reasoning. (I pronounce it “I am”, but that’s another story.) The InterpretationManager would have originally gotten the cache reference from the WebTracker through the WebApplicationManager in the ‘page’ field of a Selection object.
Selections are created when a person highlights part of a web page. After making your selection, when you release the mouse button, the SelectionTracker finds out from the BrowserPanel. It, the SelectionTracker, tells the SelectionMapper to figure out what part of in the underlying html your selection corresponds to. The SelectionMapper creates the Selection object which the Selection object. But how did the SelectionMapper find out about the ‘page’ in the first place?
Well, that came from the SelectionTracker which it got from a PageLoadEvent passed from the BrowserPanel. When the BrowserPanel created the PageLoadEvent, the PageLoadEvent asked the BrowserPanel for all kind of info including the cache reference for which, as we said previously, the BrowserPanel asks the BrowserPanelController asks the PageCacher.
Conclusion
It may be spaghetti, but there’s no chance I’d be able to swallow it if it all were rolled up into one big ball. With OOP, we’re able to cut a big ball of code into bite sized chunks. It only turns to spaghetti when our meal involves many different objects. If only we could cut the part we want from each of the objects, line them up in nice little row, and serve them with a side of sushi. Then we’d never be forced to eat spaghetti again.
Commentary