Protocol-based service abstraction

Enables future providers (AI, network, etc.) to be swapped behind a stable protocol boundary.

Problem

Feature implementations tightly coupled to a single concrete service become difficult to test, extend, or replace. When a new backend (e.g., an AI API) needs to be swapped in, every call site changes.

Solution

Define a protocol (e.g., PredictionProvider) that captures the service contract. Ship one concrete implementation (AlgorithmicProvider) at launch. All consumers depend on the protocol, not the concrete type. Swapping providers requires only a new conforming type — no call site changes.

Usage

Apply when a feature has more than one plausible implementation now or in the near future (network fallback, AI upgrade, offline mode). Inject the concrete type at app init or via a factory; use the protocol type everywhere downstream.

In FortuneTeller, PredictionProvider is injected into ViewModels at construction. The algorithmic implementation runs locally with zero latency; a future AIProvider would conform to the same protocol without touching the ViewModel layer.

Trade-offs

  • Pro: Call sites are insulated from implementation changes — future providers require zero refactoring at the consumer layer.
  • Con: Adds a layer of indirection; for a single never-changing implementation the protocol may be over-engineering.

Context

PredictionProvider protocol with AlgorithmicProvider impl.

Reusability

  • Score: 3/5
  • Used in: FortuneTeller

Source

Synced from ops-core learning data. Original source: FortuneTeller

See Also