I've written some code that models a popular uProcessor from the 80s. I've exposed a small, clean interface to allow client code to drive it by sticking it all in a package, Vanilla, and exporting the appropriate symbols.
I've also written some code that provides some debug functionality that requires some access to the internals of the above - single-stepping, disassembly, breakpoints, register inspection, stuff like that. It needs access to, well, just about anything - its whole purpose is to violate the black box. I decided to put this in a separate package, Debug, which exports its own interface.
I'm trying to figure out what the best way to arrange this might be. I've thought of a couple of solutions:
- 1. Just accept the fact that the debug code needs to violate the boundaries, and use Vanilla::<stuff> to access internals and be done with it. The key point here is that the Debug package is built on top of the Vanilla user package.
2. Put everything in the Debug package; build the Vanilla package with no real functionality, that just exports a restricted interface without debug functions - the key point here being that the Vanilla user package is built on top of Debug.