Sometimes though, new requirements arise that break the abstraction. In our example, let’s imagine I wanted to expand my application to handle circles. Now, because the formula for calculating the area of a circle is different than a square, my getArea() function would now have to take a parameter, isCircle, and then have conditional logic based on the value of that parameter. Our abstraction would be broken. In this case, the fix would be as simple as defining a more generic Shape base class. Shape would have more specific Square and Circle subclasses, both of which would implement the getArea() function in their own way.
At pMD, we’ve offered secure messaging functionality to our customers for about two years. In its earliest days, the product was envisioned as a platform where a provider utilizing pMD’s charge capture software could send an encrypted message to another charge capture user. It has evolved today to be a completely standalone, realtime, mobile secure messaging solution. This is really exciting for us as a company, but of course, this incredible growth has put strains on the original abstractions we put in place when we built the software. Specifically, our concept of what constitutes a “contact” in pMD has evolved from being a charge capture user to anyone who has a smartphone and wants to communicate securely.
Sandi Metz has an interesting blog post called “The Wrong Abstraction.” The title is a bit misleading, because what it’s really about is what to do when you realize that your current abstraction has been stretched past its breaking point. At pMD, we arrived at this realization about our secure messaging contact list recently. Our original concept of a contact was no longer capable of supporting the growing list of requirements we were asking of it. So, we decided to spend this week doing a deep refactor of our implementation.
Our goals in this refactor process were to build an abstraction that, first and foremost, is able to meet the demands we have for new features today, e.g. the ability to add anyone to your contact list. We also wanted it to be as future proof as possible, in order to be able to meet requirements that we think we’ll need to accommodate soon, e.g. the ability for doctors to securely message with their patients. It’s definitely tough to find the right balance, and to not “over engineer” our abstraction, but I think that after several days of whiteboarding and discussions, we’ve arrived at something that we’re all really happy with.
We’ll be spending the next several days implementing and testing our new design. We’re confident that we’ve chosen an abstraction the elegantly encapsulates the functionality that our growing secure messaging product asks of it. We’re excited about how far it will take us!