Transcript アスペクト指向システム
アスペクト指向
発表者 che
現在の問題点
各モジュールを完全に分離できない
それぞれが依存しあっている
○リエモーンっっ!
モジュールがきれいに
わけられないよー!
モジュール化
プログラミングにおいて、モジュール化は重要
な考え方
モジュール化の利点
再利用性
読みやすさ
分業のしやすさ
モジュール間は依存性がない方がよい
この原則を「関心事の分離」という
関心事
ひとまとまりの処理やデータ
プログラム中に何度も出てくる同じ「処理」
関数
一つにまとめることができる「データ」
構造体
ひとまとまりのデータと、それに強く結びつく「処
理」
クラス
Separation of Concern
(SOC、関心事の分離)
プログラミングにおける基本原則の一つ
Edsger W. Dijkstraらにより1970年代前後に
提唱
関心事をモジュールとしてまとめ、他の関心事
と分離する
プログラムの保守性と再利用性の向上
プログラミング言語の制約により分離できる関心
事と分離できない関心事が存在する
モジュールの依存性が少ないほど、再利用性
が高まる
大きくモジュールを分けると
ビュー
入力
世界
AI,プレイヤー
今回のモデルの問題点
「世界」を記述するときに、オブザーバの存在
を意識する必要性
本来、「世界」は独立したモジュールのはず
世界が変更
されたら知ら
せなきゃ
オブザーバパターンの実装
Worldクラスにて
世界が変更された!
void update() {
・・・ //世界を変更する処理
}
notifyObservers(); //オブザーバに通知
オブザーバに
知らせなきゃ!
何がまずいのか?
世界を変更する処理が増えると、その全てで
オブザーバへの通知を行う必要性
保守性、再利用性に影響
void update1() {
・・・ //世界を変更する処理
notifyObservers(); //オブザーバに通知
}
void update2() {
・・・ //世界を変更する処理
notifyObservers(); //オブザーバに通知
}
void update3・・・
コードが分散
してるなあ・・・
オブザーバパターンにおける関心事
オブザーバパターンに関連した関心事
「世界」を表現する
Worldクラス
「世界」を描画する
WorldPanelクラス
「世界」が変化したら「世界」を再描画する
?
これはどのクラス
に属するの?
ちょっとおさらい:
オブジェクト指向って?
モジュール化技術の一つ
プログラムは「オブジェクト」単位で構成
オブジェクトで表現できないものを表現するのは難
しい
階層構造を記述する
階層構造でないものを記述するのは難しい
オブジェクト指向の限界
オブジェクト指向では扱いにくい問題(関心事)
が存在する
ロギング
エラーチェック
ネットワークの接続性チェック
データの妥当性チェック
マルチスレッド環境下での同期
etc…
横断的関心事
横断的関心事
他の関心事に強く依存する関心事を「横断的
関心事」という
オブジェクト指向では扱いきれない
従来の方法で実装するとコードが分散してし
まう
モジュール化できない
アスペクト指向プログラミング(AOP)
の導入
アスペクト指向による解決
オブジェクト指向では扱えない問題が解決できる
アスペクト指向
モジュール化技術の一つ
従来はできなかった横断的関心事のモジュー
ル化を可能に
横断的関心事を「アスペクト」として表現
明示的でない手続き呼び出し
階層的でない構造を記述する(横のつながり)
アスペクト指向システム
AspectJ
今回は
AspectJを使います
現在最も普及しているアスペクト指向システム
Eclipseプロジェクトの一つとして実装が進んでいる
Hyper/J
最も純粋なアスペクト指向システム
あまり普及していない
JBoss
アスペクト指向としては微妙?
実用的なシステムではある
簡単な例 ロギング(従来の方法)
「ある処理をするときに、ログを出力したい」
従来の方法
ロギング部分だけ
切り出すことは
不可能
class Hoge {
void foo() {
System.out.println(“Hoge.foo()”);
・・・ //メソッド本体
}
}
簡単な例 ロギング(AOP)
アスペクト指向による実装
class Hoge {
void foo() {
・・・ //メソッド本体
これが
}
アスペクト }
メソッド自体には
何も書かなくていい
Hogeのfooメソッド
を実行する前に
aspect Logger {
before(): execution(void Hoge.foo()) {
System.out.println(“Hoge.foo()”);
}
}
ロギング
を実行
AOPにおけるオブザーバパターン
class World {
notifyObservers
・・・ //省略
を書かなくていい
void update() {
・・・ //Worldを変更
}
これが
アスペクト }
ここに
まとめて書く
aspect Observer {
after(): call(void World.update()) {
worldPanel.repaint();
}
}
ユーザ操作
「キー入力に基づいてロボットを操作したい」
2つの関心事がある
キー入力を処理する
ロボットを操作する
オブジェクト指向での実装
KeyboardPlayerというクラスを用意して、キーイベ
ントを取得する
class KeyboardPlayer implements KeyListener {
public void keyPressed(KeyEvent e) {
・・・ //キーイベントに応じた処理
例えばこんな妄想
ある一つの
クラスでキー入
力を処理して、
ロボットも
操作して、
しかもモジュール分け
ができたらいい
なぁ・・・
アスペクト指向
ならできます!
アスペクト指向のもう一つの顔:
プログラムの機能拡張
アスペクト指向では、既にあるプログラムに機
能を付け足すことができる
あるクラスにメソッドやフィールドを追加する
あるクラスを他のクラスのサブクラスにしてしまう
一つのクラスで、複数の関心事を実装し、なお
かつモジュール化される
アスペクト指向によるキー操作の実装
Robotを
KeyListenerの
実装クラスにしちゃえ!
aspect Player {
declare parents: Robot implements KeyListener;
}
public void PlayerRobot.keyPressed(KeyEvent e) {
・・・ //キーイベントを処理
}
Robotに
keyPressedメソッド
を追加しちゃえ!
AI
AIをアスペクトで表現してみよう
デモ
アスペクト指向を使ったプログラミングの実演
敵のAIをアスペクトで作ってみる
敵を動かしてみよう
敵に弾を出させよう
敵に弾を避けさせよう
もっと頭を良くしてみよう
アスペクト指向を体験してみたい方
AspectJの開発に必要なもの
Java SDK
Eclipse 3.1
AspectJプラグイン
敵を動かしてみよう
敵に攻撃させてみよう
敵に弾を避けさせてみよう
もっと頭をよくしてみよう
アスペクト指向導入の利点
横断的関心事がモジュール化できる
オブジェクト指向では実現できない
仕様変更に強い
オブジェクト指向は静的な構造を記述する
構造変化に弱い
アスペクト指向の欠点
コード量の増大
一般的にモジュール化を進めるとコード量が増え
る
コードの見通しが悪くなる可能性
あるコードに関連するコードが、全く別の場所に書
かれているかも・・・
まとめ:アスペクト指向
オブジェクト指向では扱いきれない問題
横断的関心事
アスペクト指向は新しいモジュール化技術
横断的関心事をモジュール化できる
全体まとめ
おわり