- - PR -
クラスにちょっとだけ追加属性を持たせたい場合、オブジェクト指向的にはどうするのが良い?
投稿者 | 投稿内容 | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-12-11 12:17
言語は特に限定しないのですが、C# や Java あたりを想定しています。
たとえば、つぎのような擬似コードを考えます。Foo というインスタンスを複数管理するために、リストで持っています。
ここでクラス Foo に int abc; という属性を追加で関連付けたいとします。しかし、Foo のフィールドに abc を追加するほど、Foo と abc が密接な関係でもない場合、どうするのが良いかでいつも迷います。 こういう場合、私は Dictionary(Java なら HashMap) を使い、つぎのようにしています。
ただ、これだと、個数が1つを超える属性を追加したい場合、煩雑になるので、複数個入れられるラッパークラスとして Bar を作ってしまい、下記のコード例のように、Foo を key にして、Bar を検索できるようにして、追加情報があれば Bar のフィールドに詰め込むようにしています。
これしかないですかね?もっとエレガントな方法ってないものでしょうか?という漠然とした質問になります。 私が思っているこれでは嫌な点としては、Dictionary を使うと、ハッシュで検索になりコストが高いような気がするし、Foo に安易に equals メソッドを定義できなくなります。あと、Bar というどうでもいいクラスを作らないといけない点も木になります。とはいえどれも別にどうということでもない些細なことなのですが。 質問を言い換えますと、インスタンスとインスタンスを緩く結びつけて管理したい場合、どうするのが良いか?ということです。あと、こういう問題になにかパターンのような名前って付いているでしょうか? | ||||||||||||||||||||||||||||||||||||
|
投稿日時: 2008-12-11 12:26
とか駄目? | ||||||||||||||||||||||||||||||||||||
|
投稿日時: 2008-12-11 12:39
その "場合" によりけりかもですが、オブジェクト指向的には、Foo と abc の 2 つの属性を持つ別クラスを定義するってトコでしょうか。 もちろん、そのクラスに適切な名前を付ける (=適切な責任を持たせる) 必要があります。 例えば、書籍の貸出システムで、書籍を借りている利用者を、書籍クラスの属性にしたくないという時ならば、 書籍と借りている利用者の 2 つの属性を持つ貸出クラスを定義する、とか。
それは別問題ですね。オブジェクト指向的に適切かどうかという視点では、それは無視してください。 _________________ C#と諸々 | ||||||||||||||||||||||||||||||||||||
|
投稿日時: 2008-12-11 12:53
この部分に関しては、Dictionary.Comparer プロパティを使うことで解決できると思います。 でも私も、Foo と abc をセットにしたクラスを作って、そのリストで管理するように思います。 | ||||||||||||||||||||||||||||||||||||
|
投稿日時: 2008-12-11 13:31
こんにちは。
可能であるなら、 最初から付加情報を格納できるようにクラス設計しとけばよいのではないでしょうか? Microsoft製なんかだと、よくTagプロパティなんてものがありますよね。 | ||||||||||||||||||||||||||||||||||||
|
投稿日時: 2008-12-11 13:49
インタフェースIFooExtenderを作成してFooとabcの密接な関係を 作ればいいのでは。。。。∋(・ω・)∈ ダメ? | ||||||||||||||||||||||||||||||||||||
|
投稿日時: 2008-12-11 18:29
みなさまコメントありがとうございます。
ありがとうございます。継承を使ったほうが良いのかどうかも含めて悩んでいます。 なお、私は件名に「ちょっとだけ追加属性を持たせたい」と書き、これが紛らわしかったかもしれませんが、今のところ動的である必要はないです。静的に解決できれば良いので、"ABC" のようなキーを使うことはしなくても良いと考えています。
たとえば
のようにもできますね。 考えてみると、私の悩みは、Dictionary<Foo, Bar> でも書けるし List<FooAbc> でも 書けるし、どちらも書けばちゃんと動くのはたしかだけど、場面場面でどう使い分ければいいかが分からないという感じなのかもしれません。
これはご指摘のとおりだと思います。
これは存在を知りませんでした。new するときに指定できますね。 (Java の時には同じことができるのかが少し気になりますが、もっとも私は最近は Java は使っていないので、あまり制限にはならないです。)
今のところ、拡張が容易なような設計、ということはあまり目指していなくて、最初からカッチリと固まった設計で大丈夫です。 Foo クラスに、最初からいろいろフィールド(メンバー変数)を追加すれば、アクセスも高速だしコードも簡素になって良いのですが、Foo の中に入れないほうが良さそうな情報というものがあり、悩んでいます。 たとえば、Person クラスがあって、フィールドとして name, age, address, ... があった場合、そこに所有車の Car クラスを追加のフィールドとして入れるかどうか、という感じです。車を保有しているということは人の持つ属性ではなく、人と車のつながりにすぎないかなあ、という感じです。こういう疎なつながり関係のときにどう管理しようかで悩んでいます。 (ただこれを言い出すと、じゃあ address も、Car と同様の扱いにすべきでは、ということになりフィールドとして入れるものがほとんどなくなってしまいます。これについてもちょっと良く分かっていません。)
インターフェースですか。継承に似た感じになるのでしょうか。ちょとイメージが掴めませんでした。ちょっと考えてみます。ありがとうございます。 | ||||||||||||||||||||||||||||||||||||
|
投稿日時: 2008-12-11 18:33
(利用規約違反のため削除いたしました。@ITクラブメンバーシップセンター)
|