True Story Follows
Sometimes, I find myself in a situation where I have an idea for a piece of architecture, and the idea is that the system is extensible and any developer should be able to come along and add to it by creating a class the implements a few methods, and the rest of the system will magically take care of everything. Basically, in order to maintain the system, an onboarder should not have to invest time in understanding the entire system in order to make changes.
The particular case I’m talking about is one in which an abstract class is created, and that class should be able to be extended any number of times. Imagine the typical object oriented example of extending animals; if a developer wants to integrate a new animal into the environment, it would be luxurious to subclass an abstract class, implement the required methods, and that’s it. No need to understand the rest of the system. No need to go and created references to your new concrete class elsewhere.
So here’s an example of what I’m talking about:
Notice how in this simple example, a developer must create a new subclass AND add it to the list of existing animal classes. I want to get rid of that second step. In a real world example, the 2nd step would likely be a bit more complex with more “wiring” involved.
One thing that’s magical about Flask is how you can register URL’s with just a decorator. Add the decorator to a function and BAM! There’s a new URL:
I wanted to implement the same sort of concept. So you can create a class decorator to decorate any concrete class:
And we can use in our example like so:
The remaining problem is that the registration decorator is only called once the class is imported. So we still haven’t solved our problem yet because classes aren’t auto registered. This can be resolved in our __init__.py files which will handle imports. I found one of several solutions on StackOverflow to automatically import all classes in a module. So we can do something like:
Now for any new developers that come along, they can simply do something like:
The new class will now be part of the rest of the ecosystem without any additional work. This can allow for systems that delegate and decompose responsibilities to developers that don’t need to waste time understanding the rest of the system.