ここしばらく POSA 本 を片手にアーキテクチャパターンを再勉強して記事にしています。アーキテクチャパターン Blackboard の記事ができたので紹介します。

八角研究所 : POSA 本でアーキテクチャパターンを勉強しよう(4) - アーキテクチャパターン「混沌から構造へ」より「Blackboard」
http://www.hakkaku.net/articles/20080825-262

過去の記事は以下の通りです。

■ 上記連載の趣旨

アーキテクチャパターンはシステムの基本となる構造を定義するための大規模なパターンです。デザインパターンのようにシステムの部分的な設計を支援するものではなく、システム全体の構造を対象にしています。

アーキテクチャレベルの判断は、部分的な設計判断よりリスクが高いことが多いわけですが、その割にはなかなか勉強する機会がありません。

そこで、アーキテクチャ設計を勉強できる数少ない本の一つであるPOSA 本 を片手にアーキテクチャパターンを勉強するための記事を書いてみることにしました。

しかし、パターンに対するイメージはさまざまです。構造を重視しすぎるあまり、「実際の開発で導き出される設計と何か違う」という理由で忌避する人がいることも事実です。パターンの紹介記事の中には、構造や実装のみを紹介することで、こうした傾向をあおっている節もあります。

# 小難しいから回避する人もいますが。。。

本当はパターンは、「なぜそのような設計判断をするか」「どのようなときにその設計を用いるのか」など、意思決定のプロセスを残し、あるいは読み手が学習するためのものです。本記事では、わかりやすさは重視しながらも、できる限りパターンのメリットを殺さないように書くことを心がけています。

Posted by あかさた
ここしばらく、POSA のアーキテクチャパターンを再勉強しているわけですが、前回のLayers に引き続き、Pipes and Filters の記事を書きました。

八角研究所 : POSA 本でアーキテクチャパターンを勉強しよう(3) - アーキテクチャパターン「混沌から構造へ」より「Pipes and Filters」
http://www.hakkaku.net/articles/20080724-252

Pipes and Filters は、普段の開発で採用することは少ないかも知れませんが、利用者に回ることが多い仕組みなので、しっかりと仕組みを抑えておきたいものです。


Posted by あかさた
ここしばらく、POSA のアーキテクチャパターンを再勉強しているわけですが、第一弾として「Layers(レイヤ)」について記事を書きました。以下をご参照ください。この記事ではウェブアプリケーションの世界(主に Rails)を意識して書いているので、ウェブ系の人でも比較的馴染みやすいのではないかと思います。

八角研究所 : POSA 本でアーキテクチャパターンを勉強しよう(2) - アーキテクチャパターン「混沌から構造へ」より「Layers(レイヤパターン)」
http://www.hakkaku.net/articles/20080630-227

Java EE 勉強会でもアーキテクチャに関する議論はされているみたいですが、POSA や PofEAA あたりが共有言語となっている雰囲気があります。この辺を理解して積極的に議論に参加していきたいものです。

Posted by あかさた
ここしばらく、技術に関しては目先の視点での勉強ばかりをしていました。やれ Ajax だの Flex2 だの Comet だのという感じです。当然技術的には奥行きのない世界です。結局、Document-View(MVC の一種)な構造をもったアプリケーションをどううまく書いたらいいのかとか、インフラの状態と相談しながら通信の粒度をどのように決めていくかとか、本質的なところを考えなくてはなりません。

こうした設計の基本的な事柄を考える能力というものは、オブジェクト指向原理主義的なものを抜きにしても、エンジニアの基本的な体力の一つであると感じます。しかし、昨今のネットを見ると、そういう記事がない・・・というより、記事はあるのですが浮かんでこないという問題を抱えているように感じます。また、記事や知識は断片化していて、ある文脈をもった人たちの間でしか共有できていません。

一朝一夕に何とかなるものではありませんがまずは自分で勉強して記事を書いてみようかと思います。

