C.2. Swarm流Objective C

Swarmシステムは、Objective-Cの構文/スタイルに対する拡張構文や拡張スタイルをいくつか提供しています。このセクションは、初心者が覚えておく必要のある重要な機能と、反対に無視しても構わない機能を紹介します。

C.2.1. 特殊なテクニックとそれが使われているライブラリ

Swarmシステムの内臓を構築しているとき、我々は従来のObjective C言語にかなりの装置を加える必要があることに気づきました。特に重要だと思われたのは、オブジェクトの作成に使われるシステムを拡張することです。このセクションの最大の目的は、それがどんな変更だったのか、そしてユーザはなぜそれを知っていなくてよいのか、という点を簡潔に説明することです...

Swarmライブラリの中で以下のようなマジックのいくつかを利用しなければならないのは、最も基礎的なライブラリに限られています。具体的には、Defobj、Collections、Activityという3つのライブラリだけがそのマジックを使用しています。しかし、いくつか地味な規則があるため、結果としてコードの至る所で使う必要が出ています。

C.2.2. 原則としてのZone

おそらく、オリジナルのObjective Cから最も明らかに変更された箇所は、オブジェクトが割り当てられるZoneの使用方法です。我々の要求は、主に2つの理由でオブジェクトが特定のZone内に割り当てられるようにすることでした。

C.2.3. 実践としてのZone

初級ユーザならそうすると思いますが、Zoneを与える必要があるとき、すでに有効なzoneに初期化されているグローバルなglobalZone変数を使うことができます。しかし、これにはがっかりすることになります。なぜなら、そのZoneの中にあるものはプログラムの実行全体の至る所に存在することになり、結果としてメモリの利用が非効率になると予想されるからです。また、mallocを使うのでなく、常にZoneからメモリを割当てようとしなければなりません。さらに、現在のスコープを過ぎて必要とされない一時オブジェクトを割り当てるときは、scratchZoneが提供されます。

C.2.4. 原則としてのCreateフェーズ

Swarmに使われているさらに驚くべきメカニズムの1つに、Createフェーズのプロトコルがあります。このプロトコルの背景には、あなたがあるオブジェクトを作成するとき、実際にはファイナルオブジェクトでなく"プロトオブジェクト"を取得するという考え方があります。次に、一連の"createフェーズ"メッセージが"プロトオブジェクト"に送られます。このメッセージは、システムにそのオブジェクトの使用方法に関するヒントを与えます。

したがって、たとえばListオブジェクトを作成するときは、リストへのアクセスを任意の場所からでなく一方の端からに限定するといった宣言ができます。この方法をとれば、"プロトオブジェクト"はあなた固有の使用パターンに適合することを目的としたテーラーメイドの実装を提供できます。Swarmのパフォーマンスを重視したライブラリ(たとえばActivity)では、この種のアプローチは極めて重要です。これらのライブラリでは、下図のようなことが時折り発生します。

Figure C-1. プロトオブジェクトの作成

C.2.5. 実践としてのCreateフェーズ

オブジェクト指向プログラミング界では、この形式のオブジェクト作成はまだ極めて稀なので、我々はユーザが実際にこの種のテクニックを実装するコードを記述するとは期待していません。しかし、あるオブジェクトの存続期間の中で1回だけ送られると予想されるメッセージは、複数回送られるメッセージから分割して、そのオブジェクトの作成直後に送ることを勧めます。

たとえばColorのように、オブジェクトの持っている変数が将来決して変化せず、しかもその存続期間の極めて早い段階でセットすべきものであれば、あなたは以下のようにして、createEndメッセージの前でこの変数をセットするメッセージを宣言すべきです。

-setColor: (int) aColor ; // createフェーズのメッセージ 
-createEnd ;
-(int) getColor ; // 通常のメッセージ
    

その他にもう1つだけ要求することがあります。Swarmではどのオブジェクトを作成するときも、createEndが呼び出されるときにかならずそのオブジェクトを再割り当てしなければなりません。

anObject = [anObject createEnd] ;
    

なぜなら、Swarmライブラリ内のプロトオブジェクトはcreateEnd時に自らを返さないからです。実際、それらは偶然にもユーザのニーズを満たすような、まったく異なるクラスのオブジェクトを返すこともできます。したがって、あなた自身のクラスをcreateEndするときでも、この標準の作成書式を守るべきです。

クラスによっては、オブジェクト作成に"便利なメソッド"がいくつか提供されています。基本的にこれらはそのクラスの開発者がそうすれば便利であろうと考えた、パラメータ化されたコンストラクタです。しかし、これらの"便利なメソッド"がもたらすオブジェクトは、createフェーズで呼び出された連続する一連の個別メソッドで作成されたオブジェクトとは(適切なパラメータがそれぞれにセットされる限り)、絶対に異なっていてはいけません。"nullコンストラクタ"を持つことは重要です。なぜなら、1) それはレガシーコードを壊すことなくクラスのインターフェイスの*成長*を可能にし、2) オブジェクトを扱う際の開発ツールやデザインツールの使用を容易にするためです。この特有の制約(nullコンストラクタの要求)が現在使用され、また必要になっている例は、JavaBeansに見ることができます。もちろん、我々はまだSwarmにそのようなデザインツールや開発ツールを持っていませんが...

C.2.6. CollectionsとDefobj

最後の2つのアドバイス

  1. collectionsライブラリを使っているとき、あなた自身のcollectionsのバージョンを作成したい場合に、collections自身をサブクラス化することでそれを作成してはいけません。その代わりに、内部に適切なクラスのインスタンスを含んだ異なるクラスのオブジェクトを作成してください(OOP界ではこれを委譲と呼びます)。こうすべきなのは、createフェーズの材料をアクティブに使うオブジェクト(つまりcreateEndに対して自身を返さないオブジェクト)の実際のサブクラス化は、十分にはサポートされていないためです。

  2. Defobjはスケジュール、コレクション、swarmオブジェクトを構築する土台となる最も基礎的なSwarmのライブラリです。したがって、Defobjはシステムに完全に包含されます。仮にその中で具象化されているコンセプトに馴染みがなかったり、コードが少し不可解に見えても、がっかりしないでください。

今、多かれ少なかれSwarmに服従する形でObjective Cを使う準備が用意されています。理論上、あなたはこれらのスタンダードに従わなければなりません。特に言語拡張については他のことを何ら知る必要なく、シミュレーションをコーディングできるでしょう(ただし、Swarmが提供するライブラリやツールについては学習する必要があります。それらのインターフェイスはストレートなObjective Cで書かれているため言語上の障壁はありません)。