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