The Model in MVVM
The Model in MVVM is the layer that represents the application's data and business rules: domain entities, validation logic, calculations, and access to persistence or network sources. It has zero knowledge of the ViewModel or View — no observable properties for UI binding, no formatting for display, and no awareness that a UI even exists — which means the exact same Model code could power a mobile app, a server API, and a batch job without modification. This strict independence is what lets the Model be reused and tested completely separately from any presentation concern.
Cricket analogy: The ICC's official playing regulations and a scorer's raw ball-by-ball record are the Model: they define what counts as a wide or a no-ball regardless of whether the match is being watched on TV, radio, or not broadcast at all.
What Belongs in the Model
Concretely, the Model layer typically includes: domain entities (plain classes like Order or User with their invariants), repositories or data-access objects that abstract away whether data comes from a REST API, a local database, or a cache, domain services that encapsulate business rules spanning multiple entities (like calculating shipping cost from an Order and a ShippingPolicy), and validation logic that enforces invariants such as 'an Order must have at least one line item.' None of these classes should import UI framework types, reference formatting concerns like currency symbols for display, or know about loading spinners — those are ViewModel or View responsibilities.
Cricket analogy: A player-eligibility repository that checks whether a cricketer qualifies for a domestic league under residency rules is Model logic; it should never contain code for how the eligibility badge is colored on screen.
Model vs ViewModel State
A subtle but important distinction is that the Model represents durable, domain-true state — an Order's total, a User's email — while the ViewModel represents transient, UI-specific state, like whether a spinner is currently visible, whether a form field currently shows a validation error bubble, or which tab is selected. If you find a boolean like isLoading or isPasswordVisible in your Model classes, that's a sign UI concerns have leaked into a layer that should be UI-agnostic; those flags belong in the ViewModel, which is explicitly allowed to know about presentation state even though it must not know about concrete View controls.
Cricket analogy: A player's career batting average is durable Model state that exists whether or not anyone is watching, while 'is the stats overlay currently expanded on this viewer's screen' is transient ViewModel state specific to one broadcast session.
// Model: pure domain logic, no UI awareness
struct Order {
let id: UUID
let lineItems: [LineItem]
var subtotal: Decimal {
lineItems.reduce(0) { $0 + $1.price * Decimal($1.quantity) }
}
func validate() throws {
guard !lineItems.isEmpty else {
throw OrderError.emptyOrder
}
}
}
protocol OrderRepository {
func fetchOrder(id: UUID) async throws -> Order
func save(_ order: Order) async throws
}
// Notice: no SwiftUI import, no @Published, no formatting.The repository pattern is the idiomatic way to expose Model data to the ViewModel: a repository's interface (e.g., OrderRepository) hides whether data comes from a REST API, GraphQL, a local SQLite cache, or a combination with offline-first sync, so the ViewModel that consumes it never needs to change when the data source changes.
Testing the Model
Because the Model has no UI dependency, its tests are typically the fastest and most stable in the codebase: pure unit tests that construct domain objects, call methods, and assert on results, with no need for a UI test runner, simulator, or emulator. A well-designed Model also makes it possible to test complex business rules — like tiered shipping discounts or overlapping-booking detection — exhaustively with many edge cases, something that would be slow and flaky if those rules were entangled with rendering code.
Cricket analogy: A statistician can exhaustively test 'does this Duckworth-Lewis-Stern calculation handle a rain delay at over 35' using nothing but input numbers and expected outputs, with no stadium or broadcast required.
A common mistake is letting the Model return already-formatted strings, like an Order returning '$45.00' instead of the Decimal 45.00, because that silently bakes a locale and currency assumption into the domain layer; formatting for display, including currency symbols, date formats, and pluralization, belongs in the ViewModel or a dedicated formatter the ViewModel calls.
- The Model holds domain entities, business rules, and persistence access, with zero UI awareness.
- Model code can be reused across mobile, server, and batch contexts because it never imports UI types.
- Repositories abstract data source details away from the ViewModel that consumes the Model.
- Durable domain-true state (an Order's total) belongs in the Model; transient UI state (isLoading) belongs in the ViewModel.
- Model logic is fast and stable to unit test since it needs no UI framework, simulator, or emulator.
- Avoid returning display-formatted strings, like currency-formatted text, from the Model.
- Complex business rules are best exhaustively tested at the Model layer, not entangled with rendering code.
Practice what you learned
1. Which of the following is appropriate Model-layer code?
2. What is the role of a repository in the Model layer?
3. Where should a flag like isLoading typically live?
4. Why is Model-layer code typically fast and stable to unit test?
Was this page helpful?
You May Also Like
What Is MVVM?
An introduction to the Model-View-ViewModel pattern and how data binding connects its three layers.
The ViewModel in MVVM
How the ViewModel exposes observable state and commands, manages lifecycle, and stays independently testable.
The View in MVVM
The View's role as a declarative, logic-free rendering layer that binds to the ViewModel and forwards user input.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics