Mobile Design Rounds
GuideAndroidiOS13 min read

Design patterns in mobile system design rounds (Android and iOS)

Last reviewed . Drafted with AI assistance. Checked against official documentation where noted (how this is checked). Part of: The five-step method · Case studies.

How to read this. Patterns are vocabulary. They are not answers. In a round, state the problem first, then say the pattern name in one short phrase. This page lists the patterns that the rounds on this site use, and where each one appears. The platform sections near the end cover patterns that Android and iOS use a lot, such as delegation.

TL;DR. Eleven patterns cover most of the mobile design rounds here. Four of them carry the most weight: state machine, outbox, repository and idempotency key. Each round now shows the patterns it uses at the top.

The patterns at a glance

PatternThe problem it solvesRounds that use it
State machineA flow has many steps, retries and interruptions, and flags allow impossible mixes.state machine, booking app, video app, pagination library
OutboxThe user acts on a bad link, and the action must not be lost or sent twice.chat app, news feed, travel plans app, analytics sdk, photo file sync
Repository (single source of truth)The network, the cache and the screen disagree about what the data is.chat app, news feed, live ticker, pagination library
Observer (a stream of values)Many screens need the latest value without asking again and again.live ticker, chat app, state machine, pagination library
Facade and adapterA vendor library or a messy engine should not leak into the rest of the app, or into other developers' apps.feature flags, pagination library, analytics sdk, push sdk, image loading
StrategyThe same step must behave differently by situation, and the choice should be easy to swap.feature flags, pagination library
CoalescingDuplicate or very frequent work should become one piece of work.image loading, live ticker
Memento (saved progress)The system ends the process in the middle of a task.state machine, photo file sync, booking app
Scoped owner (the careful singleton)Some objects must outlive screens: a player, a flag store, an image loader.feature flags, video app, image loading
Idempotency keyA retry must not do the work twice.booking app, chat app, state machine, analytics sdk
Layered cacheThe network is slow or missing, and the app should still show something true.image loading, feature flags, public transport app, news feed

The eleven patterns

State machine

The problem. A flow has many steps, retries and interruptions, and flags allow impossible mixes.

The shape. List every state the flow can be in, and every event that can move it. One pure function maps a state and an event to the next state and a list of effects.

On a phone. The process can end between two states. Save the states that cost money, and start from a state that asks the server, not from the first screen.

Where it breaks. The list grows past about ten states. Split it into nested machines.

Where it appears.

Say this. "I write the states and events first, so a double tap has one answer."

Outbox

The problem. The user acts on a bad link, and the action must not be lost or sent twice.

The shape. Write the intent to a local table in the same transaction as the local change. A worker sends the rows in order and marks one done when the server confirms.

On a phone. A scheduler runs the sender: WorkManager on Android, or a background task on iOS. The process can die after the send and before the answer, so the row carries a key that makes a retry safe.

Where it breaks. Rows that depend on each other need an order. A queue that never drains needs a visible failed state.

Where it appears.

Say this. "The tap writes a row. A worker sends it. A key makes the retry harmless."

Repository (single source of truth)

The problem. The network, the cache and the screen disagree about what the data is.

The shape. One class owns where a type of data comes from. The screen reads the local copy, and the network writes into it.

On a phone. Screens are recreated all the time. The local copy survives them, so the screen can draw at once and update when the network answers.

Where it breaks. Two places write the same data, or the repository only forwards calls and decides nothing.

Where it appears.

Say this. "The screen reads one copy. The network updates that copy."

Observer (a stream of values)

The problem. Many screens need the latest value without asking again and again.

The shape. A source publishes values. Any number of readers receive the newest one.

On a phone. Collect only while the screen is visible. Decide how often the screen redraws: a stream that emits every tick and redraws every tick wastes battery.

Where it breaks. A stream with no limit on its rate. Pair it with coalescing.

Where it appears.

Say this. "The screen collects the latest value, and only while it is on screen."

Facade and adapter

The problem. A vendor library or a messy engine should not leak into the rest of the app, or into other developers' apps.

The shape. A facade gives one small front to a bigger engine. An adapter turns a vendor API into the interface you want.

On a phone. An SDK author cannot see the host app, and every public name is a promise for years. Keep the public surface small, and keep the engine private.

Where it breaks. An interface that copies the vendor one to one, so a vendor change still reaches every caller.

Where it appears.

Say this. "The app talks to my small interface. The vendor is behind an adapter."

