【コラム】

ダイナミックObjective-C

60 デザインパターンをObjective-Cで - Prototype (4)

木下誠  [2006/12/20]

Prototypeパターンの話も四回目。デザインパターンからは少しそれた話題が続いたが、今回からは戻ろう。

例によって、Cocoaの中からPrototypeパターンを使っているものを探してみよう。取り上げるのは、セルとコントロールだ。

セルとコントロール

Cocoaはたくさんのビュー、つまりユーザインタフェースの部品を提供している。部品には、ボタンやスライダーといった単純なものもあるが、それらを組み合わせたり、内部に含んだりする、複雑なものもある。

例えば、テーブル表示機能を提供するNSTableViewを見てみよう。テーブルには文字列や画像の他に、ボタンやスライダーといったユーザインタフェースの部品を入れる事もできるのだ。

こういったことを実現するために、Cocoaのビューのいくつかは、セルとコントロールと呼ばれるものから構成される。1つの部品を、あえて2つに分けるのだ。

セルは、描画を担当する。かつ、ユーザインタフェースのメインとなる処理も受け持つ。ユーザインタフェースの実質となる部分だ。

それに対してコントロールは、ユーザからのイベントを受け付ける。また、ウィンドウのビュー階層の中で、自身がどこに位置するか、自身の内部にどうセルを配置するか、ということを管理する。つまり、外部とのインタフェースとなる部分だ。

具体的な例を挙げよう。ボタン機能を提供するNSButtonというクラスがあるが、これはコントロールになる。これと対になる、NSButtonCellというクラスもある。これがセルだ。NSButtonは、その内部にNSButtonCellを配置する事で、ボタンとして機能する事になる。

そしてコントロールには、様々な種類のセル内部に持つものもある。先ほどのテーブルでは、コントロールであるNSTableViewの内部に、NSButtonCellや、スライダー機能を提供するNSSliderCellが配置されているのだ。このように、セルとコントロールの分離によって、複雑なビューが実現できる。

セルはPrototype

さて、ここからが本題だ。デザインパターンの文脈で言うと、コントロールはセルをPrototypeパターンとして使っている。

どういうことか説明しよう。テーブルビューの例で見たように、コントロールは複数のセルを持つ事ができる。この場合、元になるセルを、Prototypeとして、あらかじめ設定しておくのだ。セルを増やすときは、この元になるセルをコピーして、インスタンスを作成する。正に、Prototypeパターンのやり方だ。

このような構造を持つコントロールはいくつかある。ここでは、NSMatrixを紹介しよう。

NSMatrixは、内部にセルを格子状に(マトリック状に)並べるビューだ。セルは、どんな種類のものでも構わない。例えば、ボタンをツールボックスのように並べるときに使われる。

NSMatrixでは、並べるセルの元になるセルを設定するためのメソッドが二種類ある。一つは、セルのクラスを指定するsetCellClass:。もう一つは、その名もズバリ、setPrototype:だ。こちらはセルのインスタンスを指定する。

List 1.

- (void)setCellClass:(Class)klass;
- (void)setPrototype:(NSCell*)cell;

setCellClass:を使うと、このクラスからalloc、initを使ってインスタンスを作る事になる。setPrototype:の場合は、Prototypeとなるインスタンスを指定するので、これをコピーすることでインスタンスを作る訳だ。メソッドの名前といい、Prototypeパターンの考え方がそのまま当てはまる仕組みだろう。もっとも、NSMatrixがデザインされたのは、GoFによるデザインパターンが発表される前なのだが。

Interface BuilderによるPrototypeのデザイン

NSMatrixの面白いところは、PrototypeをInterface Builderで指定できる事だ。Interface Builderは、ユーザインタフェースのデザイナであり、ボタンやスライダーにGUIを使って細かい設定ができる。このGUIを、そのままNSMatrixのPrototypeのデザインに使えるのだ。

下の図が、Interface Builderで、NSMatrixをデザインしている様子である。ここでは、NSButtonCellを配置している。

まず、NSMatrix自体の設定として、行と列の数や、XとYのスペースなどを設定できる。さらに、下にある「Match Prototype」と「Prototype」ボタンに注目してほしい。ここでPrototypeの設定を行うのだ。

まず、右下のPrototypeボタンを押す。すると、Prototypeの種類に応じた設定画面に移行する。ここでは、NSButtonCellを使っているので、ボタンを設定するための画面になる。その後、Match Prototypeボタンを押すと、その設定が全体に反映されるのだ。

Interface Builderでの編集結果は、ソースコードではなく、インスタンスのアーカイブとなる。NSMatrixのPrototypeとして指定するのはインスタンスであるので、そのまま使えることになる。Interface Builderの特徴と、Prototypeパターンが、うまくマッチした好例だろう。

    新着記事

    特設サイトの情報

    人気記事

    一覧

    イチオシ記事

    新着記事

    特別企画

    一覧