What we've done here is decoupled the act of reading the data from the act of handling it. We are free to apply multithreading to either of these, of course, but we don't have to. But the two tasks often have different requirements, and so it may be useful to be able to handle them in different ways. As we'll see below, there are times when a straightforward use of multitasking is actually worse than doing things in a completely serial way. This structure is where we get our title from.
Framework Let's get into the details of the code.
While each implementation can use whatever trickery it wants to handle the many socket connections, there is some functionality that they have in common. Each one maintains an internal list of data chunks that have already been read. After doing its trickery, the code that actually does the reading places the newly read data on this queue. All of the code that implements this common functionality is placed in a base class, simply called Multiplexor, from which the two implementations listed above are derived. After all, you might not want to use a queue to store newly read chunks.