[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends] Re: データベースに格納するデータオブジェクトに持つ機能(Re: CADのクラス構造)




ああ、前半はゴミですが修正せずに送ってしまいます.

In article <9909020952.AA09624@xxxxxxxxxx>
Kazuya Maebashi wrote:
>>まず、LineRunTimeForDrawer等をShapeのサブクラスたちに関連付ける処
>>理が必要なわけですが、これを行うには結局、
>>if (shape instanceof Line) {
>>  shape.runtime = new LineRunTimeForDrawer();
>>} else if () {
>>}
>>みたいな事が必要になってしまいます.
>
>ええと、Lineのコンストラクタでくっつければいいかと思ってたん
>ですが(Javaのデシリアライザってコンストラクタ呼ぶんだっけ)、
>よく考えたら、Lineのコンストラクタが「draw()するアプリケーショ
>ン」に依存してはいけないですね。
>
>でも、オブジェクトを構築するアプリによって、くっつけるオブジェ
>クトを変えることぐらいは、手があると思うんですけれども。それ
>こそShapeRunTimeの生成インタフェースをグローバル変数渡しにし
>てでも。

Shapeサブクラスにfactory methodを用意する以外の方法で、Shapeサブクラ
ス群と一対一に対応するアプリケーション独自クラス(ShapeRunTimeサブク
ラスのサブクラス群)を生成するわけですよね.instanceofを使わずに可能で
しょうか?
Class#forName()でも使えば出来るでしょうけれど.

>>で、Shapeにメンバを持つ形だとその後Drawerを使う時に、
>>
>>(LineRunTimeForDrawer)(shape.runtime).draw();
>>
>>なんてしないといけないので、それなら、
>
>ダウンキャストは、(RunTimeForDrawer)shape.runtime
>まででいいと思うのですが、如何?

誤記でした.すみません.そのとおりです.

>これなら、少なくともLineかRectかという else if の山は書かな
>くてすみます。

呼び出し箇所は、(ShapeRunTimeForDrawer)(shape.runtime).draw();一行で
よいですが、shape.runtimeに設定する箇所は前記のinstanceof等によるク
ラスの決定処理が必要になります.

