アスペクト指向勉強会(第9回) - Theme Composition
いよいよ第6章まできましたねぇ。
Chapter 6 Theme Composition
Theme ごとに設計したものを合成する。これがちゃんとできないと、今までやってきたことは全部水の泡。(^^;)
Overview of Composing Themes
こんな手順で行う。
- 合成する Theme を選ぶ
- マッチする Theme を識別する
- マッチさせた設計要素間の衝突を解決する
- Aspect Theme のテンプレートに束縛する Base Theme の振る舞いを識別する
Pick Themes
特になし。
Identify Matching Design Elements
Composition Relationship という関係を使って、複数の Theme を合成する。
2つ方法があって、1つは Theme に属する必要な全ての要素間に明示的に Composition Relationship を引く方法(Explicit Matching)、もう1つは名前などで自動的にマッチングする方法(Implicit Matching)。
Implicit な場合、match[name] とか書かないといけないけれど、普通はこっちがデフォルトでしょ。何も書かなければ「名前でマッチング」の方が親切だと思う。
id:higayasuoさんの言う、Convention over Configuration/Configuration by Exception ってやつね。
Specify Integration
複数の Theme を合成する際のポリシーが2つ。1つは和集合をとる方法(Merge Integration)、もう1つは2者間の場合だけだけど一方で他方を上書きする方法(Override Integration)。前者は双方向の破線矢印で、後者は片方向の破線矢印で表す。
Theme1 と Theme2 の操作 op1() を Merge した場合、Theme1 の op1() と Theme2 の op() を両方呼ぶんだって。ちょっと違和感あり。
Override の例でバージョンが異なる場合をあげているが、そもそもこれって違う Theme なの?
Specify Resolution of Conflicts
Merge の結果、衝突が起こった場合の解決方法。
まず、「ClassB.a の可視性は private だよ」と明示的に記述する方法(Explicit Values)。
resolve(ClassB.a(visibility=private)) のように指定する。
続いて、「属性の可視性のデフォルトは private だよ」のように指定する方法(Default Values)。
resolve(Attribute(visilbity=private)) のように指定する。
もう1つ、Theme間に優先順位をつける方法(Theme Precedence)。
1.prec、2.prec、... のように指定する。
ここでも疑問。
例えば可視性、ある属性が Theme1 では public、Theme2 では private な場合、private に合せちゃうと Theme1 では使えなくならない?
例えばデータ型、a : real、a : int のように型の間に汎化関係がある場合、何となくデフォルトのルールがありそうな気がするんだけど。その辺の考察が甘くない?
あと、Theme Precedence と Override Integration って似てない? もう少し整理する余地がありそう。
Specify Binding to Aspect Themes
Aspect Theme の設計要素を Base Theme に展開する。
bind[{ClassC.x(), ClassE.o(), ...}] のように指定する。ワイルドカードなども使用可能。
横断的な振る舞い(例では op2())が、テンプレートクラス B に入っていると、展開したときいろいろなクラスに複製されてしまうので、別のクラスに移したほうが良さそう。
Composing Game Themes
具体的なアプリケーション Crystal Game で、実際にやってみる。
Matching Design Elements
Explicit Matching と Impliciting Matching。
Explicit Matching の例が同じクラス名ばかりだったら意味ないじゃん。
Implicit Matching の例に何で Explicit Matching の例があるの?
何だか例がイマイチ。
同じ名前だけど、マッチングしたくない場合は dontMatch タグを使う。
同じ名前の設計要素を区別したい場合は Theme名を接頭辞につけて識別する。
Rules for Concept Matching with Composition Relationships
マッチングに関するいくつかの規約。
- Composition Relationship は同じ型どうしにしか引けない。ここで同じ型と言っているのは、Theme と Theme、Class と Class のような意味だと思う。
- 設計要素をマッチさせるためには、まずその要素を含む Theme間に Composition Relationship を引く必要がある。
- 設計要素がマッチするのは、その要素を含むコンテナがマッチする場合だけ。つまり、属性が操作がマッチするならクラスどうしもマッチしている必要がある。
- 合成前の設計要素は、合成後の1つの要素に対応づけられる。
- ただし、Aspect Theme は複数の異なる要素に展開される。
以上。こんな感じで理解あってる? >メンバーの方々
今日はちょっと辛口でした。