Skip to content

Backend agnostic design

Sven Nilsen edited this page Sep 21, 2015 · 2 revisions

Backend agnostic design uses Rust's type system to offer multiple solutions to a narrow problem in a wide range of use cases.

  • Generic libraries in an ecosystem uses a common library with an abstraction designed for generic code
  • Backends depend on the common library to integrate with the rest of the ecosystem

Backend agnostic design leads to extra nodes in the dependency graphs, but scales better with size of a project.

Naming

The name of a backend ends with _ and the kind of abstraction:

  • graphics => gfx_graphics
  • window => glutin_window

Motivation

  • More choices when shipping a product
  • Better for sharing source code
  • Quickly fix problems by swapping a backend and see if that works
  • Easier to compare, debug and benchmark different design
  • Composable with both cross and native platform programming

Understanding the problem

The time of a programmer is shared between the projects that the programmer maintains. In some cases, code is written to fix a particular problem. Over time, the tendency is that people want to use the software they have on new platforms or for slightly different use cases. To save time, the amount of effort spent into a project is often made reusable so the maintenance cost is shared between making existing code working, and addressing new needs.

The problem is to reduce the cost of maintenance

Writing new code is not the problem. Brain cycles are expensive, so making small adjustments or design improvements costs relatively much compared to the benefit they bring. In general this leads to new code written all the time, while some people are stuck maintaining existing code that can't be deprecated. This leads to a waste of brain cycles in the long term.

The scope of the problem is not specifically tied to the number of dependencies or solving a particular use case. It is the users' desire to keep the overall system familiar and understandable when they move from one platform to the next. This is in line with the programmer's motivation of an ideal organization of libraries, where they can swap out one part with another to get things working on a new platform.

  • Platform specific dependencies should be replaceable
  • The exposed API at application level should make platform specific features accessible

Cross platform design is a similar, but not solving the problem. From a maintenance perspective, a cross platform design requires changes to the core library which the entire ecosystem depends on. When there is a new platform, a new version is often required, and then the ecosystem must be updated.

Backend agnostic design is a distributed version of cross platform design. With a modern programming language like Rust one can take advantage of generics to expose backend specific features.

Limitations

Backend agnostic design is not a tool for solving every problem imaginable.

  • The abstractions are intended for generic libraries, and users should not have to deal with them more than necessary
  • It is very hard to design backend agnostic interfaces that captures all the requirements
  • There are often tradeoffs between performance and usability
  • It can make it harder to understand the overall architecture
Clone this wiki locally