>>利用者は「ShapeRunTimeというクラスをサブクラス化して、独自の実装
>>を書き、Shapeに実行時に自分で設定して、narrowing castして機能を呼
>>び出す」という約束を守れるのでしょうか?
>
>サブクラスを定義して、Shapeにくっつける所までちゃんとやれば、
>ダウンキャストでヘマすれば例外でコケるので、守らざるを得ない
>というか(^^;

くっつける作業は、draw(Shape);というメソッドを作るのと同程度の手間で
す.それを各アプリケーションが守らなければならないので、「同じような
もの」と称しました.(大して変わらない位が妥当かな)

>>別の観点から見て、ShapeRunTimeには実行時のみ使える基本機能も持た
>>せることが考えられますよね.
>>それと同程度にdraw()インターフェイスの必要性があれば、
>>ShapeRunTime#draw()という(抽象)インターフェイスも書いておけば、
>>narrowing cast無しで呼び出せます.
>
>これは、そうだと思います。そして、各アプリの特化したものだけ、
>ShapeRunTimeのサブクラスに実装すればいいわけです。

そうなると、今度は私の挙げた手に近づくのですが、私はアプリケーション
に特化したものがない場合は、前記の手間が全く不要という所を重視してい
ます.
アプリケーションに特化した処理を用意する場合は、ShapeRunTimeのサブク
ラスを用意するパターンでもspeciallyFunction(Shape);みたいなのをアプ
リケーション内に持たせるのも大差無いと考えたためです.

>>うーんとこの場合のShapeFunction実装クラスは、Shapeサブクラスと同
>>様に複数のアプリケーションから使われるクラスライブラリの位置付け
>>ですね.
>
>了解しました。

この辺の視点の違いがあったので意見が違っただけと思いますけどね.

>>        アプリケーションに独自の実装は...の部分(上に引用しました)
>>にもあるようにShapeFunctionとは独立して作らざるを得ないと思います.
>
>先程のotherYYYY()ですね。で、LineやRectをinstanceofするelse
>if の山についてはあきらめる、ということですか。
>
>そうすると、Shapeにruntimeを持つ必要もなくなるのですが...

そうです.私は持つ必要もないと思いました.

>でも、どっちみち、transientなメンバは何やかやで要りそうな気
>がします。たとえば、Windowsなら、CPenなんてオブジェクトがあっ
>て、こいつで描画属性を指定するわけですが、実装によっては、実
>行時には各ShapeにCPenを保持させときたいと思うかも知れません。

この手の普段は使わないが一時的に集合の各要素に持たせたい情報があると
きは、wrapperを使うほうが直感的な気がします.
(アプリケーションによって変わるのであればなおさらです)
# 包含関係が逆って考え方ですね.このケースでどっちの方がいいかはまだ
# 厳密には判断できていませんが.

>Shapeはたいてい大量にあるでしょうし、Shapeの実行時属性は
>Shapeごとに持ってないと管理が大変ですし...
>
>Shapeが具体的にLineかRectかってことにより動作を変えよう、な
>んてことも考えると...

リフレクションを使わない限りは、、、あ、、、ここまで書いて...
Abstract Factoryパターン使えば出来てしまう...今ごろ気付きました.
ここまでの記述は誤解に基づくゴミです.
***********************

interface ShapeRunTimeFactory {
  ShapeRunTime createLineShapeRunTime();
  ShapeRunTime createRectShapeRunTime();
  ShapeRunTime createCircleShapeRunTime();
    :
}

Drawer機能を使いたいアプリケーションは、
interface Drawer {
  void draw();
}
interface LineShapeRunTimeForDrawer extends
                         LineShapeRunTime, Drawer {}
  :
# クラスでも行けるけどinterfaceの方が汎用的に使えますね.

で、各アプリケーションは(各Drawerを返す)ShapeRunTimeFactoryのサブク
ラスをShapeに与えて、Shapeサブクラスは自分に応じたcreateメソッドを呼
べばいいと.
interface Shape {
  ShapeRunTime getShapeRunTime(ShapeRunTimeFactory factory);
//void setRunTimeFactory(ShapeRunTimeFactory factory); ※
//ShapeRunTime getShapeRunTime();                      ※
    :
}

おお、完璧かも.Shapeの実装クラスではShapeRunTimeオブジェクトをキャッ
シュしてもいいですね(その場合※のような形の方が良さそう).

新しいShapeサブクラスが出来ればShapeRunTimeFactoryとその実装クラスに
インターフェイス追加してgetShapeRunTime()でそのメソッドを呼べばOK.
# 自動でコンパイルしてくれないので明示的にコンパイルしないと修正忘れ
# に気付かない可能性はありますが.
もちろんアプリケーション毎に[newType]ShapeRunTimeFor[Function]のクラ
スの追加も必要ですが、これはどんな方法を取っても手間は同じなのでよし.

新しい機能の追加に関してはもう何の問題も無いですね.
後は、同じ機能のインターフェイス変更などの場合の修正の手間ですが、こ
れは一つのメソッドに実装するよりは厄介になりますが、各クラス
(例えばDrawer実装クラス)を同じソースファイルに書いたり(アプリケーシ
ョンと同一パッケージなら可能)、同じpackageに属させることでそんなに大
変じゃなくなると思います.


>こそShapeRunTimeの生成インタフェースをグローバル変数渡しにし
>てでも。
って書いてくださってたのに何やってんでしょ..おばかでした.すみません.

「ShapeのメンバとしてRunTimeを持ち、各アプリケーションが設定する」と
いう意見に固執して、混乱していたようです.

これでほとんど納得できました.
前半の長いゴミを読ませてしまって申し訳ないのですが、うまく編集する気
力が無かったのです.すみません.

──────────────────
木下 信@イデア
──────────────────