Strategy

The problem. The same step must behave differently by situation, and the choice should be easy to swap.

The shape. Put one decision behind a small interface, so a different rule can be swapped in without changing the caller.

On a phone. The right rule depends on the phone: the network, the battery, the foreground. Examples are when to apply new values, or how long to wait before a retry (see the retry explorer).

Where it breaks. The caller picks the rule with an if-chain, so the strategy is only a name.

Where it appears.

Say this. "The rule for when new values apply is separate from the code that applies them."

Coalescing

The problem. Duplicate or very frequent work should become one piece of work.

The shape. Merge duplicate or very frequent work into one piece of work.

On a phone. Lists ask for the same image many times while the user scrolls. A feed of prices changes faster than the screen can draw. One shared download, or one newest value, saves memory and battery.

Where it breaks. When order matters, such as chat messages, merging loses information.

Where it appears.

Say this. "Identical requests share one download. I draw the newest tick, not every tick."

Memento (saved progress)

The problem. The system ends the process in the middle of a task.

The shape. Keep a small record that lets a task resume, or lets the app check what happened.

On a phone. Where the record lives decides if it survives. A small saved state can vanish when the user swipes the app away. A database or a file survives. The state machine build guide shows the difference.

Where it breaks. Saving too much, or saving after the request has already left.

Where it appears.

Say this. "I save the attempt before I send it, so a killed app can ask what happened."

Scoped owner (the careful singleton)

The problem. Some objects must outlive screens: a player, a flag store, an image loader.

The shape. One instance owns a resource for as long as the app runs. It is created at app start and passed in, not reached through a global.

On a phone. A screen can be destroyed at any time. A player, a flag store or a payment call must not die with it.

Where it breaks. Hidden global state that no test can replace.

Where it appears.

Say this. "One store lives as long as the app, and screens take a view of it."

Idempotency key

The problem. A retry must not do the work twice.

The shape. The client makes a unique id before the first send. The server keeps the result for that id and returns it again for a repeat.

On a phone. Make the id and save it before the request leaves. After a kill, the id is what lets the app ask what happened. See idempotency keys on mobile.

Where it breaks. The same key with different data, or a key that the server has already forgotten. Stripe, for one, may prune keys after at least 24 hours.

Where it appears.

Say this. "The phone makes the key before the first send, so a retry counts once."

Layered cache

The problem. The network is slow or missing, and the app should still show something true.

The shape. Keep the data in layers, such as memory, disk and network. Read the nearest layer first.

On a phone. The network may be missing for hours. Show the saved copy at once, say how old it is, and replace it when fresh data arrives.

Where it breaks. A key made only of the URL, or stale data shown with no age.

Where it appears.

Say this. "The screen shows the saved copy with its age, and the network replaces it."

Patterns that each platform uses a lot

The general patterns above sit on top of habits that each platform has. An interviewer who works on one platform will listen for them. The rows say which general pattern each platform habit is, and which round shows it.

Android

Platform habitWhat it isGeneral patternWhere it shows up
ViewModel as a state holderA class that holds screen state and logic. It stays in memory until the screen leaves the back stack (Android app architecture guide).State machine, observerDesign a state machine for a mobile flow, Design a pagination library
Unidirectional data flowState flows down to the screen, and events flow up to the owner of the data (Android app architecture guide).State machineDesign a state machine for a mobile flow
Repository over a databaseOne repository per type of data. In an offline-first app the database is usually the source of truth (Android app architecture guide).RepositoryDesign a chat app, Design a news feed
WorkManagerWork that runs reliably even if the app exits or the device restarts. It stores the work in its own database (Android persistent work).Outbox runnerDesign a chat app, Design photo backup and file sync, Design an analytics SDK
Flow and StateFlowKotlin streams that a screen collects. Not verified against the docs here.ObserverDesign a stock ticker app
Sealed interfaces and whenA closed list of cases that the compiler checks. The Kotlin in the build guide compiles and passes its tests.State machineDesign a state machine for a mobile flow
RecyclerView adapter and view reuseAn adapter feeds rows to a list, and row views are reused as the list scrolls. General knowledge, not verified here.AdapterDesign an image loading library
Dependency injectionPass the pieces an object needs in through its constructor, with Hilt, Koin or by hand. Objects that live as long as the app belong in the application class. General knowledge, not verified here.Scoped ownerDesign feature flags and remote config

iOS

