スクリプトみたいにViewController.mにダラダラ記述して後で他メンバーが保守するときに大変な思いをするより、初見でわかりやすい・保守しやすいコードの方が断然良い。そのためにやっている手法があるので、自身の備忘録に残しておく。
おおまかに伝えたいことだけ先に言うと、機能ごとに関数を疎結合にし、ライフサイクルの上に乗せて動かすように意識すると良い。ここではObjective-Cで書いているがこれに限ったことではない。
やりたいこと
ViewやModel、Controllerなどを最小単位として列挙することで、あとで各処理を見直す際に確認が容易になる。処理を最小単位に書くことで同時に認識しやすくなり、保守が比較的楽になる。
ご指摘あればよろしくお願いします。
ポイント
- viewDidLoadで余計な初期化をしない
- 1 機能につき1 functionを定義する(ケースによるが)
- pragmaを正しく記載する
- 最小単位に処理を分けて関数化することでユニット単位でテストができる
手順
- 各処理を最小単位で関数化し記述する
- pragmaを記載する
ViewController.h
# import <UIKit/UIKit.h>
# import <Foundation/Foundation.h>
// importは必要最小限
@interface ViewController : UIViewController
// 他クラスから参照する必要がある部品以外はヘッダに書かない
@end
ViewController.m
# import "ViewController.h"
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *data;
@implementation ViewController
# pragma mark - Life Cycle // pragmaを書くことでXCode上から定義関数がインデックスされる
- (void)viewDidLoad
{
// 余計な初期化は行わない
// 目的に応じてラップした関数を呼び出す
[super viewDidLoad];
[self getData];
[self setView];
}
# pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// セクション数設定処理
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// cell描画処理
}
:
# pragma mark - Private data
- (void)getData
{
_data = @[].mutableCopy;
:
// データ取得処理をここに書く
// entityクラスを別途定義する
}
# pragma mark - Private View
- (void)setView
{
// 例えばテーブルビューのみ動作を確認したい場合に"setTableView"以外をコメントアウトすると
// テーブルビューのみの動作確認ができる
/* [self setNavigationBar]; */
/* [self setMainView]; */
[self setTableView];
/* [self setToolBar]; */
}
- (void)setNavigationBar
{
// ナビゲーションを実装する
}
- (void)setMainView
{
// view関連の実装
}
- (void)setTableView
{
// tableViewを実装するために必要な処理を書き出す
_tableView = [[UITableView alloc] initWithFrame:CGrectMake(self.view.frame.origin.x,
self.view.frame.origin.y,
self.view.frame.size.with,
self.view.frame.size.height)];
_tableView.dataSource = self;
:
[self.view addSubView:_tableView];
}
- (void)setToolBar
{
// ツールバーを実装する
}
pragma
定義する関数の順序は以下の順で書くのが一般的。
それに従ってpragmaを記述する
- Initialize
- Life Cycle
- Delegate
- Gesture
- Private
まとめ
各関数がそれぞれ疎結合になっていると関数同士の因果関係が明確になり、どこでバグが出ているのかを追いやすくなる。