2015年7月7日火曜日

ライブラリ化の当面のゴール

このブログで紹介しているように、Swiftで書いた独自ライブラリを少しずつ作り進めています。まだまだ途中の段階ですが、どんなゴールを描いているのか、簡単に紹介したいと思います。

最初に言っておきますが、これから書く話は、ゲームなどのアプリを作るのが前提ではありません。あくまで業務アプリなどの、遊び要素の少ないアプリの開発に関しての話です。ゲームのアプリなら、大規模な開発ツールが既に作られていて、それを使うのが賢い選択でしょうから。

 

新しいOSや開発ツールを使い始めたとき、独自のライブラリ化を進めるのは、開発経験が長い人なら一般的でしょう。ただ、どのようにライブラリ化するのか、どんなゴールを目指して進めるのかは、人によって異なると思います。

私の場合は、開発やメンテの手間を減らすことです。それにより、開発期間が短くなりますし、完成後のメンテの負荷も小さくなります。とにかく幅広く使えるライブラリを増やして、アプリ開発の手間を大きく減らすことが目的です。

ライブラリとして作ったコードは、単独で十分なテストをされているのに加えて、複数のアプリで使われているため、品質は高く保たれがちです。また、OSやツールのバージョンアップで変更が生じたときも、ライブラリ単体で更新してテストを済ませれば、あとはアプリ側のライブラリを入れ替えるだけです。複数アプリを合計した際の作業量は、かなり減るでしょう。

あと、ライブラリの形式として、ソースコードのままで使う方法を重視しています。ソースコードのままアプリに追加する形なので、ライブラリにバグがあっても簡単に見付かりますし、ライブラリを拡張したくなったときも、可能性が簡単に判断できます。ソースコードのまま追加するものの、基本的にはライブラリに手を加えません。ただし、どうしても手を加えなければならないケースでは、ソースの先頭に変更内容を明記する形で、認めてはいます(実際には、めったにやりません)。当然ながら、ライブラリを改良して対応するのが、第一の選択肢です。

以上は、あくまで、目先の目的としての話です(もっと大きな目的は、最後のほうに出てきます)。

 

いろいろなアプリを作っていると、似たようなコードを数多く書いている自分に気付きます。たいていは1から書かず、前に作ったソースコードをコピーしてから修正するでしょう。コピーによって手間は減っていますが、似たようなコードを書いている現状には変わりません。

そんな風に考えていると、似たようなコードを書かなくて済む方法はないか、深く考えるようになります。部分的にコピーして作るのではなく、ソースコード全体をファイル単位でアプリに持って行き、そのままで使える状態に作れないかと。これがライブラリ化の始まりです。おそらく、独自のライブラリを作っている人は、似たような経験や考えがあるはずです。

実際にライブラリ化を進めると、かなりの効果があると実感できます。似たようなコードを書くことが減り、ライブラリで済ませられる範囲が少しずつ増えていきます。もし既存のライブラリで機能が不足する場合も、ライブラリのほうを拡張して、新しいアプリに対応させます。その結果、ライブラリが適用できる範囲が少しずつ増えていきます。

Swiftを使い始めてから、それほど時間が経過していません。1.0の正式版が登場してからですから、まだ1年未満です。それでも、ライブラリを少しずつ作り続けたので、だんだん充実してきました。モデルクラスのライブラリも2つ作り、ライブラリの対象範囲も広がっています。今後の充実が、ますます楽しみです。

 

続いて、別な視点でライブラリを考えてみます。ライブラリ化する機能の種類で考えると、ライブラリ化のゴールが見えやすくなります。

真っ先に作ったのは、どのアプリでも必ず使う機能でした。UI部品の生成、日付と時間、ファイルの閲覧、電子メールの送信、描画機能などです。それらが作り終わると、環境設定など、どのアプリでも作りそうな機能をライブラリ化しました。こうした種類のライブラリ化は今も続けていて、ライブラリによるサポート範囲をさらに広げようとしています。

アプリ独自の要素として作らなければならない機能は、扱うデータを操作するモデルクラス、それを画面に表示して操作するビューとコントローラのクラスでしょう。作る量が大きい順に並べると、ビュー、モデル、コントローラとなります。

このうち、モデルのクラスは、すでにライブラリ化を進めています。まだ種類は少ないですが、少しずつ種類を増やして、ライブラリで済ませる率を向上させる予定です。

ビューは、モデルのように、個々のモデル全体をライブラリで作る形が難しい分野です。ビューの一部をライブラリとして用意し、それらを組み合わせて1つのビューを実現します。つまり、部品として作るのが適している分野です。ただし、機能の種類が多くあるため、ライブラリでカバーできる比率は、なかなか上がらないでしょう。

当面の方向性としては、次のように考えています。ビューを実現するための要素を、幾つかのタイプに分類して、タイプごとにライブラリを増やすつもりです。今までは、部品となる小さなビューだけでした。しかし、モーダルビューのように、動きの実現がメインとなるライブラリも、今後は増えていくでしょう。また、ビュー上にUI部品を繰り返して並べるような機能も、ライブラリとして作りました。これなどは、配置機能に特化したライブラリです。さらには、いろいろなUI部品を生成する関数群、同じUI部品を一気に生成する関数群など、ビューの構成部品の生成もライブラリ化しています。

