- PR -

class or interface ?

投稿者投稿内容
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-09-03 10:25
引用:

Junさんの書き込み (2003-09-03 10:03) より:
自分でソースをいじれるものならばもちろんそのように作るのがいいので
しょうが既成のクラスを使う場合そのように設計されているとは限りません.
そのような場合にインターフェースだけ利用したいということがある
と思いました.


関連の無いクラスで同じInterfaceを使いたいのであれば、
Adapterパターンで解決します。
http://www002.upp.so-net.ne.jp/ys_oota/mdp/Adapter/index.htm

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-09-03 10:27 ]
Jun
大ベテラン
会議室デビュー日: 2003/08/25
投稿数: 141
投稿日時: 2003-09-03 10:36
引用:

yamasaさんの書き込み (2003-09-01 13:54) より:
引用:

Junさんの書き込み (2003-08-29 15:34) より:
例えば乗り物をinterfaceとします
乗り物の具象クラスには車やバイクなどがあるとし, それらには走らせるという
メソッドや操作するための他のメソッドがあるとします.
これらのメソッドを使って乗り物を操作しても良いのですが面倒だからこんなことは
したくないと思って例えば次のようにします
乗り物にコンピュータを組み込み, そのコンピュータは目的を与えられれば勝手に
乗り物を操作し, 目的を達成してくれるのです.
こうなったら乗り物の操作を覚えている(=publicである)必要はありません.
その場合乗り物とは何か操作するメソッドがある(それはコンピュータにより必要
とされるメソッドであり何が必要か決まっているが(=interfaceにある) そのメソッド
は使えなくて良い(=publicでなくてよい))
どこかへいきたいときはプロトコルを指定する(=それらのメソッドをつかう別のメソッド
を呼ぶ)だけでよい

というように考えたらいかがでしょう



つまり、指示の受け渡しの関係は
運転手 <-> コンピュータ <-> 乗り物本体
のようになっているわけですよね。
運転手 <-> コンピュータ間は目的地の指示だけで、
コンピュータ <-> 乗り物本体間では実際のハンドル操作等のやり取りが行われると。

このように、問題領域(ドメイン)を抽象度や機能の固有性などをもとに分割することを
「レイヤリング」と呼び、分割された各部分を「レイヤ」と呼びます。
レイヤリングの基本は、あるレイヤに依存する対象を
隣接するレイヤに限定することです(レイヤリングにおけるカプセル化)。
すなわち、上の例で言うと、「運転手 <-> コンピュータ」と「コンピュータ <-> 乗り物本体」間の
やり取りの規約(=広い意味でのインターフェース)は独立していなければならないということです。

しかし、Junさんの例では、「運転手 <-> コンピュータ」のインターフェースがpublicメソッド、
「コンピュータ <-> 乗り物本体」のインターフェースが非publicメソッドとして混在することに
なってしまいます。
このようなやり方は、レイヤ間の独立性を大きく損ねるものだと思いませんか?

# ちなみに「レイヤリング」の失敗は、大抵の場合、大きな手戻りの発生や
# ソフトウェアの保守性の低下など、深刻な悪影響を引き起こします。

まとめると、
(1)interfaceに非publicなメンバの宣言も認める
メリット:
複数のレイヤ間の(広い意味での)インターフェースを一つのファイルに記述できる。
デメリット:
本来独立したものであるはずの複数のインターフェースを
一つの(Javaの)interfaceとして宣言することは、レイヤリングの原則に反する。

(2)interfaceにはpublicメンバしか認めない
メリット:
アクセス制限が一つしかないため、一つの(Javaの)interfaceに
一つの(レイヤ間)インターフェースを記述することが自ずと強制される。
デメリット(?):
レイヤリングの原則を無視するような記述ができない。

根拠は上に示したとおりです。


もしJunさんの意見が、
「レイヤリングやカプセル化の原則に反していようとも、
Javaのinterfaceに非publicなメンバを記述できる自由が
プログラマに与えられるべきだ」
というものでしたら、もはや私には反論する気はありません。
# でも、そういうのはC#とかでやってほしいなあ…

[ メッセージ編集済み 編集者: yamasa 編集日時 2003-09-02 15:28 ]



ちょっと他の投稿を読んでいてここを読むのが遅くなってしまったのですが

