Apple Templates Considered Harmful
-
Upload
brian-gesiak -
Category
Documents
-
view
7.200 -
download
1
description
Transcript of Apple Templates Considered Harmful
![Page 1: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/1.jpg)
Templates Considered HarmfulApple Templates and the Single Responsibility Principle
Brian Gesiak
March 28th, 2014 at Recruit Co., Ltd.
Research Student, The University of Tokyo
@modocache
![Page 2: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/2.jpg)
Today
• The single responsibility principle (SRP) • The UITableViewController file template
• Model and controller code all rolled into one • Example of how to separate concerns
• Moving data store logic out of the controller in GitHubViewer.app
• Apple file and project templates • Many violate the single responsibility principle • Best to think of them as “proof of concepts”
![Page 3: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/3.jpg)
Single Responsibility Principle
A class should have one, and only one, reason to change.
- Robert C. Martin
![Page 4: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/4.jpg)
Robert C. Martin (Uncle Bob)
![Page 5: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/5.jpg)
UITableViewController
#pragma mark - UIViewController - (id)initWithStyle:(UITableViewStyle)style { /* ... */ } - (void)viewDidLoad { /* ... */ } - (void)didReceiveMemoryWarning { /* ... */ } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { /* ... */ } !#pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView: (UITableView *)tableView { /* ... */ } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { /* ... */ } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ } !#pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ }
What’s Included in the Template
![Page 6: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/6.jpg)
UITableViewController
#pragma mark - UIViewController - (id)initWithStyle:(UITableViewStyle)style { /* ... */ } - (void)viewDidLoad { /* ... */ } - (void)didReceiveMemoryWarning { /* ... */ } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { /* ... */ } !#pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView: (UITableView *)tableView { /* ... */ } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { /* ... */ } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ } !#pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ }
What’s Included in the Template
![Page 7: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/7.jpg)
UITableViewController
#pragma mark - UIViewController - (id)initWithStyle:(UITableViewStyle)style { /* ... */ } - (void)viewDidLoad { /* ... */ } - (void)didReceiveMemoryWarning { /* ... */ } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { /* ... */ } !#pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView: (UITableView *)tableView { /* ... */ } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { /* ... */ } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ } !#pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ }
What’s Included in the Template
![Page 8: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/8.jpg)
UITableViewController
#pragma mark - UIViewController - (id)initWithStyle:(UITableViewStyle)style { /* ... */ } - (void)viewDidLoad { /* ... */ } - (void)didReceiveMemoryWarning { /* ... */ } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { /* ... */ } !#pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView: (UITableView *)tableView { /* ... */ } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { /* ... */ } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ } !#pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ }
What’s Included in the Template
![Page 9: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/9.jpg)
UITableViewDelegate
UITableViewDataSource
UITableViewControllerResponsibilities, a.k.a. “Reasons to Change”
1. Determines what data in displayed in the table !
!
2. Determines how users interact with the table
![Page 10: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/10.jpg)
UITableViewDelegate
UITableViewDataSource
UITableViewControllerResponsibilities, a.k.a. “Reasons to Change”
1. Determines what data in displayed in the table !
!
2. Determines how users interact with the table
![Page 11: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/11.jpg)
UITableViewDelegate
UITableViewDataSource
UITableViewControllerResponsibilities, a.k.a. “Reasons to Change”
1. Determines what data in displayed in the table !
!
2. Determines how users interact with the table
![Page 12: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/12.jpg)
UITableViewDelegate
UITableViewDataSource
UITableViewControllerResponsibilities, a.k.a. “Reasons to Change”
1. Determines what data in displayed in the table !
!
2. Determines how users interact with the table
![Page 13: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/13.jpg)
GitHubViewer
GitHub icon by @peterhajas, licensed under the Creative Commons License version 3.0.
![Page 14: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/14.jpg)
GitHubViewer
GitHub icon by @peterhajas, licensed under the Creative Commons License version 3.0.
![Page 15: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/15.jpg)
GHVReposViewController
- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; }
View Controller Responsibilities
![Page 16: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/16.jpg)
GHVReposViewController
- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; }
View Controller Responsibilities
![Page 17: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/17.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 18: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/18.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 19: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/19.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 20: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/20.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 21: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/21.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 22: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/22.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 23: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/23.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 24: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/24.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 25: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/25.jpg)
GHVReposViewController
- (void)getRepositories { [self startNetworkIndicators]; [self.apiClient allRepositoriesForUsername:self.username success:^(NSArray *repositories) { [self stopNetworkIndicators]; self.repositories = repositories; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }]; }
View Controller Responsibilities
![Page 26: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/26.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 27: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/27.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 28: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/28.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 29: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/29.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 30: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/30.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 31: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/31.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 32: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/32.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 33: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/33.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 34: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/34.jpg)
GHVReposViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kGHVRepoCellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kGHVRepoCellIdentifier]; } ! GHVRepo *repository = self.repositories[indexPath.row]; cell.textLabel.text = repository.name; cell.detailTextLabel.text = repository.repositoryDescription; return cell; }
UITableViewDataSource Responsibilities
![Page 35: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/35.jpg)
GHVReposViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { GHVRepo *repository = self.repositories[indexPath.row]; GHVRepoViewController *controller = [[GHVRepoViewController alloc] initWithRepository:repository]; [self.navigationController pushViewController:controller animated:YES]; }
UITableViewDelegate Responsibilities
![Page 36: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/36.jpg)
GHVReposViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { GHVRepo *repository = self.repositories[indexPath.row]; GHVRepoViewController *controller = [[GHVRepoViewController alloc] initWithRepository:repository]; [self.navigationController pushViewController:controller animated:YES]; }
UITableViewDelegate Responsibilities
![Page 37: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/37.jpg)
GHVReposViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { GHVRepo *repository = self.repositories[indexPath.row]; GHVRepoViewController *controller = [[GHVRepoViewController alloc] initWithRepository:repository]; [self.navigationController pushViewController:controller animated:YES]; }
UITableViewDelegate Responsibilities
![Page 38: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/38.jpg)
GHVReposViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { GHVRepo *repository = self.repositories[indexPath.row]; GHVRepoViewController *controller = [[GHVRepoViewController alloc] initWithRepository:repository]; [self.navigationController pushViewController:controller animated:YES]; }
UITableViewDelegate Responsibilities
![Page 39: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/39.jpg)
GHVReposViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { GHVRepo *repository = self.repositories[indexPath.row]; GHVRepoViewController *controller = [[GHVRepoViewController alloc] initWithRepository:repository]; [self.navigationController pushViewController:controller animated:YES]; }
UITableViewDelegate Responsibilities
![Page 40: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/40.jpg)
GHVReposViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { GHVRepo *repository = self.repositories[indexPath.row]; GHVRepoViewController *controller = [[GHVRepoViewController alloc] initWithRepository:repository]; [self.navigationController pushViewController:controller animated:YES]; }
UITableViewDelegate Responsibilities
![Page 41: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/41.jpg)
GHVReposViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { GHVRepo *repository = self.repositories[indexPath.row]; GHVRepoViewController *controller = [[GHVRepoViewController alloc] initWithRepository:repository]; [self.navigationController pushViewController:controller animated:YES]; }
UITableViewDelegate Responsibilities
![Page 42: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/42.jpg)
GHVReposViewController
![Page 43: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/43.jpg)
GHVReposViewController
1. View controller responsibilities
![Page 44: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/44.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch
![Page 45: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/45.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
![Page 46: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/46.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities
![Page 47: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/47.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities• Store repositories
![Page 48: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/48.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities• Store repositories• Specify how many sections in table view
![Page 49: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/49.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities• Store repositories• Specify how many sections in table view• Specify how many rows in each section
![Page 50: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/50.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities• Store repositories• Specify how many sections in table view• Specify how many rows in each section• Create each cell based on repository data
![Page 51: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/51.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities• Store repositories• Specify how many sections in table view• Specify how many rows in each section• Create each cell based on repository data
3. UITableViewDelegate responsibilities
![Page 52: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/52.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities• Store repositories• Specify how many sections in table view• Specify how many rows in each section• Create each cell based on repository data
3. UITableViewDelegate responsibilities• Push view controller for selected repository
![Page 53: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/53.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities• Store repositories• Specify how many sections in table view• Specify how many rows in each section• Create each cell based on repository data
3. UITableViewDelegate responsibilities• Push view controller for selected repository
100+ lines of code
![Page 54: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/54.jpg)
GHVReposViewController
1. View controller responsibilities• Kick off repository fetch• Show network activity indicators
2. UITableViewDataSource responsibilities• Store repositories• Specify how many sections in table view• Specify how many rows in each section• Create each cell based on repository data
3. UITableViewDelegate responsibilities• Push view controller for selected repository
100+ lines of code
![Page 55: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/55.jpg)
GHVReposViewControllerWhat a Bloated View Controller Looks Like
![Page 56: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/56.jpg)
GHVReposViewControllerSeparation of Concerns
![Page 57: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/57.jpg)
GHVReposViewControllerSeparation of Concerns
![Page 58: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/58.jpg)
GHVReposViewControllerSeparation of Concerns
![Page 59: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/59.jpg)
GHVRepoStoreA UITableViewDataStore and Nothing More
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /// Dequeue, configure, and return a cell } !- (void)reloadRepositories:(GHVRepoStoreSuccessBlock)success failure:(GHVRepoStoreFailureBlock)failure { [self.apiClient allRepositoriesForUsername:self.username success:/* ... */ failure:/* ... */]; }
![Page 60: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/60.jpg)
GHVRepoStoreA UITableViewDataStore and Nothing More
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /// Dequeue, configure, and return a cell } !- (void)reloadRepositories:(GHVRepoStoreSuccessBlock)success failure:(GHVRepoStoreFailureBlock)failure { [self.apiClient allRepositoriesForUsername:self.username success:/* ... */ failure:/* ... */]; }
![Page 61: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/61.jpg)
GHVRepoStoreA UITableViewDataStore and Nothing More
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /// Dequeue, configure, and return a cell } !- (void)reloadRepositories:(GHVRepoStoreSuccessBlock)success failure:(GHVRepoStoreFailureBlock)failure { [self.apiClient allRepositoriesForUsername:self.username success:/* ... */ failure:/* ... */]; }
![Page 62: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/62.jpg)
GHVRepoStoreA UITableViewDataStore and Nothing More
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /// Dequeue, configure, and return a cell } !- (void)reloadRepositories:(GHVRepoStoreSuccessBlock)success failure:(GHVRepoStoreFailureBlock)failure { [self.apiClient allRepositoriesForUsername:self.username success:/* ... */ failure:/* ... */]; }
![Page 63: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/63.jpg)
GHVRepoStoreA UITableViewDataStore and Nothing More
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } !- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.repositories count]; } !- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /// Dequeue, configure, and return a cell } !- (void)reloadRepositories:(GHVRepoStoreSuccessBlock)success failure:(GHVRepoStoreFailureBlock)failure { [self.apiClient allRepositoriesForUsername:self.username success:/* ... */ failure:/* ... */]; }
![Page 64: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/64.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
![Page 65: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/65.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
![Page 66: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/66.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
![Page 67: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/67.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
![Page 68: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/68.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
![Page 69: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/69.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
![Page 70: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/70.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 71: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/71.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 72: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/72.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 73: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/73.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 74: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/74.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 75: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/75.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 76: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/76.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 77: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/77.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 78: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/78.jpg)
GHVReposViewControllerTransferring Responsibilities to the Store
- (id)initWithRepoStore:(GHVRepoStore *)repoStore { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _repoStore = repoStore; } return self; } !- (void)viewDidLoad { [super viewDidLoad]; ! self.title = NSLocalizedString(@"Repositories", nil); [self getRepositories]; !!!!!!!!}
self.tableView.dataSource = self.repoStore; [self startNetworkIndicators]; [self.repoStore reloadRepositories:^{ [self stopNetworkIndicators]; [self.tableView reloadData]; } failure:^(NSError *error) { [self stopNetworkIndicators]; [UIAlertView showAlertForError:error]; }];
![Page 79: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/79.jpg)
GHVReposViewController
![Page 80: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/80.jpg)
GHVReposViewController
1. View controller responsibilities
![Page 81: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/81.jpg)
GHVReposViewController
1. View controller responsibilities• Connect table view to data store
![Page 82: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/82.jpg)
GHVReposViewController
1. View controller responsibilities• Connect table view to data store• Show network activity indicators
![Page 83: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/83.jpg)
GHVReposViewController
1. View controller responsibilities• Connect table view to data store• Show network activity indicators
2. UITableViewDelegate responsibilities
![Page 84: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/84.jpg)
GHVReposViewController
1. View controller responsibilities• Connect table view to data store• Show network activity indicators
2. UITableViewDelegate responsibilities• Push view controller for selected repository
![Page 85: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/85.jpg)
GHVReposViewController
1. View controller responsibilities• Connect table view to data store• Show network activity indicators
2. UITableViewDelegate responsibilities• Push view controller for selected repository
Less than 100 lines of code
![Page 86: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/86.jpg)
Single Responsibility PrincipleBenefits
![Page 87: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/87.jpg)
Single Responsibility Principle
• Less brittle
Benefits
![Page 88: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/88.jpg)
Single Responsibility Principle
• Less brittle• More modular
Benefits
![Page 89: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/89.jpg)
Single Responsibility Principle
• Less brittle• More modular• Easier to read, understand, and debug
Benefits
![Page 90: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/90.jpg)
The Problem with Apple TemplatesIf Only They Knew About the SRP
![Page 91: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/91.jpg)
The Problem with Apple TemplatesIf Only They Knew About the SRP
• Master-Detail Application (with Core Data) • AppDelegate
• Sets up UIWindow root view controller • Sets up Core Data stack, handles errors • 100+ lines of code
![Page 92: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/92.jpg)
The Problem with Apple TemplatesIf Only They Knew About the SRP
• Master-Detail Application (with Core Data) • AppDelegate
• Sets up UIWindow root view controller • Sets up Core Data stack, handles errors • 100+ lines of code
• OpenGL Application • View controller does it all!
• Sets up OpenGL context • Compiles shaders • Stores vertex data • 400+ lines of code
![Page 93: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/93.jpg)
Not All Templates Created EqualSome Templates Employ Modular Design
![Page 94: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/94.jpg)
Not All Templates Created EqualSome Templates Employ Modular Design
• Page-Based Application • Separates concerns among UIPageViewDelegate and UIPageViewDataSource
• Small classes
![Page 95: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/95.jpg)
Not All Templates Created EqualSome Templates Employ Modular Design
• Page-Based Application • Separates concerns among UIPageViewDelegate and UIPageViewDataSource
• Small classes• SpriteKit Game
• Small classes with a relatively clear separation of concerns
![Page 96: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/96.jpg)
Takeaways
• Single responsibility principle • Classes should have one, and only one, reason to change
• Apple’s templates should be thought of as “proof of concepts”, not as examples of clean, well-structured code
• Just because Apple does it doesn’t mean it’s a good idea • Use your better judgement on what’s “clean code” and what isn’t
![Page 97: Apple Templates Considered Harmful](https://reader031.fdocuments.net/reader031/viewer/2022020217/54b75f714a7959a23c8b4613/html5/thumbnails/97.jpg)
Want More on Clean Code?
• Slides for this talk available at http://modocache.io/apple-templates-considered-harmful
• Follow me on Twitter and GitHub at @modocache • Clean Code Resources
• Follow Robert C. Martin at @unclebobmartin • More on Object-Oriented Design at http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
• Clean Code videos at http://cleancoders.com/ • Building a Healthy Mistrust of Apple Engineering
• Follow Peter Steinberger at @steipete • Follow Justin Spahr-Summers at @ jspahrsummers