1*61c4878aSAndroid Build Coastguard Worker.. _docs-facades: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker================== 4*61c4878aSAndroid Build Coastguard WorkerFacades & backends 5*61c4878aSAndroid Build Coastguard Worker================== 6*61c4878aSAndroid Build Coastguard WorkerThis page explains what "facades" and "backends" mean in the context of Pigweed 7*61c4878aSAndroid Build Coastguard Workerand provides guidelines on when to use them. 8*61c4878aSAndroid Build Coastguard Worker 9*61c4878aSAndroid Build Coastguard Worker.. _docs-facades-definition: 10*61c4878aSAndroid Build Coastguard Worker 11*61c4878aSAndroid Build Coastguard Worker------------------------------ 12*61c4878aSAndroid Build Coastguard WorkerWhat are facades and backends? 13*61c4878aSAndroid Build Coastguard Worker------------------------------ 14*61c4878aSAndroid Build Coastguard Worker.. _top-down approach: https://en.wikipedia.org/wiki/Bottom%E2%80%93up_and_top%E2%80%93down_design 15*61c4878aSAndroid Build Coastguard Worker 16*61c4878aSAndroid Build Coastguard WorkerLet's take a `top-down approach`_, starting with high-level definitions. 17*61c4878aSAndroid Build Coastguard WorkerIn the context of a Pigweed module: 18*61c4878aSAndroid Build Coastguard Worker 19*61c4878aSAndroid Build Coastguard Worker* A facade is an API contract of a module that must be satisfied at compile-time, 20*61c4878aSAndroid Build Coastguard Worker i.e. a swappable dependency that changes the implementation of an API at 21*61c4878aSAndroid Build Coastguard Worker compile-time. 22*61c4878aSAndroid Build Coastguard Worker* A backend is an implementation of a facade's contract. 23*61c4878aSAndroid Build Coastguard Worker 24*61c4878aSAndroid Build Coastguard WorkerUsually, the facade and the backend are in different modules. One module 25*61c4878aSAndroid Build Coastguard Workerexposes the facade contract, and another module is the backend that implements 26*61c4878aSAndroid Build Coastguard Workerthe facade contract. The naming pattern that Pigweed follows is 27*61c4878aSAndroid Build Coastguard Worker``{facade_name}_{backend_name}``. 28*61c4878aSAndroid Build Coastguard Worker 29*61c4878aSAndroid Build Coastguard WorkerFacades, by design, don't need to be configured until they're actually used. 30*61c4878aSAndroid Build Coastguard WorkerThis makes it significantly easier to bring up features piece-by-piece. 31*61c4878aSAndroid Build Coastguard Worker 32*61c4878aSAndroid Build Coastguard WorkerExample: pw_log and pw_log_string 33*61c4878aSAndroid Build Coastguard Worker================================= 34*61c4878aSAndroid Build Coastguard WorkerHere's a step-by-step walkthrough of how a real backend module implements 35*61c4878aSAndroid Build Coastguard Workeranother module's facade. 36*61c4878aSAndroid Build Coastguard Worker 37*61c4878aSAndroid Build Coastguard Worker.. _//pw_log/public/pw_log/log.h: https://cs.opensource.google/pigweed/pigweed/+/main:pw_log/public/pw_log/log.h 38*61c4878aSAndroid Build Coastguard Worker.. _//pw_log_string/public_overrides/pw_log_backend/log_backend.h: https://cs.opensource.google/pigweed/pigweed/+/main:pw_log_string/public_overrides/pw_log_backend/log_backend.h 39*61c4878aSAndroid Build Coastguard Worker 40*61c4878aSAndroid Build Coastguard Worker* :ref:`module-pw_log` is a module that exposes a facade. The macros listed in 41*61c4878aSAndroid Build Coastguard Worker :ref:`module-pw_log-macros` represent the API of the module. 42*61c4878aSAndroid Build Coastguard Worker* The ``#include "pw_log/log_backend.h"`` line in `//pw_log/public/pw_log/log.h`_ 43*61c4878aSAndroid Build Coastguard Worker represents the facade contract of ``pw_log``. 44*61c4878aSAndroid Build Coastguard Worker* :ref:`module-pw_log_string` is a backend module, It implements the 45*61c4878aSAndroid Build Coastguard Worker ``pw_log/log_backend.h`` facade contract in 46*61c4878aSAndroid Build Coastguard Worker `//pw_log_string/public_overrides/pw_log_backend/log_backend.h`_. 47*61c4878aSAndroid Build Coastguard Worker* In the build system there is a variable of some sort that specifies the 48*61c4878aSAndroid Build Coastguard Worker backend. In Bazel there's a `label 49*61c4878aSAndroid Build Coastguard Worker flag <https://bazel.build/extending/config#label-typed-build-settings>`_ 50*61c4878aSAndroid Build Coastguard Worker at ``//pw_log:backend``. In CMake there's a ``pw_log_BACKEND`` variable set 51*61c4878aSAndroid Build Coastguard Worker to ``pw_log_string``. In GN there's a ``pw_log_BACKEND`` variable set to 52*61c4878aSAndroid Build Coastguard Worker ``dir_pw_log_string``. 53*61c4878aSAndroid Build Coastguard Worker 54*61c4878aSAndroid Build Coastguard Worker.. note:: 55*61c4878aSAndroid Build Coastguard Worker 56*61c4878aSAndroid Build Coastguard Worker There are a few more steps needed to get ``pw_log_string`` hooked up as the 57*61c4878aSAndroid Build Coastguard Worker backend for ``pw_log`` but they aren't essential for the current discussion. 58*61c4878aSAndroid Build Coastguard Worker See :ref:`module-pw_log_string-get-started-gn` for the details. 59*61c4878aSAndroid Build Coastguard Worker 60*61c4878aSAndroid Build Coastguard WorkerExample: Swappable OS libraries 61*61c4878aSAndroid Build Coastguard Worker=============================== 62*61c4878aSAndroid Build Coastguard WorkerThe facade and backend system is similar to swappable OS libraries: you can 63*61c4878aSAndroid Build Coastguard Workerwrite code against ``libc`` (for example) and it will work so long as you have 64*61c4878aSAndroid Build Coastguard Workeran object to link against that has the symbols you're depending on. You can 65*61c4878aSAndroid Build Coastguard Workerswap in different versions of ``libc`` and your code doesn't need to know about 66*61c4878aSAndroid Build Coastguard Workerit. 67*61c4878aSAndroid Build Coastguard Worker 68*61c4878aSAndroid Build Coastguard WorkerA similar example from Windows is ``d3d9.dll``. Developers often swap this DLL 69*61c4878aSAndroid Build Coastguard Workerwith a different library like ReShade to customize shading behavior. 70*61c4878aSAndroid Build Coastguard Worker 71*61c4878aSAndroid Build Coastguard WorkerCan a module have multiple facades? 72*61c4878aSAndroid Build Coastguard Worker=================================== 73*61c4878aSAndroid Build Coastguard WorkerYes. The module-to-facade relationship is one-to-many. A module can expose 74*61c4878aSAndroid Build Coastguard Worker0, 1, or many facades. There can be (and usually are) multiple backend modules 75*61c4878aSAndroid Build Coastguard Workerimplementing the same facade. 76*61c4878aSAndroid Build Coastguard Worker 77*61c4878aSAndroid Build Coastguard WorkerIs the module facade the same thing as its API? 78*61c4878aSAndroid Build Coastguard Worker=============================================== 79*61c4878aSAndroid Build Coastguard WorkerNo. It's best to think of them as different concepts. The API is the interface 80*61c4878aSAndroid Build Coastguard Workerthat downstream projects interact with. There's always a one-to-one relationship 81*61c4878aSAndroid Build Coastguard Workerbetween a module and its API. A facade represents the build system "glue" that 82*61c4878aSAndroid Build Coastguard Workerbinds a backend to an API. 83*61c4878aSAndroid Build Coastguard Worker 84*61c4878aSAndroid Build Coastguard WorkerThis is a common point of confusion because there are a few modules that 85*61c4878aSAndroid Build Coastguard Workerblur this distinction. Historically, the facade comprised the API as well as 86*61c4878aSAndroid Build Coastguard Workerthe build system concept. We're moving away from this perspective. 87*61c4878aSAndroid Build Coastguard Worker 88*61c4878aSAndroid Build Coastguard WorkerAre Pigweed facades the same as the GoF facade design pattern? 89*61c4878aSAndroid Build Coastguard Worker============================================================== 90*61c4878aSAndroid Build Coastguard Worker.. _facade pattern: https://en.wikipedia.org/wiki/Facade_pattern 91*61c4878aSAndroid Build Coastguard Worker 92*61c4878aSAndroid Build Coastguard WorkerThere are some loose similarities but it's best to think of them as different 93*61c4878aSAndroid Build Coastguard Workerthings. The goal of the Gang of Four `facade pattern`_ is to compress some 94*61c4878aSAndroid Build Coastguard Workerugly, complex API behind a much smaller API that is more aligned with your 95*61c4878aSAndroid Build Coastguard Workernarrow business needs. The motivation behind some Pigweed facades is loosely 96*61c4878aSAndroid Build Coastguard Workerthe same: we don't want a device HAL to leak out into your include paths when 97*61c4878aSAndroid Build Coastguard Workera facade is implemented. 98*61c4878aSAndroid Build Coastguard Worker 99*61c4878aSAndroid Build Coastguard Worker------------------------------ 100*61c4878aSAndroid Build Coastguard WorkerWhy does Pigweed have facades? 101*61c4878aSAndroid Build Coastguard Worker------------------------------ 102*61c4878aSAndroid Build Coastguard WorkerPigweed's facades are basically a pattern that builds off the ideas of 103*61c4878aSAndroid Build Coastguard Worker`link-time substitution <https://bramtertoolen.medium.com/91ffd4ef8687>`_. 104*61c4878aSAndroid Build Coastguard WorkerLink-time substitution only allows you to replace one source file with another, 105*61c4878aSAndroid Build Coastguard Workerwhereas facades enable substituting program elements defined in *header files*. 106*61c4878aSAndroid Build Coastguard Worker 107*61c4878aSAndroid Build Coastguard WorkerPigweed facades enable implementation flexibility with zero performance cost. 108*61c4878aSAndroid Build Coastguard WorkerThere are two ways to look at this. Continuing with the ``pw_log`` example: 109*61c4878aSAndroid Build Coastguard Worker 110*61c4878aSAndroid Build Coastguard Worker* Organizations can reuse more code across projects by adopting the ``pw_log`` 111*61c4878aSAndroid Build Coastguard Worker API as their logging layer. Facades enable each project to customize how 112*61c4878aSAndroid Build Coastguard Worker its logs are handled. 113*61c4878aSAndroid Build Coastguard Worker* For projects that want to integrate with ``pw_log`` but cannot adopt its 114*61c4878aSAndroid Build Coastguard Worker API, facades can wrap the existing API which enables Pigweed to be compatible 115*61c4878aSAndroid Build Coastguard Worker with the existing system. 116*61c4878aSAndroid Build Coastguard Worker 117*61c4878aSAndroid Build Coastguard WorkerTwo of the major aspects of "implementation flexibility" enabled by facades are: 118*61c4878aSAndroid Build Coastguard Worker 119*61c4878aSAndroid Build Coastguard Worker* Portability. For example, ``pw_sync`` needs platform-specific 120*61c4878aSAndroid Build Coastguard Worker implementations to work correctly. 121*61c4878aSAndroid Build Coastguard Worker* Customized behavior. For example, you can make a fully portable ``pw_log`` 122*61c4878aSAndroid Build Coastguard Worker implementation, but what makes it special is the ability to tune it to your 123*61c4878aSAndroid Build Coastguard Worker needs. 124*61c4878aSAndroid Build Coastguard Worker 125*61c4878aSAndroid Build Coastguard WorkerWhy compile-time? 126*61c4878aSAndroid Build Coastguard Worker================= 127*61c4878aSAndroid Build Coastguard WorkerResolving facades and backends at compile-time enables: 128*61c4878aSAndroid Build Coastguard Worker 129*61c4878aSAndroid Build Coastguard Worker* Call-site control from backends. 130*61c4878aSAndroid Build Coastguard Worker* Static allocation of backend-provided types. 131*61c4878aSAndroid Build Coastguard Worker* Explicit backend includes so it’s visually obvious you’re poking through 132*61c4878aSAndroid Build Coastguard Worker abstraction. 133*61c4878aSAndroid Build Coastguard Worker 134*61c4878aSAndroid Build Coastguard Worker-------------------------------- 135*61c4878aSAndroid Build Coastguard WorkerWhen to use facades and backends 136*61c4878aSAndroid Build Coastguard Worker-------------------------------- 137*61c4878aSAndroid Build Coastguard WorkerIf you're trying to use a Pigweed module, and that module exposes a facade, 138*61c4878aSAndroid Build Coastguard Workerthen you've got no choice: you've got to hook up a backend to fulfill that 139*61c4878aSAndroid Build Coastguard Workerfacade contract or else the module won't work. 140*61c4878aSAndroid Build Coastguard Worker 141*61c4878aSAndroid Build Coastguard WorkerWhen to roll your own facades and backends 142*61c4878aSAndroid Build Coastguard Worker========================================== 143*61c4878aSAndroid Build Coastguard Worker* You need a global function or macro. 144*61c4878aSAndroid Build Coastguard Worker* You absolutely must avoid the overhead of virtual functions. 145*61c4878aSAndroid Build Coastguard Worker 146*61c4878aSAndroid Build Coastguard WorkerWhen to NOT roll your own facades and backends 147*61c4878aSAndroid Build Coastguard Worker============================================== 148*61c4878aSAndroid Build Coastguard Worker* If you can afford the runtime cost of dependency injection, use that. 149*61c4878aSAndroid Build Coastguard Worker In all other cases where link-time subsitution will work, use that. 150*61c4878aSAndroid Build Coastguard Worker Only if the API contract requires a backend to provide a header (which 151*61c4878aSAndroid Build Coastguard Worker link-time substitution doesn't let you do) should you reach for a facde. 152*61c4878aSAndroid Build Coastguard Worker* You're trying to use globals to avoid dependency injection. Use 153*61c4878aSAndroid Build Coastguard Worker the dependency injection! It makes testing much easier. 154*61c4878aSAndroid Build Coastguard Worker* Your needs can be served by a standard mechanism like virtual interfaces. 155*61c4878aSAndroid Build Coastguard Worker Use the standard mechanism. 156