[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が良いかなと思っています。