Keep Platform-Dependent Code at Minimum

Keep the amount of platform-specific code at a possible minimum.

Sounding very simple, it's one of the hardest to follow, and the most often ignored piece of advice. By its nature, it goes hand-in-hand with the common sense in package design – keep the public API of a package as narrow as possible.

The best way to keep things simple is to have no cross-platform code. But often that's not possible, and some code has to be made platform-dependent. In such case, you have to keep the amount of such code as small as possible.

Having learned the tools for conditional compilation, you know that it's possible to conditionally include code in the final binary depending on the constraints specified at the build time. This leads to a question about what code to pull into files that are conditionally included? Or, in a more general form, what parts of the code are better to be made cross-platform?

Looking at the problem from a general software design perspective, our building blocks in code are:

  • types
  • methods
  • and helper functions.

Therefore, when working in a cross-platform context, these are what can have varying implementations between platforms supported by a project. However, the guideline says that it's good to keep the code at a minimum. This helps in deriving guiding principles for writing cross-platform code.

In general, when working with varying implementations for the same functionality for several platforms, bear in mind the following suggestions:

  • in the worst case, types are implemented differently for each platform, but obey the same interface/contract
  • a slightly better option is to allow methods vary between platforms
  • the best option is to pull platform specifics into helper functions.

The insightful reader might have already noticed that these guidelines do support and reflect two of the basic principles introduced at the beginning of this unit, namely:

  • the business logic must be platform-agnostic
  • and keep the amount of cross-platform code at a possible minimum.

The first of the two is supported by the fact that by default you aim to pull platform-specifics in to helpers. This guarantees that methods and types do not depend on a platform, thus less business logic is leaking to the platform.

The second is supported by the fact that aiming for having no details leaked to type and method levels, a lower amount of platform-dependent code is automatically guaranteed.

One warning should be made though. The guideline does not prevent you from introducing platform-specific helper types when it helps to improve the logic of software and its design. What should be avoided, however, is platform-specific public API of a package. If a public method or type depends on a platform, then decouple the public part and use cross-platform private implementations that are not exposed to the user. This drastically improves both, the user and developer experience. Being free to change the implementation without the risk of breaking user's applications is vital for productive and efficient maintenance of any software, but even more so in the cross-platform world.