More Related Content
Similar to アップルのテンプレートは有害と考えられる
Similar to アップルのテンプレートは有害と考えられる (20)
More from Brian Gesiak (10)
アップルのテンプレートは有害と考えられる
- 2. 内容
• 単一責任原則
• The single responsibility principle、またはSRP
• UITableViewControllerのファイル・テンプレート
• モデルとコントローラの役割を両方果たしている
• 責任を分担させる一例
• GitHubViewer.appのview controllerからUITableViewDataStoreの
コードを取り出す
• Appleのファイルやプロジェクト・テンプレートについて
• その多くは単一責任原則(SRP)に違反する
• 実装の一例であり、プロダクション・コードで真似すべきでは
ない
- 5. 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 { /* ... */ }
テンプレートの内容
- 6. 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 { /* ... */ }
テンプレートの内容
- 7. 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 { /* ... */ }
テンプレートの内容
- 8. 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 { /* ... */ }
テンプレートの内容
- 17. 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の責任
- 18. 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の責任
- 19. 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の責任
- 20. 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の責任
- 21. 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の責任
- 22. 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の責任
- 23. 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の責任
- 24. 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の責任
- 25. 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の責任
- 26. 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の責任
- 27. 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の責任
- 28. 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の責任
- 29. 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の責任
- 30. 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の責任
- 31. 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の責任
- 32. 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の責任
- 33. 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の責任
- 34. 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の責任
- 35. 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の責任
- 53. GHVReposViewController
1. View controllerの責任
• レポを取得させるようにメッセージを送る
• 通信インジケーターを表示させる
2. UITableViewDataSourceの責任
• レポのデータを持つ
• テーブルビューのsectionの数を決定する
• テーブルビューのrowsの数を決定する
• レポのデータをもとにセルのビュー構成を構築する
3. UITableViewDelegateの責任
• タップしたレポを表示するためのview controllerをプッシュする
- 54. GHVReposViewController
1. View controllerの責任
• レポを取得させるようにメッセージを送る
• 通信インジケーターを表示させる
2. UITableViewDataSourceの責任
• レポのデータを持つ
• テーブルビューのsectionの数を決定する
• テーブルビューのrowsの数を決定する
• レポのデータをもとにセルのビュー構成を構築する
3. UITableViewDelegateの責任
• タップしたレポを表示するためのview controllerをプッシュする
コードが100行以上にも及ぶ
- 55. GHVReposViewController
1. View controllerの責任
• レポを取得させるようにメッセージを送る
• 通信インジケーターを表示させる
2. UITableViewDataSourceの責任
• レポのデータを持つ
• テーブルビューのsectionの数を決定する
• テーブルビューのrowsの数を決定する
• レポのデータをもとにセルのビュー構成を構築する
3. UITableViewDelegateの責任
• タップしたレポを表示するためのview controllerをプッシュする
コードが100行以上にも及ぶ
- 60. GHVRepoStore
UITableViewDataStoreの責任のみを果たす
- (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:/* ... */];
}
- 61. GHVRepoStore
UITableViewDataStoreの責任のみを果たす
- (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:/* ... */];
}
- 62. GHVRepoStore
UITableViewDataStoreの責任のみを果たす
- (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:/* ... */];
}
- 63. GHVRepoStore
UITableViewDataStoreの責任のみを果たす
- (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:/* ... */];
}
- 64. GHVRepoStore
UITableViewDataStoreの責任のみを果たす
- (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:/* ... */];
}
- 71. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 72. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 73. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 74. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 75. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 76. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 77. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 78. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 79. GHVReposViewController
GHVRepoStoreへの責任分担
- (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];
}];
- 92. Appleのテンプレートの問題点
SRPに違反している例
• Master-Detail Application (with Core Data)
• AppDelegate
• UIWindowのroot view controllerの初期化
• Core Data関連のセットアップ、エラーハンドリング
• 100行以上
• OpenGL Application
• ひとつのView controllerがすべての責任を負っている
• OpenGLのcontextの初期化
• Shadersのコンパイル
• Vertexのデータも持っている
• 400行以上
- 97. 最後に
• 本日のスライド: http://modocache.io/apple-templates-
considered-harmful
• Twitter、GitHubでフォローしてください:@modocache
• クリーンコード
• Robert C. Martin:@unclebobmartin
• Object-Oriented Design:http://www.butunclebob.com/
ArticleS.UncleBob.PrinciplesOfOod
• Clean Codeのビデオ:http://cleancoders.com/
• Appleのエンジニアリングの適当さを知るには
• Peter Steinberger:@steipete
• Justin Spahr-Summers:@ jspahrsummers