Decomposing Complex Abstractions
Occasionally a single object has different roles to play in different parts of an application. Threads Module is designed to give users of its objects the simplest interface possible that is suitable to their needs. A “fat” interface can be confusing, and it might include methods that are dangerous or inappropriate in a given context.
The handle-body idiom allows you to offer different interfaces, using separate handle classes, to the same body. Examples in Threads Module include escrows in the Interthread Communication package and threads themselves in the Threading package. Escrows are a thread-communication device that provides an area where one thread can write a result, which other threads can retrieve when ready. The Interthread Communication package provides two separate handle classes with minimal interfaces for the escrow implementation, one for reading and one for writing. Thread object implementations, too, have different handle classes for different contexts. When a thread has a handle to itself, it is of a different handle class than the class that would implement a handle to some other thread. In this way, the interface is tailored to prevent a thread from making a request on itself that requires it to take action before returning — a classic deadlock situation. The request won’t return until the thread takes action, and the thread can’t do anything until the request returns. Decomposing abstractions with handle-body keeps the programmer from accidentally falling into this trap.