あと、紹介していませんが、環境設定の専用ビューもライブラリを試作しました。以前に紹介した、環境設定の機能をライブラリ化したものと連動して、環境設定の値を変更するためのビューを生成します。凝った機能には対応できないレベルですが、一般的な設定の範囲であれば、もう使える状態です。以前紹介した環境設定のライブラリを使うと、環境設定の値を定義するだけで、環境設定の機能が作れます。ビューも同様で、環境設定画面の定義を用意するだけで、環境設定を変更するビューが作れてしまいます。これら2つは連動するので、環境設定機能とビュー機能のやり取りは、コーディングする必要がありません。このように、特定の機能を実現するビューなら、ライブラリとして、まだまだ作れる範囲があると思います。

 

アプリ全体として見た場合、ライブラリが適用できなくて、そのアプリ専用にコーディングが必要となる領域は、ビュー関係に一番多く含まれます。つまり、ライブラリ化の一番の肝は、ビューに関する機能のライブラリ化をどれだけ実現できるかです。モデルに関しては、5種類ほど作れれば、半分以上のモデルをライブラリで作れるでしょう。ビューでは、そのような考え方が通用しません。どんな切り口でライブラリ化したら良いのか、どうすれば新しい工夫ができるかが、ビューに関するライブラリ化の度合いを決めます。

今後は、さらにレベルアップできないか検討中です。もう少し違った切り分け方で、ビューの機能を実現できないかと、かなり考えています。まだ結論は出ていないものの、もしかすれば何とかなりそうなヒントだけは思い浮かびました。これを発展させて、新しい種類のライブラリが作れたら、ビューに含まれる機能のライブラリ比率が、かなり向上させられそうです。

 

アプリとして作る機能のうち、モデルとビューでのライブラリ比率が向上できると、アプリ全体でのライブラリ化率がかなり向上できます。

ライブラリなしで開発したときのコード量を10割としたとき、ライブラリの使用により何割減らせるかが、ライブラリの効果を評価する際の数値になると考えています。ライブラリなしで開発したときのコード量というのも、やや大雑把ですね。あえて説明すると、すべての機能をベタで書いたとき(雑誌やウェブでのサンプルのようなコード)のコード量という意味です。

Swiftのライブラリ化を始めた頃は、どの程度まで作れるのか予想が付きませんでした。漠然とですが、遠い将来は5割が目標だけど、当面は3割ぐらいかなと考えていました。

ところが、ライブラリが増えるごとに、それもライブラリの対象範囲が広がるとともに、5割は簡単に実現できると思うようになりました。実際、今まで作ったライブラリの機能だけに限定したアプリを作るなら、5割ぐらいはライブラリで済ませられ、残りの5割をコーディングする形になりそうです。

もし新しい機能を使うアプリを開発する場合は、その新しい機能の部分も、ライブラリとして作ります。そうすると、ライブラリが対応できる機能が増え、似たようなアプリを再び開発する場合は、やはり5割ぐらいがライブラリで対応できる状態になります。

今では、将来的に7割ぐらいも可能じゃないのかと、思い始めています。前述のビュー機能のライブラリ化が、どこまで実現できるかにかかっています。ただし、ライブラリがいくら充実しても、7割強ぐらいが限界ではないかと思います。ライブラリとして作りにくい機能が、ある程度は残りますから。

 

以上の話は、コード量に関してだけです。アプリ開発では、コードを作る以外の作業が多く含まれます。それが減らない限り、開発の負荷は大幅に減りません。その部分に関しては、かなり難しいでしょう。

それとは別に、開発スタイルが大きく変わる可能性はあります。新規に作らなければならないコードの開発量が減ると、とりあえず試しては変更し、異なる仕様を何度も試せます。ライブラリで実現した機能は、使う際の定義データや使い方を変更するだけで、ある程度まで機能を変えられます。もし機能が不足する場合は、ライブラリを拡張して、新しい機能を追加するでしょう。どちらにしても、いろいろと変えながら試せる可能性は、今よりもずっと高まります。

このような開発スタイルが、ライブラリ化を進めている当面のゴールです。それを実現するために、ライブラリで作るコードの割合を7割ぐらいにするのが、別な視点での当面のゴールとなります。

ライブラリを使って作ったアプリは、俗に言うプロトタイプではありません。本番でも使える、実際に動くアプリです。本番用のアプリを、プロトタイプ的に作ろうというのが、ライブラリ化の本当の目的と言えるかもしれません。

 

今回は趣向を変えて、ライプラリが充実したときの状態を、当面のゴールという形で書いてみました。具体的なコードばかり見ていると、大きな目標を見失ったりします。せっかくですから、大きな目標を掲げて、それに向かって努力したほうが、良い結果が得られるでしょう。これを読んだのを良い機会にして、自分なりの当面のゴールを、考えてみてはいかがでしょうか。

0 件のコメント:

コメントを投稿