asatoの技術的な日常日記

「成長に最大の責任をもつ者は、本人であって組織ではない。自らと組織を成長させるためには何に集中すべきかを、自らに問わなければならない」  非営利組織の経営 - ピーター・ドラッカー

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

デザイン:Design Research Quarterly

またまた、Nigel Cross さんのページ みてたら発見。オンラインの雑誌かな? よくわからん。

 Design Research Quarterly
スポンサーサイト

本:Design Research Now

設計研究本。Nigel Cross さんのページ見てたら発見した。



Design Research Now: Essays and Selected Projects

Design is becoming a recognised academic discipline, and design research is the driving force behind this transformation. Design Research Now Essays and Selected Projects charts the field of design research with introductory essays and selected research projects. The authors of the essays, all leading international design scholars, stake out positions on the most important issues of design research. They locate the significance of design research at the interface with technological development, describe what makes it a necessary ingredient of the continued development of the design disciplines, and assign it a seminal role in the relevant developments of society.

The essays are supplemented by the presentation of recently completed research projects from universities in the Netherlands, the UK and Italy.


コード進化パターン:フィールドの削除

昔から書いてる、

 Java におけるコード進化パターン

を更新。今回は「フィールドの削除」を追加。

話としては、(一見)すごく単純。単にフィールドを削除する場合がありますよ、というだけ。

コードで書くとこれだけ。
before:

public class MyClass {

private String s;
}



after:

public class MyClass {
}



難しいのは、どんな状況の時に、フィールドを削除することになるのか、 という点。

いくつかの状況は考えられる。でも、それらの状況を分析しようとしている人はそんなに多くないと思う。

たとえば、フィールドを削除するだけ、というコードの進化は普通は起こらない。フィールドはどこかで使われているはずだから、メソッドボディの変更も伴う。

デザイン:表現の定義

前回の記事(『デザイン:対象と操作』)に関係することを補足。単なる引用だけど。

Simon によれば、表現を定義するとは次のことらしい。

Defining a representation means (1) specifying one or more data types, and (2) specifying the primitive (i.e., "fast") operations that can be performed on information in those data types.


一部しか引用してないけど、詳細を知りたい方は次の論文を参照。

 On the Forms of Mental Representation

ちなみに、元々この論文の存在を知ったのは、 Vinod Goel さんの「Sketches of Thought」という本の139ページで紹介されてたから。


さて、表現の話がなぜデザイン(設計)と関わるのか? そもそも、何を 表現したいのか? これに関しては、(プロダクトとしての)デザインといえる。正確に言えば、もしデザインという行為が、意思決定のプロセス だとするなら、その出力を表現したい。

という流れ。

デザイン:対象と操作

ソフトウェアは、もちろん成果物。成果物を出力するには、なんらかのプロセスが必要。

基本的には、ソースコードをコンパイルして得られるのがソフトウェアだと思う(スクリプトの話はなしで)。

プログラマーは、コードを編集する。要求仕様を満たすように編集する。

さて、ソースコードを抽象化して考えてみよう。ここでの抽象化とは、コメントや空白などを除くことを意味する。抽象化した対象にたいして、プログラマは編集操作を行う。Java プログラムの一部を具体例として考えてみよう。

抽象化した対象をどう表現するか。ここでは、Eclipse なんかでであるようにGUIで表現できるとする。もしくはもっと簡単に、変数名と値を表示するだけとする。

operator_class.png


これで対象が決まったので、次は対象に対する操作を考えてみる。一番単純なのは、クラス名を変更するといった操作。

operator_class2.png


ここで言いたいのは、対象が決まれば、可能な操作が決まるということ。もちろん、可能な操作は勝手には決まらない場合もある。

ソースコードに対する編集操作と、ソースコードを抽象化した表現対象に対する操作は異なる。ソースコードに対する操作には、たとえば、「コメントを追加する」や「空白を追加する」「タブを追加する」「改行する」などの操作が考えられる。しかし、そのような操作は、抽象化した対象に対しては意味を持たなくなる。


次に、操作を抽象化することについて考えてみよう。代表的なのはリファクタリング。たとえば、「スーパークラスの抽出」リファクタリングを考えてみよう。

operator_refactor.png


ここで言いたいのは、抽象化された対象に対する操作のみを使って、より抽象度の高い操作を表しているということ。つまり、「クラスを作成する」などの操作を行ってはいるけどソースコードレベルの操作、たとえば「改行する」などは操作として含まれていないという点。