レイヤリングを促すのが interface に public しか認めない理由である
というなら納得できます.もちろん他にも理由はあるかもしれませんが

私はだいぶ前にjavaのプロジェクトに関係してからしばらくブランクが
あり,最近またjavaで開発を始めたのですが, 最初からある程度設計を
頭の中で描いて作ることは難しいので作り直しながら開発を進めています.

今作っているものに私が例としてあげたようなものが出てきたのですが
私が直面している実際の例の場合について考えてみても
最終的にはあなたがおっしゃるようにレイヤを分けるのが正しいと思います.
ただレイヤを分けるためには継承関係にあるクラスの系列を別にもうひとつ
用意しなければならないことになってそれだけ手間がかかりますので,
おそらくかなり後の段階にならないと最終的なクラス構成におちつかない
とは思いますが


Jun
大ベテラン
会議室デビュー日: 2003/08/25
投稿数: 141
投稿日時: 2003-09-03 10:45
引用:

ぽんさんの書き込み (2003-09-03 10:25) より:
引用:

Junさんの書き込み (2003-09-03 10:03) より:
自分でソースをいじれるものならばもちろんそのように作るのがいいので
しょうが既成のクラスを使う場合そのように設計されているとは限りません.
そのような場合にインターフェースだけ利用したいということがある
と思いました.


関連の無いクラスで同じInterfaceを使いたいのであれば、
Adapterパターンで解決します。
http://www002.upp.so-net.ne.jp/ys_oota/mdp/Adapter/index.htm

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-09-03 10:27 ]


もちろん方法はあって実際に私はパターンについては何も知らないのですが
実際にこのような場合が発生して同じような方法で解決を試みました.
もっともそれは私の勘違いで実際には別なクラスを継承すればよいとわかったのですが

ただ,interfaceでないものでも私のいったようなことができるとさらに簡単になる
場合があるように思います.

Jun
大ベテラン
会議室デビュー日: 2003/08/25
投稿数: 141
投稿日時: 2003-09-03 10:56
引用:

ぽんさんの書き込み (2003-09-02 16:14) より:
Junさん、こんにちは。

yamasaさんの発言にプラスして、
Astmildさんの「2003-09-01 02:05」への意見も聞かせては頂けませんか?
(1)・(2)の「メリット」&「デメリット」&「根拠」がJunさんの考えと一致してますか?

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-09-02 16:35 ]


これは, いってしまうと同意は出来かねるというところなのですが
それ以前にその仮定(狭義の仕様, 広義の仕様)というところがどうも
理解できなかったのでどういっていいのか良くわからなかったのです

話がまたそれてしまうかも知れませんが
そもそも仕様の公開性ということと, アクセスの公開性(メソッド等を呼び出せるかどうか)
ということと多態性に関する制限(オーバーロードされるか隠蔽されるか)とは
本質的に異なることであるように感じます.

それがc++やjavaでは言語として同じキーワード(public.private,protected)
を使うことにより混同されてしまっているようだと感じるのですがいかがでしょう

言語としての簡潔性にはいろいろな視点がありうると思いますが, なんでも一通り
のキーワードで済まそうとするのが簡潔であるとは思わないのです.
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-09-03 11:18
Junさん、「2003-09-02 16:14」へのご回答ありがとうございます。

引用:

Junさんの書き込み (2003-09-03 10:45) より:
もちろん方法はあって実際に私はパターンについては何も知らないのですが
実際にこのような場合が発生して同じような方法で解決を試みました.
もっともそれは私の勘違いで実際には別なクラスを継承すればよいとわかったのですが

ただ,interfaceでないものでも私のいったようなことができるとさらに簡単になる
場合があるように思います.