まずは、アーキテクチャを勉強します。マーチン・ファウラーの PofEAA(エンタープライズアプリケーションアーキテクチャパターン)のように著名なフレームワークに実装例を探すことができる本を再読することも考えましたが、ここは一つそろそろ古典の領域に入りますが名著として名高い POSA 本(ソフトウェアアーキテクチャ―ソフトウェア開発のためのパターン体系)を読み直してみることにしました。

冷静に考えればこの本を読んだのは大学 4 年の時です。当時この本の良さを理解できていたとはとうてい思えません。今読んだらどのような知見を得られるのかわくわくしています。

・・・というような、需要があるかどうかわからない記事を書いても怒られないのか心配ですが(一応記事そのものは仕事として書いているので)、これから 2 ~ 3 ヶ月かけて POSA 本を勉強します。

POSA 本でアーキテクチャパターンを勉強しよう(1) - パターンとは何か?
http://www.hakkaku.net/articles/20080603-215

本に登場する例は少し古さを感じなくもないので、適用例の紹介はできるだけ最新の流行を反映したものにしたいと思います。設計を勉強したいという方は、ぜひおつきあいください。


Posted by あかさた
八角研究所にて、AutoPagerize と LDRize などのユーザスクリプト(GreaseMonkey スクリプト)を例にあげつつ、「ウェブアプリの使い勝手の一部は単体のモジュールとして開発されるようになったた」「ウェブアプリ開発はこれからどうすべきか」という趣旨で記事を書きました。

八角研究所 : ユーザインタフェースとアプリケーションは分離する
http://www.hakkaku.net/articles/20080417-189

ついで(?)に、サイトを AutoPagerize と LDRize に対応させるまとめもコラムとして載せてあります。

Posted by あかさた
ソフトウェア技術者がどっかの段階で覚えなきゃいけないことを読んで思ったのは、広場っぽいカラーが出てていいなぁと思いました(笑)。私の結論は以前書いたとおり、自分の目指すところに合わせてポートフォリオを組んでくださいということですが、この考え方を使ってソフト(Kodougu)を組んだばかりなので、いまさらですが再考します。

ソフトウェア技術者がどっかの段階で覚えなきゃいけないことより

ソフトウェアにはメタな構造があって、さらに根源のところでは自己記述っぽい形でぐるぐる回ってるというイメージを持つ事じゃないかなーと思う。これはソフトウェアの本質そのものなので、知っておいて損は無いはず。


例に挙がっている Lisp なら、Pure Lisp の言語仕様と car/cdr に注目してもいいと思います。より、シンプルで本質的です。ちょっと視点は変わりますが、Ruby で DSL を作った Rails がなぜ流行るのかも考えてみるとよさそうですね。

マシン語だって、高級言語からアセンブリ言語、そしてその命令がスーパーパイプラインでどのように処理されているかというような階層を知れば、意外とそういう理解を得ることも可能なんじゃないかなという気がします。それに、知れば知るほど、深く掘れば掘るほどシンプルで要素分解できるというほどわかりやすい世界でないことがわかります。Pentium4 が出た時は、CPU は神のお告げで命令の実行順を決めているなんて言われたもんです。(μOP、分岐予測あたり。)言うまでもなく、shi3z 氏はこの手のことくらいは熟知していると思います。

確かにこの手の知識は必須じゃないのですが、その割にこの手の知識を知っている人には技術的に「骨のある人が多い」のも事実なんですよね。なんでだろ。

さて、メタ階層的な話に戻ります。Kodougu は UML の抽象構造であるメタメタモデル(UML Infrastructure)をいくつか改造して実装しています。メタモデルはデータで表現されています。適切な例かわかりませんが、クラスとオブジェクトの関係が、メタメタモデルとメタモデルの間に表現されています。メタモデルのデータをもとにコードを生成して、クラスとオブジェクトの関係をメタモデルとモデルの間に構築しています。そのため、Kodougu はモデリング言語を設計することができるのです。また、メタ階層的な考えで実装しているため、Kodougu のコードはサーバは 4000 行(Wiki とか余分な機能が含まれていますが)、クライアントは 2000 行で書かれています。この種のアプリの一般的なコード量は十万行から百万行程度になりますから、ずいぶんスリムです。