さて、ここからが今回の話のコアとなる部分。過去の記事で何度か設計という行為は、意思決定の観点から考えられると言ってきた。考えられるとは、つまり、意思決定の観点から抽象化して考えられるとしてきた。

意思決定とは、選択肢からの選択を意味する。つまり、ある操作を表す。そして、操作があるということは操作対象が存在する。

具体例で考えてみよう。状態遷移を実現する必要がある場合、どんな決定を行うだろうか? 選択肢としては、「ifによる分岐」「Stateパターン」「遷移テーブル」などがあると思う [アジャイルソフトウェア開発の奥義]。

ここでは、Stateパターンを選択したとする。

operator_state.png


Stateパターンの基本構造は、こんな感じ。
operator_state2.png



次にStateパターンが適用された構造に対する操作を考えてみよう。二つの観点から考えてみる。

(1)Stateパターンかどうかに関係なくできる操作。たとえば、Stateパターンが適用されていると知らなかったとする。すると、どんな操作が可能か。

(2)Stateパターンが適用されているからできる操作。


まず一つ目だけど、どんな操作でもできる。Stateパターンでなくなるような操作ですら可能。



次に二つ目だけど、たとえば、「ConcreteState」を追加・削除するなんてのは適切な操作の一つ。他にも、request/handleメソッドのペアを追加・削除するなんてのも可能な操作。一方で、request メソッドのみを削除するなんてのは不適切な操作。


まとめ:

対象が決まれば、可能な操作が決まる。

ASE 2007

FOSE に参加したりしてたので ASE が同じ時期に開催されてたのを忘れてた。

ASE の論文はあんまり読まないんだけど、今年の気になる論文は次のだった。

・Keyword Programming in Java

・An Aspect-oriented Weaving Mechanism Based on Component and ConnectorArchitecture

・Inferring Structural Patterns for Concern Traceability in Evolving Software

鵜林先生 のアスペクトの論文が気になる。


本会議はさておき、ワークショップが気になる。特に、Workshop on Living with Uncertainties (IWLU) が気になる。

コード進化パターン:要求変更からコード進化パターンへ

一つ前の記事は、Java での コード進化のパターン の一つとして「View コードの変更」があることを紹介した。

このパターンを簡単に言えば、いわゆる Model-View-Controller (MVC) のビューに関するコードを変更するということ。

何も変化がなければ、この進化パターンは起こらない。実際にどんな要求仕様の変更があったのか?


具体的に何かというと、僕が今作ってるゲーム(不思議のダンジョン系)での要求変更。一人で作っているので、僕が「ユーザ」と「開発者」の二つの役割を持ってる。

見た目の変化は次の画像からわかるように「クリティカル率」を「必殺率」に変えた点。

見た目変更前:
view_change_before.png


見た目変更後:
view_change_after.png




ユーザと開発者の仕様の変更のやりとりはこんな感じ:

ユーザ「もっとステータス画面うまく表示できないですかね? クリティカル率って他のと比べて長くないですか?」

開発者「分かりました。クリティカルじゃなくて、じゃあ、同じような意味の必殺でいいですかね? 文字数もちょうどそろいますし」。

ユーザ「それでいいんじゃないですか」



で、実際にどの部分のコードが変更されたか。StatusViewDrawer クラスがこのステータス画面の見た目を描画してる。

変更前のコード:


public class StatusViewDrawer implements GameViewDrawer {

private GameManager gameManager ;

public StatusViewDrawer(GameManager gameManager ) {
this.gameManager = gameManager;
}

public void draw(Graphics g) {

...

Player player = env.getPlayer();

drawStringWithShadow(g, "攻撃力     " + player.getAttackPoint(), baseX + 20, baseY + 30);
drawStringWithShadow(g, "防御力     " + player.getGuardPoint(), baseX + 20, baseY + 60);
drawStringWithShadow(g, "命中率     " + player.getStatus().getHitRate(), baseX + 20, baseY + 90);
drawStringWithShadow(g, "回避率     " + player.getStatus().getAvoidRate(), baseX + 20, baseY + 120);
drawStringWithShadow(g, "クリティカル率 " + player.getStatus().getCriticalRate(), baseX + 20, baseY + 150);

drawStringWithShadow(g, "経験値 " + player.getEXP(), baseX + 20, baseY + 180);

int nextLvExp = env.getPlayer().getNextExp() - env.getPlayer().getEXP();
drawStringWithShadow(g, "次のレベルまで " + nextLvExp, baseX + 20, baseY + 210);
...
}
...
}



変更後のコード:


