2014年11月6日木曜日

Roltoへの印刷機能をswiftで書く(全体設計編)

どんな機能でも、ある程度の設計方針を決めてから作り始めないと、効率が悪いのはもちろん、仕上がりまで悪くなりがちです。ただの印刷機能ですが、全体の構造を先に考えました。今回は、その辺の話でも。

印刷機能といっても、いろいろな要素が含まれます。プリンターのドライバーと関わる部分、印刷内容を作る部分、ユーザーインターフェースに関わる部分などです。これらをどのように組み合わせるのか、どのように分割するのかを考えるのが、全体設計です。構成要素への分割だけでなく、要素間のインターフェースも含みます。

 

まずは、プリンターに近い部分から。プリンターを用いた印刷のような、特定の機器に依存する機能は、機器へ依存する箇所をできるだけ少なく作ることが大切です。つまり、別なプリンターを追加したり切り替えたときに、印刷機能を利用する側の変更が、少なくて済むように作るということです。具体的には、プリンターとやり取りするインターフェースを、特定のプリンターに依存せず、どのプリンターでも共通の仕様にしておきます。

プリンタを利用するための一般的な機能として、次のように洗い出してみました。

プリンターのクラスで用意する機能
・プリンターの検索と登録
・プリンターの状態確認
・プリンターで印刷
・印刷のキャンセル
・プリンターの解放と登録解除

これらをメソッドとして用意すれば、プリンターを切り替えたときの、プリンターを利用する側の変更が最小限で済みます。メソッド名も、機種に依存しない一般的な用語で作るのは当然のことですね。

クラスの作り方としては、プリンター全体のスーパークラスを先に用意し、そのサブクラスとしてRoltoのクラスを作るのが順当な考え方でしょう。でも、Roltoが1台目ですし、後で大きく違うタイプのプリンターを追加することもあり得ます。スーパークラスは2機種目の追加のときに考えれば良いし、余計な作業はやりたくないので、今はスーパークラスを作らないと決めました。今回は、スーパークラスを後で追加しても大丈夫なようにメソッドを用意し、Roltoのクラスだけを作ります。

Roltoを別なプリンターに切り替える話をしましたが、逆のこともいえます。別なアプリでRoltoを使う場合、Roltoのクラスをそのままコピーすれば、それを呼び出すコードだけ書けば済みます。つまり、再利用しやすいコードになるわけです。

 

続いて、印刷内容を作る部分です。オフスクリーンで描画し、その内容をUIImageとして仕上げます。オフスクリーンの描画に関しては、作成から終了までの機能を、独立したクラスとして以前に作りました。どのアプリにでも使えるようになっています。今回も、それを使います。

印刷内容を作るのに使うデータは、そのデータを扱うモデルのクラスに入っています。オフスクリーン描画クラスを使うと、実際に書くコード量は短くなるでしょう。今回は印刷の種類が1つで、わざわざ別クラスに作る必要もないと考え、モデルのクラスに含めることとしました。今後、印刷の種類が増えたら、別クラスに分けるかもしれません。

 

最後に、ユーザーインターフェース(UI)部分です。プリンターのような機器を使う場合は、UIに2つの要素が含まれます。1つは、印刷するデータを選んだり、印刷の形式を選んだりするもので、プリンターに直接関係しない要素です。残りは、プリンターを検索したり、印刷を開始したりとか、プリンターを操作する要素で、プリンターに直接関係するものです。これらが明確に分けて画面に付けられれば良いのですが、実際には混在して作ることになります。

また、プリントする機能は、対象となる内容を表示した画面に付けるのが一般的で、印刷する内容の種類だけ追加することになります。大抵の操作手順は、関係する画面ごとに印刷ボタンを用意して、タップしたら選択画面に切り替わります。現れた画面では、データの選択や、印刷の開始などが行なえます。

難しいのは印刷の途中キャンセルで、キャンセルを可能にするとUIが使いづらくなりがちです。現れた選択画面を消さないままキャンセル可能にしておき、そこに印刷の成否などを表示し、確認できたらユーザー操作で戻るといった形でしょうか。逆にキャンセルが不要なら、印刷開始で元の画面に戻り、印刷の成否は、戻った画面にメッセージを表示するという形も可能です。余計な操作を不要に作れます。

以上のようなことを総合的に検討するのですが、今回は印刷が1種類で、特定の画面上でしか使わないため、そこに多くの機能をつけることとしました。もちろん依頼主と相談し、要望を重視しての結果です。

具体的には、その画面を開いたときにRoltoを自動的に検出して(検出の手間を不要にする配慮)、画面上には、Roltoの状態を表示するボタン(もし接続してなければ、検出から始める)、印刷ダイアログの呼び出しボタンを加えます。ダイアログ内では、印刷対象のデータを選択する機能と、印刷の開始とキャンセルのボタンも付けます。印刷時間が短そうなので、印刷の途中キャンセル機能は付けません。また、Roltoの画質変更機能は、アプリの環境設定画面に付けることとしました。

以上の機能は、それぞれ対象となるクラスに加えます。こちらも、印刷の種類が増えた時点で、新しいクラスを追加するか検討することとしました。

 

全体の構造が固まったので、あとは1つずつ作っていくだけです。まずは、Roltoのクラスからでしょう。

0 件のコメント:

コメントを投稿