This is the first post in a series I’ll be doing around coding abstraction. Generally speaking, a point of abstraction is really a “component” representing a piece of functionality where the application expects it to behave in a certain way, but the implementation of that behavior will vary, sometimes dramatically. This topic has been covered quite a bit in the software industry, but we’re going to take a look at this concept from more of a business standpoint instead, focusing on how an abstraction might look to our end users, and why they might care about it. Today, we’ll take a look at exactly WHY you might want to create abstractions within an application and how to identify the points that you might want to abstract.
While “abstraction” is really a technical, coding term, it is easier to think of abstraction from an end user’s point of view. For any given application, there are likely to be many users, each with different preferences or needs when using that application. For example, suppose I have a file-syncing application that runs on end-users’ machines that syncs a given directory of files with a cloud storage provider. Each user is definitely going to have a preference on which cloud storage provider they use. Some might use Microsoft’s OneDrive, others might use DropBox, some might use Google Drive, and so on. Our file syncing application is going to have many common components, such as the general user interface, the gathering of file metadata on the user’s machine, and the storage of basic application settings (more on that later). However, when we get to pushing the local files to the target provider, we need a way to swap cloud storage providers, easily, and seamlessly. This is the perfect scenario for an abstraction!
The scenario above is a somewhat trivial extension point to identify. Any time you have functionality that you believe might change from user to user, an abstraction might be in order. Other examples would be integration with common external business systems. Say your application requires data points to be pulled from an Enterprise ERP. You might be using Zoho as your ERP right now, but what if you changed to SAP? Wouldn’t it be nice and easy to just swap out a single component of your application as opposed to completely re-architecting an application that is tightly bound to Zoho? Diving into a more technical realm, another good use case for an abstraction is testability. Creating an abstraction allows us to generate “mock” providers, which are just dummy components meant as stand-ins of actual functionality, catering to unit testing or even early user testing scenarios. Identifying these points early in your application development cycle will allow you to speed up your initial development process by breaking off complicated components to perhaps pass off to another developer or to save until later, while using mock components in the meantime.
Visualizing an abstraction in terms of functionality might be a little easier (from a developer’s perspective) than visualizing the user interface portion of an abstracted component. What if we have a large configuration or “settings” interface within our application that is responsible for saving and retrieving all application level settings? Each provider (Google Drive, Microsoft OneDrive, etc) is going to need their own configuration interface to show their provider-specific settings in a friendly way that is familiar to the user. You will undoubtedly need to create an abstraction point from within the master settings interface to “plug in” custom user interface screens to house a provider-specific UI for either selected providers or all providers (depending on your application’s needs). Later in this series, we will go into more technical detail on how one might accomplish these tasks. The big thing to remember in regards to both the user interface component and the functionality component of an abstraction is to be mindful of your abstraction points early in the development cycle. It will make things much easier as your application increases in complexity and more providers get implemented if you identify them early.
Abstractions are a great way to keep code clean and organized, but it’s also a way to leave your application open to better integrations later on, with minimal effort. In part 2 of this series, we’ll talk about creating a contact between the main application and your abstractions, and in part 3, we’ll talk about deciding using a given abstraction “provider” at runtime using Dependency Injection!