Some say meta-abstractions are meaningless. Little do they realize that this is a wonderful pattern to foster job security among developers and provides opportunities for code jockeys to rise up the ranks.
Why? Abstractions creates indirections which in turn increases source code size. More code can also mean more people are needed to manage it. There will be more opportunities for senior developers to mentor junior developers or new joiners on how to program each level in the indirection. Indirections also act like little picket fences that defines the boundaries of each technical lead who manages code within each level, making it easier to demarcate who-does-what in a project that typically cross-cut abstraction levels.
What is meta-abstraction?
Put simply, meta abstraction is abstraction of abstraction which in itself may be an abstraction. Confused? Perhaps some code will help. The following pseudocode is inspired by Joel Spolski’s example of meta-abstraction:
// example code taken from Joel Spolski's hammer story Hammer tool = HardwareStore.getInstance().getClerk().getHammerFactoryFactoryFactory().getHammerFactoryFactory().getHammerFactory().createHammer(); // you will need to scroll to the right to see the entire line of code.
Still not familiar? How about this example:
// A typical way to get a hold to an instance of a database object in an over-engineered enterprise application. // 1. Find a singleton of some "directory and naming" service interface (does the term ring a bell?) // 2. Lookup a business logic factory class by giving it's registered name (as in a string that's mapped somehow to a factory class instance somewhere). // 3. Use the business logic factory instance to create the business logic class instance and pass it some context information (usually transaction stuff). // 4. The business logic class will have a factory instance that can create the data object that you want, use it. // 5. Finally you get the data object instance that you wanted. Phew! IDataObject obj = LookupServiceSingleton.getInstance().lookup("com.example.project.biz.services.DataObjectBusinessLogicInterface").create(businessContext).getDataObjectFactory().createDataObject(); // you will need to scroll to the right to see the entire line of code.
More familiar? Good. Not familiar? If you’ve ever been a software engineer, consider yourself lucky.
As you can see for yourself, the levels of indirection in the above examples are overwhelmingly deep. This a recurring theme in enterprise applications. Typically within each level of indirection there will be a source file that defines the interface and another source file that contains its implementation. There could be even more than that for cases like supporting multiple implementations, remoting, and other bits and bobs.
Technical Leadership by Levels of Indirection
What I meant by technical leadership are people who manage code. These people usually have titles like technical leads, principal developers or architects. It doesn’t mean having some kind of leading-edge technology.
In some technology companies, technical leaderships are enforced by commit locks on source files. That is, approval by a code manager is needed to commit changes to a source file that he/she manages. In turn the technical lead reviews the changes before allowing it to be part of the main product that will eventually be released. As you can see for yourself, the number of leads is limited by the number of lockable files that he/she can be assigned to review.
What to do when you need to make room for people to get promoted? One possible way is to increase the number of files — junior technical leads will get a set of less important files that are not frequently changed whereas more senior leads will guard “hotter” files that often need modifications. That way the senior lead also has the visibility and authority to split those files and promote more junior leads to take care of them (which in the process also increase that his/her own rank in the pecking order). This way, technical people can remain technical while still getting timely promotions and have a sense of progress within the company.
Imagine that the code base is the territorial area of a monarchy. Territories are awarded to dukes to rule and maintain their loyalty to the monarchy. When the monarchy expands, new territories are awarded to people as reward for their services and that’s how new dukes are appointed. Likewise when a territory becomes too large or too developed for a duke to manage (and by extension did a poor job of ruling the duchy), it can be split among two or more dukes. During those days, there were a lot of unruled land areas and thus it’s easier to apply this method of expansion.
Back to the analogy. If a duchy is a set of source files and the duke is the technical lead that governs that collection of source files, it would be easier to give room for more people to be promoted to dukes by having more source files to manage. Every level of indirection will add its own set of source files and likewise an opportunity for people to get promoted as a technical lead to manage those source files. These dukes govern their territories that are demarcated by commit locks on source files and thus any minion who needs to modify a source file will need to ask the appropriate duke for code review and to unlock the file for committing.
It May Not Work in Your Company
One caveat though: this pattern will only likely to work in a MegaCorp that only have one (or a small number of) flagship products. Like for example a large product-based software company or a large dot-com. It will unlikely work in banks, government offices, or even consulting-based software companies. As expected, you need to be in the engineering unit that takes care of that primary product to feel the effect.
Why? Because the code base will need to be large and complex enough for this kind of commit-locks to work. When the company have multiple products and the source files of each product are not interdependent, higher management may as well assign one person to handle code reviews for the entire product. In effect each product is small enough to become a duchy in itself and the small “surface-area” doesn’t provide much room for developers to become code managers.