コーディング上「簡単」になっても、オブジェクト指向設計上問題があります。
Javaにはオブジェクト指向設計を犠牲にしてまで「コーディングを簡単にする」という考えが
無いと思います。
(http://www.atmarkit.co.jp/fdotnet/special/java2cs/java2cs_01.html
を読む限りではC#にはあるみたいですが・・・)


デザインパターンを学んでみて下さい、世界が変わりますよ。

[ メッセージ編集済み 編集者: ぽん 編集日時 2003-09-03 11:36 ]
ぽん
大ベテラン
会議室デビュー日: 2003/05/13
投稿数: 157
投稿日時: 2003-09-03 11:35
引用:

Junさんの書き込み (2003-09-03 10:36) より:

今作っているものに私が例としてあげたようなものが出てきたのですが
私が直面している実際の例の場合について考えてみても
最終的にはあなたがおっしゃるようにレイヤを分けるのが正しいと思います.
ただレイヤを分けるためには継承関係にあるクラスの系列を別にもうひとつ
用意しなければならないことになってそれだけ手間がかかりますので,
おそらくかなり後の段階にならないと最終的なクラス構成におちつかない
とは思いますが


クラス構成の設計は、コーディングの前にやる事だと思うんですが...
Astmild
常連さん
会議室デビュー日: 2003/06/09
投稿数: 30
お住まい・勤務地: 大田区
投稿日時: 2003-09-03 12:29
引用:

Junさんの書き込み (2003-09-03 10:56) より:
これは, いってしまうと同意は出来かねるというところなのですが
それ以前にその仮定(狭義の仕様, 広義の仕様)というところがどうも
理解できなかったのでどういっていいのか良くわからなかったのです


これは私の表現が良くありませんでした。失礼しました。

広義の仕様として、「要求を分析した結果作成され、どのような動作を
するのか、どのような構造をしているのかを示すもの」、
狭義の仕様として、「ソースコードを起こせる状態まで突き詰めたもの」
という意味で使用しました。

同じ「仕様」として表現するには違う気がする、けどほかに上手い表現が
思いつかなかったので「広義」「狭義」で分けてしまいました。


ところで、これは別の発言へのレスなのですが、
>最初からある程度設計を頭の中で描いて作ることは難しいので
>作り直しながら開発を進めています
もしかしてクラスの全体図ができる前にソースコード(もしくはそれに近い詳細設計)
を作っている、と言っています?


[ メッセージ編集済み 編集者: Astmild 編集日時 2003-09-03 12:55 ]
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-09-03 12:40
ほむらです。
-------------
Jun氏へ
引用:

そもそも仕様の公開性ということと, アクセスの公開性(メソッド等を呼び出せるかどうか)
ということと多態性に関する制限(オーバーロードされるか隠蔽されるか)とは
本質的に異なることであるように感じます.

それがc++やjavaでは言語として同じキーワード(public.private,protected)
を使うことにより混同されてしまっているようだと感じるのですがいかがでしょう


interfaceについて話がすれ違い気味ということがあるので本質的にという
単語にもすれ違いがあるかもしれません。
僕的には
仕様の公開性ということと, アクセスの公開性とは、
仕様の公開性と動作の公開性という表現でいいかえられ。
それが、公開性(公開の必然性)という意味で異なるものだとおもいます。

多態性に関する制限については、動作の公開性に属するものとして
同じと考え結果 仕様・動作の公開性という二つにおいて考えたとき。
前者 仕様の公開性については仕様という点から結果何ができるのかを宣言する都合で
   外部との橋渡し的な意味もあり、すべてにアクセスできる必要があると考えます。
また、逆に
後者 動作の公開性については動作という点から結果何をするのかを宣言する都合で
   内部での利用が出来ればよいということから決して
   すべてにアクセスできる必要性はないと考えます。
   ただし、外部からの入力が必要な場合には公開される必要あるでしょう。
 
つまり、ここで大切なことは可視性を実現する上でキーワードなわけで
privete,protected,publicについては
C++もJAVAも同じ物であるとおもいます。

同じ意味ならば、同じ言葉を使用したほうが道理にかなっていますよね。
某MS社のようにおなじ略語にまったく別のものを
わりあててしまうのは問題だと思いますけど

あとJavaの場合defaultなんて(暗黙的な)アクセス修飾子もあるみたいですね。。。。
C++でなれている僕にはこれのほうがややこしいです。

#ちなみに、オーバーロードは多態性(いろんな動作)を
#実現するものではないと思っています。
#むしろ多様化(いろんな形)を実現するといったほうがしっくりくるかも
#最近、多態と多様の違いがわかってきたつもり(笑


#多少、文言などを修正

[ メッセージ編集済み 編集者: ほむら 編集日時 2003-09-03 17:23 ]

スキルアップ/キャリアアップ(JOB@IT)