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

[jfriends-ml 1549] Re: 集約とコンポ ジション



前橋です。

> > Toru TAKAHASHI <tooru6.takahashi@xxxxxxxxxxxxx> wrote:
> privateなinner classを定義したら、クラス外部からはアクセスされない
> ことが実現できると思いますが、いかがでしょう?
> public class Composite {
>     Part part = new Part();
> 
>     private class Part {
>             :
>     }
> }
> 
> Compositeクラスに、partをreturnするメソッドを書くと、外部に参照が
> 漏れてしまうかもしれませんが。。。

innerクラスは、ActionListenerなどのように、スーパクラスや
インタフェースを外に出す使い方が多いので、やっぱり例として
不適切ではないかと。

また、例えばRectangleが、左下と右上の座標をPoint2Dで持つ場合、
このPoint2DはライフサイクルをRectangleと共有しますが、まさか
Rectangleのinnerクラスにはできんでしょう。他で問題でまくりです。

こういうことは、以前JavaHouseに書いたことがあって、

http://java-house.etl.go.jp/ml/archive/j-h-b/028630.html#body
より抜粋:
| Javaでは、オブジェクトや配列はポインタでしか扱えないので、
| 
| ・ちょっと使うだけの一時オブジェクトまで、いちいちnewしなきゃなら
|   ないのは、面倒くさい(これは些細なことですが)。
| 
| ・オブジェクトのフィールドにオブジェクトを格納することができない
|   (オブジェクトへのポインタなら格納できるけど)ので、そのオブジェクト
|   が他からも参照されるようなものなのか、それとも完全に親オブジェクト
|   の一部で、ライフサイクルを共有し、nullになることも許されないのか、
|   という点の区別がつきにくい。
|
| ・オブジェクトの配列を作ることができないので(オブジェクトへのポイ
|   ンタの配列なら作れるけど)、いちいちnewするのが面倒くさい上、
|   そのオブジェクトが他からも参照されるようなものなのか、それとも
|   完全に配列の一部で、ライフサイクルを共有し、nullになることも許
|   されないのか、という点の区別がつきにくい。
|
| ・配列の配列を作ることができないので(配列へのポインタの配列なら作
|   れるけど)、多次元配列のつもりなのか、配列の要素のうちどれかひと
|   つがnullになったり、要素数が子によって違ったりして良いものなのか、
|   という点の区別が付きにくい(これは、言語仕様が初めから多次元配列
|   を用意してくれていれば良かったように思うんですけどねえ)。
| 
| という問題があると思います。
|
| # C でも、例えば可変長の配列を作るときには、aggregationであるとき
| # でもポインタを使わなければならないので、似たようなものかといえば
| # そうかもしれませんけど(^^;

# ここでaggregationという言葉を使っていますが、GoFではこういう
# 言葉を使っていた... はず...

> > C++の場合、ポインタや参照ではなくインスタンス自体をメンバとして
> > 持っているような場合では明示的にコンポジションになると思います。

そうなんですが、そうすると、childのサブクラスを保持することが
できなくなって、「サブクラスは常にスーパクラスとして使える」という
原則ががらがらと...

また、実体をメンバに持つと、コンストラクタに引数が必要な場合には
どうしよう? なんて話もあって、おかげでC++は異様に複雑になってしまって
います。異様に複雑にしたんだけど、結局オブジェクトの配列を作るときには
コンストラクタに引数が渡せないという。

http://java-house.etl.go.jp/ml/archive/j-h-b/028630.html#body
より再度抜粋:
| でも、実際問題として、オブジェクトの実体を扱うことを認めると、
|
| ・ポインタの宣言などのための構文を用意しなければならなくなって、言語
|   仕様が複雑になる。
|
| ・オブジェクトの実体の配列を確保したり、オブジェクトの実体を含むオブ
|   ジェクトをnewしたりしたときに、暗黙にコンストラクタの呼び出しが
|   行われたりして、言語の挙動を把握するのが困難になってくる。
|   その暗黙のコンストラクタ呼び出しに引数を渡そうとしたりすると、さらに
|   大変。
|
| ・プログラマがよく分かっていないと、巨大な配列やら巨大なオブジェクト
|   やらをじゃんじゃん実体でコピーして、とんでもなく効率の悪いプログラ
|   ムを書いてしまう可能性がある。
|
| ・継承の扱いが厄介になる。サブクラスへのポインタを、そのスーパークラス
|   へのポインタとして扱うのはいいが、サブクラスの実体を、そのスーパー
|   クラスの実体として扱うわけにはいかない。
| 
| ・実行系の実装も複雑になる。
| 
| ・(これは別の問題ですが) Cでいう&演算子を認めると、GCの実装が困難になる。
| 
| この辺のトレードオフを考慮した上で、Javaは、「(基本型は実体だが)オブジェ
| クトと配列は常にポインタである」という線を選択したのだと、私は認識してお
| りますが。
|
| それはそれで分かりますけど、やっぱり不便だよなあ、と思うこともしばしば...

この辺のことはWebページにまとめようかと思いつつ、なかなか
時間がなくてできなくています。

Java本の話も来てたりするので、ネタ集めおよびちょっと公開して様子見、
なんて意図もあったりする... (^^;

                                               de 前橋