この手の設計思想のメリットは、初期の開発コストはそこそこ高いですが、ソフトウェアの規模が小さいため、保守コストが小さいことでしょう。デメリットは、このメタ階層が処理できない問題にあたると、どうしようもなくなるか、途方もないコストがかかる恐れがあることでしょう。そういう意味では、もっとももメタな部分の設計/実装センスが問われてしまうので、リスクを取ってでもやりたいという強いモチベーションが必要です。(ここでいうセンスは別に先天的なものを意味しているつもりはありません。音楽やスポーツに要求される”才能”とは違う気がします。)

それがアーキテクチャ設計の宿命だといえばそれまでなので、エンジニアとして生き残っていきたいのなら、この種の能力は必須かもしれません。

お、スラドでも話題になっているようです。さすがにスラド、割りとガチでテクニカルに議論している気がします。

Posted by あかさた
何人かにはお話させていただきましたが、Kodougu の IE 実装は Firefox の 1/10 位の速度です。通信による遅延と思っている方も多いようですが、インターネット上でも Firefox ではそこそこ軽快に動作します。

Kodougu の IE 実装がしょぼいからですが、VML のような先があるのかどうなのかわからない技術のパフォーマンスをチューニングするのは、なかなかモチベーションが上がりません。そこで、Silverlight を使おうかと考えています。おそらく、今後の IE 上のリッチなコンテンツは Silverlight に収束していくでしょうし、新技術との格闘なら私のモチベーションも上がりそうです。(私が Flash にしない理由は・・・Silverlight のアーキテクチャを調べてください。)

とはいえ、パフォーマンスの問題、既存の Kodougu の実装との整合性など問題は山積みです。そもそも実装できるのかどうかすらわかりません。年内リリースを目指して実装していくつもりですが、当面は調査を行います。

Posted by あかさた
複雑な GUI を持つアプリケーションの設計について(Web アプリ編)を書いていたときに見ていた本は POSA 本だったのですが、以下のエントリでも同じようですね。

Flex2におけるアーキテクチャパターン @ 2007年08月 @ ratio - rational - irrational @ IDM

少なくともPACでいうAgentの開放/閉鎖は意識したほうがよさそうで、それだけでもイベントでワケワカになるのはかなり解消できます。


続報を強く期待します。Flex2 の固有事情とかもありそうです。

PAC で対処しやすい問題と対処しにくい問題があるから、その辺をどう考えるかですね。私はモデリングツールの開発経験が多いのですが、この種のアプリでは、構造ツリーとダイアグラムウィンドウという大きな枠組みがある場合が多いです。こういう大きな枠組みがあると、その単位で Agent を認識できるので、PAC の適用可能性が高く、スパゲティ対策に有効に働きます。

問題は、PAC が対応していない複雑性をどう制御するかでしょうか。たとえば、GUI アプリの状態やモードによって、中間レベル、下位レベルの Agent の枠を越えたアプリの制御を行わなくてはならなくなる場合があります。こういう場合、より上位の Agent に記述しますが、結局そのレベルの Agent の肥大化を招くことになります。これは、フォームやウィンドウのサブクラスを実装するタイプの開発スタイル(VB、Delphi 型)でよく遭遇します。

で、まだ整理されていないようですが、上記エントリに書かれているイベント翻訳(この言葉、知りませんでした。例外翻訳は聞いたことがありましたが。)や Command の適用などの話が出ていますから、その辺に対応策がありそうです。どういう解決策があるのか楽しみですね。

