Ronald is a Dutch software analyst who principally works with C++. He is currently the chief software architect for Optel Vision in Canada and can be reached at www.landheer-cieslak.com.
One of the appplications I work on was designed according to a Latino-Communist design pattern such as this: If any class A knows any other class B, it not only knows B, but also all its family, friends, and acquaintances and not only does it know them, but it knows their family, friends and acquaintances, and not only that, but it knows their internals and has a right -- nay, an obligation -- to play with those internals.
One of the problems with such an "approach" is that if there's a bug, you don't really know what's going on or what class is responsible: If you have four classes, Everybody, Somebody, Anybody, and Nobody, if Somebody has a bug, it could be Anybody 's fault but Nobody really knows, while Everybody shares responsibility.
Another problem is that when you have to add something to such an application, and you don't want to get your hands too dirty and you want to be able to unit-test your addition, you really have no choice but trying to hide a chopstick in a bowl of spaghetti. This is exactly the scenario I found myself in when I came up with the idea of the specific type of adapter I discuss here.
Your mission, should you choose to accept it, is to take the core functionality of the application descibed above, encapsulate it in a single class we'll call Task, and construct an instance of that class. For this, you need to know three types, each of which is currently a template parameter of another class that you will partially replace, and which is known by the entire planet, where the planet in question is the application. Each of these types is different but related to each other type. You cannot simply take the definition of one particular type, rip it out of the application, and put it in your test case -- but you do have to write a test case.
For your class Task to work, you need a batch of data to work on, which you will visit with a visitor .
From the existing application, you can determine that the different types that can provide batches of data all have a function that can take a visitor as parameter, but those functions have different names, though they have similar signatures (most of them return void and take a reference to the visitor type as parameter, but the visitor type changes with each data batch type).
Visitors in the application all share the same signature and are derived from a common base class. That base class, however, is highly coupled with the entire rest of the application, which makes extracting it to use it in your test cases next to impossible. Also, you cannot expect the caller to provide you with an instance of the visitor, but it can provide you with its type.
You do not want the entire implementation of your Task class to be exposed, which means that though the code needs to be generic, you cannot exclusively rely on compile-time binding of your client's types in your implementation: Such approaches have already led to dramatic losses of productivity in the team that developed the application in the first place, and you don't want to add to that problem while solving another one.