(前回)Cocoaの日々: BlogAssistant(5) - プラグインのローカライズ文字列事情
プラグイン作成中の過程でクラス構成を見直すことにした。具体的には MVCの Modelが責務過剰だったのでこれを見直した。
今まではこんな感じだった。
あきらかに1つのクラスに責務が集中しすぎている。
これを責務に毎に分解した。
- 名前も Contorller をやめて Manager としてみた(MVCのControllerとごっちゃになるので)。
- CoreDataManager はCore Data 関連クラスのインスタンスを保持する。他のクラスからの要請に応じてそれを渡すだけの役割を担う。このクラスは汎用的なので他のアプリでも使える。
- ModelManager はトランザクション管理(今回はSQLiteへの保存と画像保存がセット)やデータに関するヘルパー的な役割を担う。ここがいわゆるビジネスロジックを実装する部分。このアプリケーション専用のロジックが埋め込まれる。またController や View に対するデータ操作のインターフェイスを提供する。
- ModelManager は今回一つだが、たくさんのモデルを扱うアプリケーションではビジネスロジック毎複数用意するようになる。
- PathManager はDBファイルや画像ファイルを格納するパスの管理、新規作成する画像ファイル名の発行などを行う。
いずれの Manager もシングルトンで +[sharedManager]でインスタンスを取得してアクセスする。
(例)CoreDataManager* manager = [CoreDataManager sharedManager];
インスタンスを作らずすべてクラスメソッドとグローバル変数で実装する手もあるが、インスタンス化しておいた方が後々拡張しやすいのでこうしておく(インスタンスを複数作成して切り替えたり、実行時にプリファレンスなどによる変更などしやすい)。
それぞれのインターフェイスは現時点でこんな感じ。
CoreDataManager.h
@interface CoreDataManager : NSObject {
NSPersistentStoreCoordinator *persistentStoreCoordinator;
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
}
+ (CoreDataManager*)sharedManager;
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator;
- (NSManagedObjectModel *)managedObjectModel;
- (NSManagedObjectContext *)managedObjectContext;
@end
ModelManager.h
@class Resource;
@interface ModelManager : NSObject {
}
+ (ModelManager*)sharedManager;
-(void)save;
-(Resource*)createResource;
@end
PathManager.h
@interface PathManager : NSObject {
NSString* dataPath;
}
@property (retain) NSString* dataPath;
+ (PathManager*)sharedManager;
- (NSString*)imagePath;
- (NSString*)newImageFilename;
@end
全体の構成イメージはこんな感じとなる。
データの保存や読み込みやビジネスロジックなどはすべて右側の modelクラス群が受け持ち(中心的なのは ModelManager となる)、左側の view と controller はそれらを利用するだけ。おおざっぱに言うと、viewはユーザインターフェイスに専念し、コントローラは view と model の紐付け(データの受け渡し)に専念する。
MVCの考え方は下記がとても参考になった。
Life is beautiful: Ruby on Railsの「えせMVC」の弊害
ついつい controller にビジネスロジックが詰め込まれる、という話はよくわかる。
(今回は modelが肥大化したんだけれど)
- - - -
今日は時間切れ。動くところまでコードの実装が終わらなかった。ソースコード公開は明日以降。