所詮さじ加減といわれるとそれまでですが・・・。(^^;

Posted by あかさた
以下のようなエントリを見つけました。非常に良い問題意識です。そう、GUI プログラミングは泣けるほど面倒くさいのです。

subtech - Pink Blossom Diary - AS3/Flex2 を使い始めて約半年より

まずイベントドリブンなプログラミングに慣れてないのが一つで。Flex のイベントや自前イベントやをただ単に投げまくってると、とりあえずは動くけど後からメンテし辛いスパゲッティコードができあがる。このスパゲッティコードは goto 文が乱立するコードよりも酷く、goto だったら割と行き先は把握できるけど、イベントを投げまくってるだけだと、どこでどのオブジェクトがこのイベントを受け取るかが解らない。解りづらい。いちいちソースコード grep ですね、おめでたいですね。あのイベントが発生してから、そのイベントが終了したら発生するイベントが終了したらウィンドウ閉じて、その間は別のイベントはブロックして/発生しないようにして、とかもうわけわかんない。これも GUI プログラミングをしたこと無いからのような気もしなくもないけど。


もう、このエントリは素敵すぎです。GUI のいやらしさをよく表現しています。しかし、残念ながら、C# + Windows.Forms を使おうが、Java + Swing を使おうが、Delphi + VCL を使おうが、そのスパゲティから逃れることはできません。

なぜ、C# や Java でもこの問題から逃れることができないのか、考えて見ましょう。確かに、Form や Window を継承したクラスにイベントハンドラを追加していくスタイルは、一見すると、わかりやすくて簡単です。でも、何の指針もなく開発を進めていくと、イベントハンドラに、UI の状態管理、アプリの処理、UI の見た目管理などの処理が混ざることになり、結局、Form や Window を継承したクラスはスパゲティになります。

言い換えると、Web アプリは、MVC2 を採用したフレームワークにしたがって書けば、関心ごとがそこそこ分離され、わりと綺麗に書けます。でも、GUI プログラミングの場合、フレームワークに従っても、複数の関心ごとを分離してはくれません。開発者は自衛する必要があります。また、関心ごとの分離という意味では、JavaScript でも、スタンドアロンアプリでも本質的に同じ問題を抱えています。

では、どうすれば、このいやらしさから逃れられるか考えて見ましょう。

(0) 前提

複雑な GUI アプリの場合のアイディアを書きます。一応、Web(Ajax とか Comet とか絡みそうなもの)を前提にしています。

(1) UI の状態は抽象化しよう

UI の状態を抽象化します。vi みたいにモードを作ってもいいです。

GUI アプリでは、特定の作業をしているときに、特定の入力を排除するようなことがあります。保存中に全ての入力を排除するとかですね。どの状態(モード)のときに、どの View 部品が、どのイベント(キーとかマウスとか)を受け付けるか、わかりやすく定義できるような抽象化が望ましいです。View 部品は構造化しておくと、粒度に応じた管理が出来るようになります。

また、UI の状態遷移図を書いて整理して、状態遷移を実現するフレームワークを書いて抽象化してもいいでしょう。State パターンですかね。サーバと通信があるなら、それも考慮した状態管理を行いましょう。

Kodougu ではこの辺の手を抜いていて、関係線の作成中に Del キーを押したりするとちょっと変な動作をします。

(2) イベントハンドラは UI の状態管理だけを行おう

イベントハンドラにアプリの処理を書かないようにしようということです。画面描画に関わるような処理も書かないようにして、UI の状態管理に徹させることです。イベントハンドラは UI の状態に応じて、別のクラスか関数に書いたアプリの処理を呼び出しましょう。

(3) 必要ならアプリの処理と UI の変更処理は分離しよう

ここで言う UI の変更処理とは、たとえば、チャットの場合、ユーザーの発言を受信したら画面を書き換えたりするようなことです。特定の UI の状態で、ボタンを disabled にするような処理は別です。そういう処理は、状態管理で考えてください。

アプリの処理とは、チャットなら、クライアントで発言ログやログインユーザを管理したりするような処理です。

以下のケースなら、アプリの処理と UI の変更処理の分離を検討した方がいいです。当てはまらない場合は行う必要はありません。
1. アプリの処理と UI の変更処理が一対一でない場合
2. アプリの処理と UI の変更処理が同一のイベントで処理できない場合(画面への反映はサーバの応答待ちとか)
3. サーバの処理とクライアントの処理の境界があいまいな場合(Web なら、HTML の組み立てをサーバでやるか、JavaScript でやるかあいまいなとき)

(4) 必要ならアプリのモデルを定義しよう

Web アプリの場合、サーバにはしっかりとしたモデルクラス(社員クラスとかね)があるかもしれませんが、JavaScript にはそれはないかもしれません。サーバとは異なるモデルかもしれませんが、クライアントにモデルが必要になら、ちゃんと定義しましょう。Kodougu(Web 上で動作するモデリングツール) は、クライアントにもモデルを定義しています。

(5) アプリ処理、画面変更、サーバとの通信の順序を決めよう

そのままです。機能ごとに上記の順序が変わるとわかりにくいので、決めた方がいいです。

とりあえず、こんな感じかなと思います。私はまだまだ、JavaScript については経験不足です。Kodougu も JS の部分は、2000 行位しかなく、小さなものしか作ったことがありません。

■ 追記(2007/8/14 4:53)
GUIプログラミングのパターンが知りたい : akiyan.com

イベントドリブンでステートフルなGUIプログラミングには、いわゆるWebサーバーアプリーケーションでの抽象化経験は全然役に立ってる気がしません。むしろ余計に感じたりします。


無駄になるということは無いと思います。要は関心ごとの分離ですから。ただ、フレームワークを「使う」Web アプリ開発と異なり、複雑な GUI アプリはフレームワークを「作る」ことになるという違いはあります。たしかに、Rails アプリを作るように、複雑な GUI アプリを作ったら自滅しますね。そういう意味では、上記の余計に感じるという表現は非常に示唆に富んだものだと思います。

Posted by あかさた
Rails を使ったアプリに限った話ではありませんが、ファイルをアップロードする機能を Web アプリにつけたときに、ファイルを DB に入れるか、Web サーバにファイルを保存するかについてです。

私は Web サーバに保存すべきと考えていました。Web サーバとアプリケーションサーバ(Rails のサーバ)を分けている場合、静的ファイルはWeb サーバが処理して、動的コンテンツはアプリケーションサーバが処理してというようなことをする場合があります。DB に入れると、アプリケーションサーバを経由しなくてはならないので、こうした構成が取れなくなります。ただ、Web サーバを複数台にする場合、ファイルアップロード時に全ての Web サーバにファイルをコピーする手間がかかるというデメリットがあります。(バックアップの手間も一手間増えます。)

もともと私は、DB に静的コンテンツをいれると、Web アプリのレスポンスが遅くなるという問題が発生すると考えていました。ただ、この問題は Rails のキャッシュ機構を使えばある程度回避できます。この場合、静的コンテンツも全てアプリケーションサーバが処理することになります。それぞれのサーバが DB からファイルを取り出してキャッシュをするので、ファイルの管理は楽になります。

もっとも、動画アップロード&配信サイトとか、データ量が多い場合は、ファイル置き場とアプリケーションサーバは分けざるを得ない(ストレージにも IO にも問題が発生する可能性があるので)ので、この方法はとりづらいですが。

所詮はケースバイケースですが、一つあたりのファイルがそれほど大きくなくて、ファイルの総容量が 100GB 以内に収まるのなら(最大容量は適当)、DB に入れるというのもアリかなと思うようになりました。Kodougu では、アイコン画像などがアップロード可能なのですが、今は DB に入れています。

Posted by あかさた