public class StatusViewDrawer implements GameViewDrawer {

private GameManager gameManager ;

public StatusViewDrawer(GameManager gameManager ) {
this.gameManager = gameManager;
}

public void draw(Graphics g) {

...

Player player = env.getPlayer();

drawStringWithShadow(g, "攻撃力 " + player.getAttackPoint(), baseX + 20, baseY + 30);
drawStringWithShadow(g, "防御力 " + player.getGuardPoint(), baseX + 20, baseY + 60);
drawStringWithShadow(g, "命中率 " + player.getStatus().getHitRate(), baseX + 20, baseY + 90);
drawStringWithShadow(g, "回避率 " + player.getStatus().getAvoidRate(), baseX + 20, baseY + 120);
drawStringWithShadow(g, "必殺率 " + player.getStatus().getCriticalRate(), baseX + 20, baseY + 150);

drawStringWithShadow(g, "経験値 " + player.getEXP(), baseX + 20, baseY + 180);

int nextLvExp = env.getPlayer().getNextExp() - env.getPlayer().getEXP();
drawStringWithShadow(g, "次のレベルまで " + nextLvExp, baseX + 20, baseY + 210);
...
}
...
}




考察:

この要求変更の場合、運よくコードへの変更は、一つのクラスの一つのメソッドだけが対象となっている。でも、場合によっては、複数のビュークラスを変更しなければならない場合もある。現実的にはありえないけど、たとえば、次のコードのそれぞれの行に対して、クラスを割り当てている場合など。



drawStringWithShadow(g, "攻撃力 " + player.getAttackPoint(), baseX + 20, baseY + 30);
drawStringWithShadow(g, "防御力 " + player.getGuardPoint(), baseX + 20, baseY + 60);
drawStringWithShadow(g, "命中率 " + player.getStatus().getHitRate(), baseX + 20, baseY + 90);
drawStringWithShadow(g, "回避率 " + player.getStatus().getAvoidRate(), baseX + 20, baseY + 120);
drawStringWithShadow(g, "必殺率 " + player.getStatus().getCriticalRate(), baseX + 20, baseY + 150);



このことからは、モジュール(この場合はクラス)を分割しすぎると、変更がしにくくなるかもしれないことを意味する。

また、ビュー以外のコードも変更になるかもしれない。

view_code_change.png

コード進化パターン:Viewコードの変更

3年以上前から続けてる「Java におけるコード進化パターン」を更新。今回は、「Viewコードの変更」を追加してみた。

このパターンを簡単に言えば、いわゆる Model-View-Controller (MVC) のビューに関するコードを変更するということ。

今までと同じように、下の図では一般化して表してはいるけど、昨日プログラミングしているときに実際に出くわした変更(進化)のパターン。

change_view_code_before.jpg



言うのは、簡単に見える。でも、色々と疑問はある。

まず、「Viewコードの変更」ということで、View の存在を仮定してる。正確に言えば、View というクラスではなく、View という役割(ロール)を持ったクラスが存在することを仮定してる。

View の役割がどこからでてきたかといえば、既に書いたように、MVC における View を指している。

したがって、この「Viewコードの変更」は、MVC (アーキテクチャ)パターンが適用されてることを前提にした進化パターンなのかということになる。

そうすると、MVC が適用されてるかどうかを どこまで厳密に 前提とするのかが問題となる。

そのため、僕は POSA 本と PoEAA 本を見てみた。

MVC のようなアーキテクチャパターン限らず、あるアーキテクチャ・デザインパターンが適用されているのか(したのか)を判断することは、人手でも難しい。通常、パターンの記述に、あるパターンの全てのバリエーションを書くことはできない。

MVC も同様で、どこまでが MVC かを判断することは難しい、と思う。たとえば、POSA 本では、MVC の実装するとして、Publisher-Subscriber デザインパターンを用いている。しかし、僕が「Viewコードの変更」を行ったときの設計・実装では、Publisher-Subscriber は適用していない。


また、場合によっては、View と Model が分離されていないかもしれない。その場合は、もう MVC とは呼べないかもしれないけど、別の見方をすれば、あるクラスは Model と View の二つの役割を持っているともいえるかもしれない。とすると、「Viewコードの変更」パターンは、MVC 以外でも存在することになる。


一つ目の疑問をまとめると、ある進化パターンを表現する場合、どんな前提を置くかということになる。


二つ目は、「Viewコードの変更」パターンの "Viewコード" の部分。書き方としては、view メソッドとも書けたかもしれない。でも、コードとしたのは複数のメソッドを変更する場合があったかもしれないため。



FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。