[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[jfriends] Re: CADのクラス構造
> CADでは、形状を沢山表現しなければなりませんから、Shape
> という抽象クラスを作ります。この Shapeは、何らかの
> Collection に突っ込むとしましょう。
>
> で、Shapeを継承して、Lineとか、Rectとか、Arcとかいうク
> ラスを作るとします。
:
> ということは、どこかにdraw() というメソッドを作ることに
> なるわけですが、それはどこに作ればいいのでしょう?
議論がすでに進んでいますが、以前、C++でこのようなアプリを
作った経験をふまえて、、、、
##########
1. Shape に abstract draw()を設ける
・素朴で素直な設計。わかりやすい。
・保守フェーズでdraw()の引数変更があると
(描画モードの追加やプリンタ印刷追加等)
修正箇所が分散していて大変。
※各図形クラス毎に1ソースファイルの構成の場合。
※各図形のdraw()メンバ関数の実装を1つのソースファイルに
まとめておけば良いが、これはC++で可能でも、
Javaではできませんね。
###########
2. 外側(描画キャンバス)に draw(Shape) を設ける
・多対1の Model/View構成であり、奇麗に役割分担ができる。
・保守フェーズでの機能変更に強い(と思われる)
・draw(Shape)の中が instanceof の羅列になるのが
気に入らない。
・draw(Shape)に対して、各Shapeの詳細情報(メンバ)アクセスを
許す必要がある。C++なら friend 宣言、Javaならパッケージスコープ。
###########
3. 各 Shape に対応した View を設ける
interface Drawer { public void draw(); }
class Line extends Shape {}
class LineView implements Drawer {}
・1対1の Model/View構成であり、奇麗に役割分担ができる。
・保守フェーズで引数変更があると、1と同じく面倒。
・各Viewに対して、各Shapeの詳細情報(メンバ)アクセスを
許す必要がある。C++なら friend 宣言、Javaならパッケージスコープ。
############
4. 各 Shape から派生して、Drawerインタフェースを実装する
interface Drawer { public void draw(); }
class Line extends Shape {}
class LineDrawer extends Shape implements Drawer {}
・1の変形。奇麗に役割分担ができる。
・派生クラスに対して、各Shapeの詳細情報(メンバ)アクセスを
許す必要がある。protected またはパッケージスコープ。
C++でアプリを作ったときは3.だったのですが、
保守フェーズでは、多少みっともなくても 2.にしておけば
良かったと何度も思いました。
Javaで組みなおす機会があれば、4が良いかなと思っています。