Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
MVVM
Search
Matt Diephouse
May 13, 2014
Programming
250
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
MVVM
Matt Diephouse
May 13, 2014
More Decks by Matt Diephouse
See All by Matt Diephouse
Noble Cocoa
mdiep
2
270
Static Libraries
mdiep
1
130
Other Decks in Programming
See All in Programming
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
610
symfony/aiとlaravel/boost
77web
0
100
Inside Stream API
skrb
1
810
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
130
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
370
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
210
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2.4k
これからAgentCoreを触る方へトレンドはGatewayです
har1101
6
430
ランチタイムLT会3周年!ランチタイムLT会を3年間続けられたお話
y0hgi
1
120
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
990
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
130
ふつうのFeature Flag実践入門
irof
8
4.2k
Featured
See All Featured
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
790
Paper Plane
katiecoart
PRO
1
52k
New Earth Scene 8
popppiees
3
2.4k
How to train your dragon (web standard)
notwaldorf
97
6.7k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
400
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
620
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
320
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.5k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Transcript
MVVM Model – View – ViewModel
WHAT IS MVVM?
IT'S LIKE MVC, BUT DIFFERENT.
BUT IT'S NOT THAT DIFFERENT.
IT'S JUST DIFFERENT ENOUGH.
Example: IPHONE RECIPE APP A TABLE OF RECIPES GROUPED ALPHABETICALLY
MVC 1.0
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.fetchedResultsController.sections.count; } - (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section { id<NSFetchedResultsSectionInfo> info = self.fetchedResultsController.sections[section]; return info.numberOfObjects; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:...]; RCPRecipe *recipe = [self.fetchedResultsController objectAtIndexPath:indexPath]; cell.textLabel.text = [NSString stringWithFormat:@"%@ by %@", recipe.name, recipe.author.name]; return cell; }
MVC 1.0 ▸ Logic is tied to presentation ▸ It
can only be tested visually ▸ The code is verbose ▸ Tightly coupled to the database and model ▸ No separation of concerns
MVC 2.0
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.numberOfSections; } - (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section { return [self numberOfRecipesInSection:section]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:...]; RCPRecipe *recipe = [self recipeAtIndexPath:indexPath]; cell.textLabel.text = [NSString stringWithFormat:@"%@ by %@", recipe.name, recipe.author.name]; return cell; }
- (NSInteger)numberOfSections { return self.fetchedResultsController.sections.count; } - (NSInteger)numberOfRecipesInSection:(NSInteger)section { id<NSFetchedResultsSectionInfo>
info = self.fetchedResultsController.sections[section]; return info.numberOfObjects; } - (RCPRecipe *)recipeAtIndexPath:(NSIndexPath *)indexPath { return [self.fetchedResultsController objectAtIndexPath:indexPath]; }
MVC 2.0 ▸ Some logic could be tested in code
▸ Partial separation of concerns ▸ Reusable methods for getting model objects ▸ Slightly less verbose
MVC 2.0 ▸ Some logic is still tied to presentation
▸ Still requires visual testing ▸ Tightly coupled to the model
MVC 3.0
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.numberOfSections; } - (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section { return [self numberOfRecipesInSection:section]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:...]; RCPRecipe *recipe = [self recipeAtIndexPath:indexPath]; cell.textLabel.text = [self displayNameForRecipe:recipe]; return cell; }
MVC 3.0 ▸ Logic is testable in code ▸ Separation
of concerns
MVC 3.0 ▸ Tightly coupled to the model ▸ Testing
per-row logic requires an entire table view ▸ Logic could easily depend on view
MVVM
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.viewModel.numberOfSections; } - (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section { return [self.viewModel numberOfRecipesInSection:section]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:...]; RCPRecipeViewModel *viewModel = [self.viewModel viewModelAtIndexPath:indexPath]; cell.textLabel.text = viewModel.displayName; return cell; }
@interface RCPRecipeListViewModel : NSObject @property (assign, nonatomic) NSInteger numberOfSections; -
(NSInteger)numberOfRecipesInSection:(NSInteger)section; - (RCPRecipeViewModel *)viewModelAtIndexPath:(NSIndexPath *)indexPath; @end
@interface RCPRecipeViewModel : NSObject @property (copy, nonatomic) NSString *displayName; -
(instancetype)initWithRecipe:(RCPRecipe *)recipe; @end
MVVM ▸ Separation of concerns ▸ Testable in code ▸
Easy to test per-row logic ▸ Loosely coupled ▸ Independent of UIKit/AppKit ▸ Easily have different row types
Q & A