I’ll be writing a validator for a specific file format (the format itself is unimportant). There’s a large set of documents that specify what every section of the format needs to look like, how the different parts relate and so on. Lots and lots of MUST’s, SHALL’s, SHOULD’s, MAY’s etc.
The architecture I envision is as follows: load the document into memory/separate files on disk, and then run numerous validation “passes” on the document: every pass would check for the adherence to one and only one rule specified in the standard, and if the pass fails, an error message is printed to stdout. Every pass would be a separate class implementing a common interface and an instance of each pass would be created on the stack, run on the document and the Result collected (containing error ID, message, line/column number etc). The Results would then be looped over and messages printed out. A unit test could then be easily created for every pass.
Now, I expect to eventually have hundreds of these “pass” classes. And every one of these would need to be instantiated once, run over the document, and the Result collected.
Do you see where I’m going with this? How do I create all these different instances without having a 500 line function that creates each and every one, line by line? I’d like some sort of loop. I’d also like the new pass classes to somehow be “discovered” when created, so I don’t have to manually add lines that instantiate those new classes.
Thinking about it now, all this seems to remind me of unit testing frameworks…
C++ is a static language that lacks reflection, hence you will have to enumerate your classes one way or another, be it a map of class names to factory functions, an explicit function that creates them all, or cppunit-style “registration” (same as putting them in a static map).
With that said, go with the simplest possible way that’s easiest to change, and does not introduce too much needless work and boilerplate code: creating a list of them in a function.
You are saying you will have hundreds of them “eventually”, not now. By the time you have hundreds of them, your design will have changed completely. If instantiation of all of them is localised in one function, it will make it easier to change your (uniform) design to add validators that depends on the state of previous validators, add arguments to validator constructors, or replace a simple list of validators with some composite structure, like conditional validators (e.g. run X only if Y had certain result, or run Z if X and Y are enabled).
Simple code like that is also easier to throw away if it is no longer fit for the task, as you only tend to get invested in a complicated designs and add kludges to it instead of throwing it away. 🙂
When your codebase matures, you will know exactly what kind of arrangement you need, but for now, do the simplest thing that can possibly work.
PS
Use a file-local macro, if typing
some_ptr<Foo> foo = new Foo()bothers you, macros aren’t that dirty 🙂E. g.