iOSプログラミングのキモ(行き当たりばったりなプログラミングでも、何とか形にするために守っていること その1)
公開日:
:
Computer Language, FileQ, iOS, iPhone, Java, MacOS X, Objective-C, XCode, オブジェクト指向プログラミング, プログラミング
FileQ iOS版がリリースされて、のんびりしたい気持ちもありますが、FileQ Android版の準備を始めています(^_^)
今回のテーマですが、FileQ iOS版も、QTubeも 私が一人で開発したこともありますが、システム開発で言うところの 基本設計、詳細設計 といった 作業はせず割りと思いつくままにコードを書きました。
行き当たりばったりなので、途中でコードはどんどん変わっていきます。ボタン1つ押したその後のアクションだけでも 最初は1つだけだと思っても後から2つ3つとやらせたい機能が増えることは しょっちゅうです。画面もどんどん増えます。その中で 最初は必要だと思って作ったクラスがその後 必要なくなることもあります。機能追加・変更作業はリファクタリングの連続みたいなものです。
システム開発では、開発途中に仕様追加・変更がよく起こります。
開発側から見ると 出来るだけやめて欲しい(笑)ところですが、どうしても対応しなければいけないこともよくあります。
WEB系のシステムでは 最近では何かしらのフレームワークを使いながら開発を進めることが多いので、その枠(フレーム)から外れない
追加・変更であれば 割りと対応しやすくなってきました。
アプリ開発の場合は WEB系のシステム開発ほど枠(フレーム)がある状態ではありません。
これはアプリよって 設計も異なることが多いので 1つの枠組(フレームワーク)では カバー出来ない ということも起因している気がします。
とは言え、アプリも仕様追加・変更がよく起こることに変わりはないので 何とか上手く対応して行くことが求められます
ということで 今回は 私が、行き当たりばったり(急な仕様追加・変更)な やり方でもアプリとして形にするために 守っている手法を紹介します。
今回はデザインパターンで紹介されている手法に照らし合わせながら、説明していきます。
1,Singleton デザインパターンを積極的に使う
Singletonデザインパターンは、システムがランタイム時にインスタンスが1つだけしかない ことを保証するデザインパターンです。
なんのこっちゃ(笑)って感じですが、WEBシステムでもアプリでも シングルトンにすることで、システムの全体像の見通しが良くなることがあります。
JavaではDIコンテナ(SpringやSeasar2)が2000年代中頃以降 積極的に使われています。
DIコンテナに登録したクラスは基本的にシングルトンとして扱われます、またアブストラクトファクトリーデザインパターンやアスペクト指向プログラミングも同時に提供しているので、クラス生成の管理や機能追加・変更に一貫した手法が提供されるので 品質が一定しやすいというメリットもあります。
私は、親子関係にないインスタンス同士でも互いを簡単に呼び出せるので、Singletonデザインパターンを頻繁に使います。
iOSのプログラミングでは、UIApplicationDelegate クラスは 事実上シングルトンクラスです。シングルトンクラスであること、アプリ起動時最初に呼ばれるクラスであることなどから アプリ全体の動きに関わる管理の役割を果たすことが多いです。
FileQでも多くの箇所で この特性を利用しています。
FileQAppDelegate *appDelegate = (FileQAppDelegate*)[[UIApplication sharedApplication] delegate]; appDelegate.assets = (NSMutableArray*)assets; [tableView_ reloadData]; [[NSNotificationCenter defaultCenter]postNotificationName:NOTIFICATION_ASSETS_CHANGED object:assets];
上記の一行目 [[UIApplication sharedApplication] delegate]; は UIApplicationDelegate を取り出すメソッドです。
このメソッド1つで UIApplicationDelegate を どのクラスからでも 呼び出せるので、UIApplicationDelegate に 共有情報を
管理させて使うのに便利です。
2,複数のクラスから呼ばれる機能は シングルトンデザインパターンで専用のクラスを作る
事実上のシングルトンであるUIApplicationDelegateは、便利ですが 何でもかんでも 機能や情報を詰め込むのはメンテナンス性が下がり問題です。特定の機能については 専用のクラスを作って 共有するのが望ましいです。
Javaの場合、DIコンテナに頼ってしまえば、シングルトンにするためのメソッドを追加する作業は省けるのですが、Objective-CにはDIコンテナがないのでシングルトンにするメソッドを追加する必要があります。
以下は スマートフォン向け広告メディアであるAdMobの広告表示インスタンスを 複数の画面で使いまわすためのシングルトン化するためのメソッドです。
+(GADMasterViewController *)singleton { static dispatch_once_t pred; static GADMasterViewController *shared; // Will only be run once, the first time this is called dispatch_once(&pred, ^{ shared = [[GADMasterViewController alloc] init]; }); return shared; }
クラス全体の説明はCreating A GADBannerView Singleton in AdMob Applicationsを参照してください。
+ で 始まっているメソッドはObjective-Cでは staticメソッドです、インスタンス化しなくても使えるメソッドです。
シングルトン化のキモは この インスタンスを取り出すメソッドを staticメソッドで定義します。
メソッドの中身も至ってシンプルです、iOS4以降で使えるようになった ブロック処理(ここでは dispatch_once)をうまく使っています。
ブロック処理の中で インスタンス化( [[GADMasterViewController alloc] init]; )を行っています。
dispatch_once は その名の通り 一度しか実行されないブロックなので、その中の処理も一度しか実行されません。
ですから GADMasterViewController のインスタンスは singleton メソッドから取り出す場合に限り 常に1つ(同じインスタンス)です。
シングルトンクラスを呼び出す側も簡単です。
GADMasterViewController *shared = [GADMasterViewController singleton]; [shared resetAdView:self];
先に書いたように singleton メソッドはstaticメソッドなので、[クラス名 メソッド名]で呼び出せます。
さらっと書いてしまいましたが 実際使い始めてみると いちいちインスタンス化する手間なく 使えるstaticメソッドって便利だな〜
と思うはずです。
シングルトンに限らず インスタンス化する必要があるかどうか吟味して 必要がなければ 積極的にstaticメソッドを使うことは
コードの安定化に役立つでしょう。
また、マルチスレッドで動作する複数のインスタンスから ある処理が呼ばれる場合、排他処理が必要になることがあります。
この場合もシングルトンクラスを定義し、排他処理が必要な箇所(メソッド)で @synchronized(Objective-Cの場合) で括ることで 割りと簡単且つ安全に排他処理が書けるようになります。
まとめ
例も含めると 結構長くなりそうなので このテーマは2回か3回に分けます。
次回書く予定の項目は以下のものです。
- Mediator デザインパターンを積極的に使う
- 出来るだけ早くエンティティクラスを定義して、クラス間の情報やりとりをシンプルにする
- エンティティクラスはO/Rマッパーと連動させると尚良し
デザインパターンは いろいろな種類があってパターンだけ説明されてもピンとこないことが多いのですが。全てのデザインパターンを覚えなくてはダメというものではないです。 使えそうなところから 少しづつ使ってみるだけでも十分です。
今回、説明したシングルトンは デザインパターンの中でも 意図を理解しやすく 有用性も高いのでぜひ活用して欲しいパターンです。
関連記事
-
-
iOSプログラミングのキモ(拡張子がpchというファイルの役目)
XCodeで プロジェクトを作成すると、-prefix.pch というファイルができています。このフ
-
-
iOSプログラミングのキモ
このブログでは、実際に弊社が公開しているアプリのソースコードを使って、iOSプログラミングのキモを解
-
-
iOSプログラミングのキモ(AppDelegate説明 NSUserDefaultsに設定情報を格納する )
QTubeは、YouTubeを閲覧するときに 国別コードを設定しています。国別コードは iOSに設定
-
-
iPhoneが7GBの転送制限に引っかかりそうになって Nexus7(2013)LTE版のテザリング機能が大活躍
皆さんは スマホを使ってて、転送制限に引っかかったことはありますか?私はあります(笑) 最
-
-
iOSプログラミングのキモ(1:QTubeアプリの説明 )
ソースの説明の前に、QTubeとはどんなアプリなのかを説明します。 QTubeは Youtub
-
-
母校で特別 講義をやってきました。
少し 間が空いてしまいました(^_^;) ちょっと前になりますが、4月末に 同級生で 現在 母
-
-
iOSプログラミングのキモ(サードパーティ製ライブラリをサクッと入れるcocoapods)
iOSプログラミングでは 便利なライブラリがたくさんあります。特にUI系のライブラリは豊富で自分で作
-
-
iOSプログラミングのキモ(MainViewController説明 NSNotification/NSNotificationCenter これ大事)
前回のエントリの続きで 今回はNSNotification/NSNotificationCenter
-
-
iOSプログラミングのキモ(複雑な画面を複数のViewControllerで制御する その1)
久々に、プログラミングの話です(^^; 今日は 機能が複雑な画面を 複数のViewContro
-
-
iOSプログラミングのキモ(MainViewController説明 : dispatch_asyncとブロック構文を使った 今どきのお手軽マルチスレッドプログラミング)
TwitterやYouTubeといったサービスでは、コンテンツの見出しにサムネイルが付加されることが