Platform habitWhat it isGeneral patternWhere it shows up
DelegationOne object (the delegating object) hands decisions and events to one other object, the delegate. A delegate can return a value that changes what happens next. Apple's older page says the delegating object keeps a weak reference to its delegate (Apple delegation (retired archive page)).Strategy, a one-to-one observerDesign a push notification SDK, Design an analytics SDK (how an SDK reports back to the app)
Data sourceAlmost the same as a delegate, but it supplies data: a table or collection view asks its data source for rows (Apple delegation (retired archive page)).AdapterDesign a pagination library, Design an image loading library
NotificationCenterBroadcasts a message to any number of registered observers inside one app. It can also hand the messages to you as an async sequence or a Combine publisher (Apple NotificationCenter).Observer (one-to-many)App-wide signals such as the app coming to the foreground. No round depends on it.
Combine, @Published, ObservableObjectStreams and published properties that SwiftUI watches. The Swift store in the build guide is an ObservableObject.ObserverDesign a state machine for a mobile flow
Enums with associated valuesA closed list of states, each with its own data. The compiler checks every switch.State machineDesign a state machine for a mobile flow
Actors and @MainActorCode that runs on one actor handles one event at a time, in order.A serial queue for eventsDesign a state machine for a mobile flow
CoordinatorA common convention, not an Apple API: one object owns the order of screens in a flow, so screens do not know about each other.State machine at flow levelDesign a state machine for a mobile flow
Background tasksPersistent work on iOS. See the guide WorkManager vs BGTaskScheduler.Outbox runnerDesign photo backup and file sync, Design a chat app

How does the code report back? Four options

This is a question you meet when you design an SDK, and when you explain one in a round. This table is my own guidance, not an Apple or Google rule.

NeediOSAndroid
One result of one callA closure, or an async functionA lambda, or a suspend function
One listener, several related events, or a decision that comes backA delegateA callback interface
Many listeners that you do not know in advance, and no answer neededNotificationCenterA shared stream, or an event bus owned by the app
A stream of values over timeAn async sequence or a Combine publisherA Flow

The choice matters in an SDK because the host app lives for years. A delegate or a callback interface is easy to read in a stack trace. A stream is easy to combine. A closure per call is the lightest. I would say which one I pick and why, and that I keep it the same across the SDK.

How to talk about patterns in a round

  • Problem first, name second. "A retry could charge twice, so the phone makes a key first. That is an idempotency key." The other order sounds like a recitation.
  • One sentence of cost. Every pattern costs something. Say it: a state machine costs a longer list of states, an outbox costs a queue that can stall.
  • Use the platform word too. "A ViewModel holds the state, and it is a state machine" shows that you know both.
  • Do not stack patterns. Three patterns on one box is a sign that none of them is doing work.

Common weak answers. Naming a pattern before there is a problem. "I would use a singleton" with no word on how it is created or replaced in a test. A repository that only forwards calls. An observer with no rate limit. These repeat across public prep material. They are not a dataset.

Further reading (official docs)

Verification notes (last reviewed 15 Oct 2026)

The patterns themselves are general software design knowledge, and the choice of eleven is my opinion. I fetched these pages on 2026-10-15. Android architecture guide: unidirectional data flow, state flows down and events flow up; a single source of truth owns a type of data and only it can change it; in an offline-first app the source of truth is usually a database; a ViewModel stays in memory until the screen leaves the back stack; a repository exists per type of data and abstracts its sources. Android persistent work: WorkManager keeps tasks across app restarts and reboots, stores work in an internal SQLite database, and is for work that must run reliably. Apple delegation (a retired archive page that says it may not show current best practice): the delegating object keeps a reference to the delegate and sends it messages; a delegate can return a value that changes what happens; in managed memory the delegating object keeps a weak reference to its delegate; a data source is almost identical to a delegate. Apple NotificationCenter: a dispatch mechanism for broadcasting to registered observers within one program, with async sequence and Combine publisher forms. Not verified: the Flow, RecyclerView and dependency injection rows, and the table of reporting-back options, which is my guidance. Which patterns each round uses comes from that round's own page, read on 2026-10-15, and I kept to what the page says.

Get the free one-page cheat sheet

One page: the five steps, a 45-minute time plan and two checklists. Print it or keep it on your phone.

We email you the cheat sheet after you confirm your address. You can also open it now from the Start here page. You get a short note when a new case is published. Unsubscribe any time. Privacy.