デザインパターン

まえおき

個人の趣味なんてどうでもいいとは思うが私はデザインパターンが嫌いである。
なんだって他人の考えたデザイン案をいちいち勉強して適用しなければならないのか、と駄々をこねてみたりする。
いわゆる確立されたデザイン案というのはグループでの開発において、「こういうパターンで行くから」と言えばグループ全体がデザインパターンを理解していれば、イメージの共有がしやすくて効率はいいと思う。
ただ、オープンソースの世界や個人での開発は、その場その場で最適なものを考えていけばいいだろうと。
優れた設計案のお勉強で人のを参考にするのもいいが、考える力を奪われるのは楽しくない。
結果的にそのパターンを適用していた、というのが、私が設計する上では一番理想的な形である。だからデザインパターンも大して勉強してない。
ちょっと少数派かもしれない、と認識した上で書くとしよう。

WitchPaperとOrdinaryPaperを考える

前の日記でDirectX描画とGDI描画を分ける場合に継承しちまえば楽だろうという話を出したが、こういう事を言うと決まってうるさい事言う人がいるので事前に検討しておこうという話。
どうもWitchPaperとOrdinaryPaperの設計案は「Template Method」パターンを適用している気がする。
で、ここで指摘されうる事は描画部分を継承じゃなくて委譲にした方が、WitchPaperを使用するフォーム側がやりやすいんじゃないかい?ということ。
描画エンジンを作るごとに丸ごと継承しないといけないんでは非効率すぎるという指摘は覚悟するべきだろう。となれば当然、描画エンジンを委譲した作りの方がスマート、となる。実にもっともな指摘だ。

委譲型の案

で、描画エンジンごとに作り分ける方法を、まずはデザインパターンを無視して適当に考える。
現在WitchPaper関連の描画メソッドは「InitializeGraphics」、「render」、「renderLines」、「renderSelectArea」の四つである。
InitializeGraphicsはデバイスの初期化、renderは全描画、renderLinesは線描画、renderSelectAreaは選択領域の描画。文字描画はrender内に格納されている。
この他、OnPaint時にMicrosoft.DirectX.Direct3D.Device.Presentメソッドのコールのみもやっている。バックバッファの内容を画面に反映、という処理のつもり。
問題は委譲するに当たって、「render」メソッド内でWitchPaperの内部データを参照している箇所をどう扱うか、である。
で、これらのメソッドは文字列分解とかもしているので、現実問題このメソッド単位で分離するのは難しい。
ではいわゆる画面に描画する情報の取得と、画面描画部分を分離させればどうかという話になる。
画面描画のみを分離させるとなると、今度は対象が以前挙げた「BitBlt」、「LineTo」、「TextOut」の三つに、前述の「Present」と将来的な改行記号等の描画用に「DrawImage」辺りがあるといい。
これにインターフェースをかませばいいのだから、こんな感じだろうか。オーバーロードは適当にどうぞ。

public interface IWitchDrawer {
 void Init();
 void DrawSelectArea(Rectangle[] selectRects);
 void DrawLine(Point start, Point end);
 void DrawString(/* 引数多いので略 */);
 void DrawImage(/* 引数多いので略 */);
 void UpdateScreen(bool isSync);
}

引数はあまり検討してないので細部は変わるだろう。Initは多分やっとかないとまずいので一応。多分BeginとEndもないと遅くなる。
その他は特に記述する必要ないと思うが、このインターフェースを実装したDirectXDrawerとGDIDrawer辺りを作って呼び出し元で変えるようにすれば、スマートになることはなる。
デザインパターンだとこれはStrategyになるのだろうか。
外してたら申し訳ない。

いやいやそもそもという人々のために

いやいや、そもそもGUI部品ってのはさ、部品に対するアクションと、それに応じたロジックで実装されるべきなんだよ。
だから本来テキストエディタ自体を○○パターンで作るべきで、ロジックの実装に各種デザインパターンを適用した作りにしないとダメだよ。
なんてのたまうStrutsかぶれに一応説明しておこう。
WitchPaperの設計はおざなりで、テキストエディタというものを強引に作りにかかっていたから仰るように検討不足でした。申し訳ございません。
ただスマートな作りにした場合に処理速度が確保出来るか、その作りに束縛されないかという懸念があったので、あえて一クラス一極集中でいったんです。粗雑な作りでごめんなさい。
ようやくノウハウも蓄積されたし、速度の目処も立ったから、余力あったらちゃんと設計から起こしますんで、その時の対応ということでよろしくお願いします。余力はなかなか確保出来ないと思うんで、貴方様の方でリファクタリング実施していただいても構いません。そのためのSourceForgeですから。

で、結局どうすんの

まあ、GDI対応することになったら考えるとしよう。
エンジン部分分離してもいいが、要するに今更WitchPaperにスマートさなんて求めても仕方ないということで、エンジンだけスマートにするくらいなら一から作り直すかもしれない。で、一から作り直すくらいなら継承してコピペですますのが楽チンだし、暫定対処としては十分だろうとは思っている。
WitchPaperを一から作り直したいという話は以前からしているのだが、正直9月末という期限を考えれば厳しいだろう。
やるならその後だが、テキストエディタの作成は正直うんざり気味なので、他のやりたいことを片付けてからとなれば、一年後くらいにどうするかちゃんと考えるとしよう。