The Difference Between Samples and Prototypes
Recently my work has found me focusing on developing SDKs for Android. I’ve found this work is distinctly different from building user-facing client applications in numerous ways, but one of the most notable for me has been the shift in expectations for documentation and education of others on my thought processes. In the past, I’d always been able to rely on my collogues having a working knowledge of the implementation details that go along with the code I was working on - this meant that we could use inline comments, variable names, and other common “best practice” systems to communicate efficiently and concretely about the decisions being made during the implementation process. I recognize now that this had become something of a crutch for me, I had become lax in documenting according to the principles that I’d been taught. My shift into SDK development reminded me of the importance of documenting my work in a way that consumers of my work could easily follow using plain English. No longer could I rely on convention or assume that my peers would just “get it” from reading my code and following a stack of method calls - I had to provide readable, understandable artifacts that balanced a delivery of technical detail with reader engagement. To accomplish this task I employed fairly standard methods: JavaDoc-style code comments, descriptive class and interface names, layers of abstraction where appropriate, and convenience methods (especially using Kotlin’s extension functions features) to support common use-cases.
In addition to the writing of documentation targeted at downstream consumers of my SDKs, I took the initiative to create a sample application to ship alongside the SDK artifact. This sample application serves many purposes, and I found its development to be nearly essential to the development of the SDK itself. The purposes that the sample application serves include:
- Aid in the development of the SDK itself by providing a test bed for new features. As I developed new SDK features I would avoid closing out the development cycle until the feature was implemented in the sample, thus ensuring that I always had proof of the functionality of my work and a way to demonstrate to other members of my team what the SDK was capable of at any given point in the development process.
- Expose awkward endpoints. As I would implement features in the sample application I would often uncover areas of the SDK that didn’t have the level of support I would have desired. Because I came to these realizations about any given area of the SDK before releasing new versions, I saved myself from having to patch the code and go through additional release cycles. This resulted in consumers of the SDK spending less time updating their implementation.
- Demonstrability: Developers, myself included, love to show off our work. We want to be able to point at things and say “I built that, and I’m proud of what it can do”. When I was first working in the industry this was easy: I was building a consumer-facing product, so new features were intended to be public and promotion of those features was a part of daily life. As I’ve shifted to SDK development I found myself missing the feeling of watching a user be delighted by the results of my work, I missed the satisfaction that comes from seeing that user’s eyes light up and the subtle smile that would appear on their face as they realized that one of their favorite products was suddenly capable of something that it wasn’t before. Showing my sample to my co-workers and managers approximated this feeling for me; I found it motivating and rewarding.
The benefits of sample-app development cannot be understated - I’d encourage others embarking on SDK development journeys to strongly consider creating samples in tandem with their core development work. To further iterate upon the value that I extracted from developing a sample application, I recently took the time to develop a prototype consumer application that consumes my SDK. What makes this prototype different from the companion sample? The key difference for me was in when each was developed: the sample was done alongside the main artifact, while the prototype came after the primary artifact and wasn’t intended to directly provide feedback in return to the main SDK. I used the process of developing the prototype to take a step back from my intimate understanding of the details contained in my SDK and attempt to approximate the experience that a new end-user would have if they were to turn to my work to solve their problems. In taking up this mindset I was able to further expose problems with the underlying code and smooth out the adoption experience. I found great value in being able to contribute to the prototype application, and would encourage others working on SDKs to take advantage of opportunities to do similar explorations if given the chance.
As I reflect on the development of both the sample and the prototype I found that there were distinct differences in the value that each provided; below I identify a selection of these differences.
|The purpose of a prototype is to show extended capabilities of your SDK.
|Samples should remain as simple as possible, isolating individual features and showing the simplest possible methods for implementing these features into downstream applications.
|A prototype is an opportunity to show how your SDK can integrate with platform features, common libraries, and generally emulate how well your work functions as a citizen of the platforms on which it is deployed.
|The sample application should only show the base-case integration, without assuming that consumers will be using any other tools or libraries. No matter how common these additional tools may be, your sample application should remain pure to the platform-provided solutions. If you find that you’re experiencing issues creating a functional sample without third-party dependencies you should consider what you can do to support others in their integrations.
|Prototypes should seek to excite their audience. Use them as a chance to “sell” your work, demonstrate advanced uses of your SDK’s feature set, and provide a compelling argument for why others should adopt your solution.
|Samples provided alongside your SDK should bore the user - they’re really not meant to be consumed in isolation, rather they should be viewed side-by-side with their source code, providing a jumping-off point for implementers. By the time that someone is looking at your sample you’ve already gotten them interested in using your tool, take the sample as an opportunity to show how simple it is for the reader to get started with your product.
|Prototypes, as alluded to above, can be consumed as a complete product, separate from their source code. They may be toys at the end of the day, but their usefulness is elevated when you think of them as fully-featured and complete experiences, supported by what your SDK provides.
|Sample apps, unlike prototypes, don’t need to “make sense” in isolation. One can assume that any consumer of a sample app will be also interested in how the sample was created, the experience these individuals are seeking is one that doesn’t rely on something being impressive end-to-end.
|Consumers of a prototype typically get their first look at it from a “traditional” UX - there is usually some kind of UI, some typical path that they can be expected to follow through the prototype. This is partially a consequence of how these prototypes are distributed: they come built and runnable.
|Viewers of sample apps can be directed to take a more hands-on approach to consuming the sample: if you provide the sample as a compile-it-yourself product, you necessitate that consumers get their hands in the source first. These consumers are then directed away from focusing on the final UX, reducing the time that you need to spend polishing a sample’s presentation layers. Some consumers of sample apps may never build the full app, preferring instead to simply take the source code at face value.
SDK developers face unique challenges, especially when considering how best to support their customers and provide a first-class experience to developers relying on their work. My recent transition into roles where I am focused on solving problems by providing libraries and SDKs has led me to believe that through the careful development of both sample and prototype applications one can optimize their end product, prove the value of their work, and support clients by understanding the experience that they are providing. By understanding the different purposes that samples and prototypes serve, SDK developers can ensure that they are taking each as an opportunity to best engage with their target audiences.