kr_ryo 徒然日誌 <2006年5月14日分>

三國志製作記139〜あれ?デザインパターンは解決策か?〜

もう5月、6月なんて蒸し暑いが枕詞なんで5月は暑いから上着もいらない!と思っていたのに、また寒くなってきました{(>_<)}三寒四温はすぎたかと思いきや、実はまだ続いているのかもしれません。5月といえば心ともども風邪をひきやすい季節、みなさま元気に参りましょ〜(^O^)

さて、シミュレーション的自由であることから自由になった三國志製作、シミュレーション的制約、つまりルールの中でゲームをするということが、いかにおもしろいかがよくわかりました(^O^)あくまでゲームなんです。なんでもかんでも自由にすればいいってもんじゃあありません。手が使えないからサッカーはおもしろいんです。倒せばいいだけだから曙は強かったんです、ってそりゃいかんか(*_*)

それはともかく、一気にルールを再設計、あっと言う間にそれっぽいものができあがりました(^^;;そりゃあ、なんでもできる自由とするなら、ルールなんてできません。制約があっても良い、むしろ制約を厳しくするべきだ、という視点であれば、少ない行動でいかにうまく天下を治めることができるか。これこそがゲームの醍醐味なんです。

と、いうことでルール問題は解決、再びプログラムに戻ることになります……あまりに久々なんでなんだかよくわからない感じかな〜(~_~;)と、思いきや、さすがオブジェクト指向、重要なオブジェクトが決まっているので、だいたいつかむことはでき、そして…そして、もはや新しいルールとそぐわない部分でできあがってるものもたくさんあるということに気がつきました(ToT)これだから、ルールが中途半端な時点で作ると危険ということなんですよね〜!他に影響を及ばさず不要部分変更部分を消す、これがたいそう難しい。作り替えた方がましだ、というのがこれまででした。

はや4度目の作り直しか、と思いきや、さすがにオブジェクト指向で作ったプログラム、いらない部分だけを切り分けてばっさりいく、という作業はこれまで以上に楽です(^-^)なんといってもオブジェクト指向最大の利点であるのがカプセル化。あるオブジェクトの中身がどうあれ、それを使う側は、○○やってね、という指示を飛ばすだけで済んでいるわけですから、いらないオブジェクトと、使う側の○○やってね、という指示部分を消すだけですむのです。

ただ、オブジェクトの中でのさらにそれだけが使っている別のオブジェクトなど、深みはあります。「このDLLはどのプログラムからも使われていません。削除しますか?」という感じの指示に似た気もしつつ、まあ、作った方が他から使わないよな、と思いながら切っていきます。もっとも、オブジェクトが使うオブジェクトが使うオブジェクトが使うオブジェクト、とかになると、見つけられないと残ったまま使われないでメモリの無駄になります。将来的には見つけて消さないといけないんでしょうが、あまりに多いと困ったことになります。

ここで問題は、オブジェクトがオブジェクトを使うということより、あまりにオブジェクトの関係が深すぎるといことにあるんでしょう。オブジェクト指向とデザインパターンの教科書である『オブジェクト指向のこころ』によれば、3階層より以上のオブジェクトの深みを持たせてはいけない、といわれますが、こういうところで影響があるんですなあ〜!確かに困った感じはあります。深すぎて見通しが利かない。今後の検討課題ですなあ〜!!

とか思いつつ、さて、新たに作り直そうと思いつつも、どうもキーが進まない。なんでかいな?と思うところ、どうも新しいルールに従ったコマンドを中心に作ろうとしていて、それは機能分解という、オブジェクト指向以前のアプローチだと無意識に気がついたからみたいです。

実は、今回消されたオブジェクトなどは、コマンドを実現するための内容だったりします。消されなかった部分も、結構コマンドを実現するための内容であるものもあり、機能分解タイプであることが滲み出ています。逆に、武将やなんかの、自分で動く機能をそなえたオブジェクトなどの部分は、この変更にも柔軟に対応できそうな感じではあります。

しかし、武将が行動をする、ということを実現するためのオブジェクトなどは、次から次へと直列でオブジェクトを並べる感じで、直列すぎて、途中を変えるわけにもいかず、先程のようにばっさり切るしかなくなるんです。これに対し、武将オブジェクトそれ自体は、城などのオブジェクトと並列で、かつ、武将オブジェクト単独であれこれできるなど、並列の関係に近いんです。並列なので、ある列を改良しても他の列には影響が少ないか、ないんです。

と、難しいですね(*_*)たとえば、武将の情報を表示したいとして、武将オブジェクトに「情報表示」という命令を送るだけで、武将オブジェクト側が対象武将データを呼び出し、画面オブジェクトにそのデータを表示させるよう命令を送る、画面オブジェクト側がそのデータを表示する、というのが、正しい?オブジェクト指向だとします。

これに対し、情報表示オブジェクトというのがあって、これに武将情報表示オブジェクトが継承やなんかで作られている、と。そこに情報表示オブジェクトに表示命令が出て、表示する内容が武将情報なんで、武将情報表示オブジェクトを選択して対象武将データを送り返してもらう、と。情報表示オブジェクトは共通情報表示命令を呼び出してそのデータを送ります。

ここで、実は情報表示オブジェクトは武将オブジェクトと同じことをしています。しかし、情報表示オブジェクトの方が非常にややこしい感じがしませんか?実際ややこしいんです。武将オブジェクトを基本に考えると、武将の情報表示だろうが武将移動だろうが、戦争だろうが、武将のなんとか、という機能を使う、というだけでしかありません。ところが機能を中心に考えると、情報表示オブジェクトと、武将情報オブジェクトと城情報オブジェクト…、移動オブジェクトと、武将移動オブジェクトと軍団移動オブジェクト…、戦争オブジェクトと、味方が関係している戦争オブジェクト、敵同士戦争オブジェクト…、という感じで、とにかく細かく細かく増え続けます。

これが機能分解のワナです。一度機能分解しちゃうと、機能ごとにオブジェクトが増え続けます。機能同士を統合しようとしても、機能の対象ごとにどうしても分かれたくなります。情報表示、という機能オブジェクトが、武将情報、城情報、ある城にいる武将情報、ある武将がいる城情報…という感じにわかれたくなるんです。ここでは統合元の情報表示オブジェクトは、中身がなく形骸化するか、八面六臂の大活躍=いろんな場合分けをしまくるか、どちらかなんです。

これに対し、武将オブジェクトの情報表示機能、城オブジェクトの情報表示機能、と作り込んでおけば、別の、リストオブジェクトが、表示する際にそれぞれのデータを呼び出すことで、すっきりします。城にいる武将情報だろうが、武将がいる城の情報だろうが、単なる組み合わせにすぎません。

と、ほとんど同じことを言っているように見えますか?ほとんど同じことを言っています(^^;違いは、何を主に置くか、ということだけなんです。機能を中心に置くと、細々になりやすく、変更に非常に弱いんです。ある機能のちょっとした追加が、ある機能を構成しているオブジェクト全部をだんだんと更新していかないといけなくなります。今回のように、仕様の変更によって、まるまる全部そのシリーズを消すことにもなります。

それを、武将や城など名詞オブジェクト中心に構成していけば、そんなことにはなりませんよ…というのがかつてのオブジェクト指向でした。しかし、この発想は、私のなぜ?という疑問に答えられませんでした。先程、ほとんど同じことを言っているというのと同じ、というように、名詞オブジェクトの中の機能メソッドが、新たに作られた機能オブジェクトシリーズを呼び出しているんだったら同じだ、ということなんです。

私自身がまだわかりきってないので非常にわかりにくい文章になってますが、この解決策のひとつがデザインパターンのようです。オブジェクト指向だけでは足りず、デザインパターンを用いてこそ、変更に強いプログラムになる、と。

これすらそれだけじゃあ???とは思うんですけども(--;)無理を承知でどうしてそうなのか検討してみましょう。デザインパターンでは、プログラムされるべき内容(問題領域)から、名詞を取り出してオブジェクトに、機能を取り出してメソッドに、というような単純で思いつきな方法を取りません。プログラムされるべき内容(問題領域)に、各デザインパターンをあてはめて解決できる部分にあてはめる、つまり、デザインパターンに「よって」設計し、プログラムしていく、ということなのです。結局、問題領域は各デザインパターンの組み合わせで表現でき、残った部分は問題領域固有の部分としてそこだけオリジナルでプログラムを作る、と。

たとえていえば、家を建てるのに、和風なら破風や縁側、洋風ならアーチや螺旋階段など、既存のデザインを組み合わせて設計するようなものです…(本当は、この建築の世界からデザインパターンが生まれたんですけどね(^^;)…既存の問題を解決する既存の美しいデザイン=デザインパターンを使って解決する、と。もちろんそのデザインの意味や意図を理解してなきゃ、不自然だったり何かがおかしいものになったりします。

つまり、優れて美しい既存デザインがあるんだから、それを使って設計しましょうということなんです。そうすることで、思いつきでデザインするよりも、はるかに変更に強く、使いやすいプログラムになる、と。

そして、既存のデザインパターンは、単に名詞を取り出してオブジェクトとし、機能をメソッドとして搭載していくというような方法ではなく、明確な意思と役割を持った内容であったりします。たとえばAdapterパターンは、変更できない別のシステムを新しいシステムに組み込む際に使います。まさにアダプター、接続のためのオブジェクトです。そんなものは、問題領域をいくら眺めても出てきません。……まあ、出てくることもあるかもしれませんが、普通は出てきません(^^;;

発想は非常に簡単です。システムとシステムとをつなぐオブジェクト、というだけですから。しかもつながれるシステムがどうであっても、Adapterオブジェクトがそのインターフェースを統一してしまう、さらにつながれるシステムをつなぐシステムから隠してしまう、カプセル化を図っているのです。つながれるシステムが変更されても、つなぐシステムに対しては、Adapterオブジェクトの該当部分を変えるだけで済みます。非常に便利になるわけなんですね。

ところが、そういうデザインパターンの存在を知らないと、そういうものがあったら便利だな、とか、思いつかない限り、問題領域からそうそう都合よく名詞が出てくるはずはありません。逆に、そういうパターンがあると知っているから、ふたつのつながり合わないシステムがあった場合に、Adapterパターンを使ってつなげればいいんだ、と思い浮かぶものです。さらには、この問題領域には、ふたつの独立したシステムがあることが問題で、Adapterパターンを使ってつなげればそれでおしまい、という発想にまでつながる、と。

さらには、デザインパターンすらすぐれてはいるが例示であって、その意図する、変わりそうなところをカプセル化したりだとか、単一の責任を持たせるだとか、そういうことができる設計になる、と。うーむ、わかっちゃいるけどそうできない?(T-T)何かがわからない、何かがひっかかる気もしつつ、もうちょっと考えてみましょう。

index

〔TopPage〕

このページへのリンクはフリーです。
このページについてのご意見、ご質問などは、kr_ryo_green@yahoo.co.jpまでお願いします。
Copyright 2006© kr_ryo All rights reserved.
訪問件数