Anyone who knows commercial software knows the dreaded self-mutilation that is software licensing. From the developer point of view, having the application turn off parts of itself always seemed a little silly to me. But from the business standpoint, it is not only necessary but it is of the utmost importance to generate revenue and to protect your product.
Additionally, Licensing is one of those things that touches everything in the application at least at some level. As a result it can be terrible if you get it wrong, and worse when you have to make changes to it.
For my second stint on a legacy code team, this was the exact task they assigned to me. Honestly, when we started I didn’t think there was any way I could get it done in the 10 weeks I had to do it in. To help get you some idea of what I was dealing with, I will start by sharing what I found out about our previous system.
Now to start off, you should know, this code base is in C++. Furthermore, it bears the scares of a transition from C into C++ and from functional programming to Object Oriented Programming. In laymen’s terms that means that this code base is older than I am. A lot older.
To be certain this code has seen some years, but the fact that it has stuck around this long is a testament to its impressive library of functionality. After all, no one keeps code that doesn’t do something useful.
Getting back on point though, the previous manner of managing Licenses reflects the code’s age as well, though perhaps less favorably. In previous generations of this product License were sold per feature area, rather than as a bundle. The result was that many areas of the applications, and especially the central UI area, are thoroughly riddled with checks for multiple of these Feature Licenses.
Admittedly, the LicenseManager object does a good job of executing its apparent job description. The trouble is that since the a particular function might be available in multiple Feature Licenses, it can be difficult to tell, from the back-side of the UI, what the program is trying to protect from the user.
For the work I did on this system, the proliferation of multiple License checks was especially troubling. You see, recently my company had reorganized the Licenses which they sell, resulting in some confusion between the old and new Licenses in the code. For simplicity I will call them License A, License B, License C ( which is really a combination of A and B) and License D.
My product manager wanted to allow the users under License B to see data which had been created in the same project by users under License A. Further he wanted them not to be able to modify this data, or to be able to import or export it. Given the current system and confusion, this was a very tall order!
As I have mentioned above, the previous system required the UI area to make a number of checks for several different Feature Licenses before determining whether a particular function was allowed to the user or not. Naturally, this resulted in several complex logical expressions in an attempt to determine whether or not the user was allowed to take a particular action.
For example, in order to determine if a user is allowed to load a given data type from the database, the data manager would first query the License Manager for Feature Licenses X, Y, and Z. Then if the user had X or Y, but not Z they would be allowed to proceed to loading. If they have Feature X they loaded a particular subset of the data, and if they have Feature Y they loaded a different one.
Admittedly this is a simple case, but imagine if this kind of check was made in several different areas of the code. The same check written by different developers at different times for slightly different reasons. The natural differences between coding styles would prevent one from simply searching through the code base for all similar checks.
Furthermore, there is no clear place in the code to determine what a particular Feature License would allow or disallow. This is even further compounded when the new Licenses do not directly match up with a set of Features, and under the hood they are really just re-skinning some of the bigger Feature Licenses.
But that is enough of my belly-aching! After sifting through the old implementation, and some whiteboard work, I was able to develop a better design. Please check back next week, when I’ll explain how I made it easier to make the license checks, easier to tell what a license allows and doesn’t, and how I was able to avoid replacing the entire licensing system!
Part 2 – The Whiteboard Strikes Back!
Part 3 – Return of the Designer