立てたのかよw
オレはようやく登りはじめたばかりだからな。 このはてしなく遠いOOP坂をよ… みかん
OOPLラブ(ハート) オブジェクト指向はどうでもいい(無視)
OOPとOOPLは優れた問題解決ツールである
OOPの本質は抽象化なんじゃよー カプセル化とか継承とかは手段に過ぎないんじゃよー みんな手段におぼれすぎなんじゃよー
・オブジェクト指向 オブジェクトを中心とする「考え方」を指す用語。略してOO。 OOP(〜プログラミング)、OOA(〜分析)、OOD(〜設計)などがある。 ・OOP オブジェクト指向プログラミングの略。ここのスレタイ。 オブジェクトを中心としたプログラミングのこと。 ・OOPL オブジェクト指向プログラミング言語。よく勘違いされるが 別にこれが無くてもOOPは可能。でもあるとOOPには便利である。 ・クラスベースOOPL JavaやC++など、OOPLの実装として「クラス」を採用した言語。 オブジェクトの設計図たる「クラス」から 「インスタンス」(あるクラスから作成されたオブジェクトのことをこう言う)を作成する。 別にこれじゃないとOOPLじゃない、なんてことはない。 ・プロトタイプベースOOPL JavaScriptなどが有名。あとSelfとか言うのもあるみたい。 OOPLの実装として「プロトタイプ」を採用したものらしい。 ごめん俺はよく解らない。でも少なくともクラスは使ってないのは判る。 ・その他 他にも、色々な機能を組み合わせ、OOPを ライブラリやそれに準ずるものなどで実装したシステムや OOPLでない言語に拡張を加えてOOPを可能にした言語などが存在する。 例えばLISPにはマルチメソッドを利用したOOPシステムがあり、 Perlは既存の機能にわずかな拡張を加えてOOPシステムとしている。
いつもの彼は、とりあえずまともに一つアプリケーションを書いてみるべきだな。 丘ハカーが何を言っても説得力皆無だよ。
>>7 OOを知らない人は「オブジェクトを中心とする「考え方」を指す用語。」で分かるわけないんだよな。
かといって、「OOPとはHoge_dosomething(hoge)のことである」なんて説明もなあ。
11 :
デフォルトの名無しさん :2010/11/11(木) 00:41:08
このスレッドは天才チンパンジー「アイちゃん」が 言語訓練のために立てたものです。 アイと研究員とのやり取りに利用するスレッドなので、 関係者以外は書きこまないで下さい。 京都大学霊長類研究所
アイちゃんってまだ生きてるの・・・?
商用マシンでオブジェクトという語を前面に出してきたのは IBMシステム38だと思うけど、あのマシンのオブジェクトと 現在OOPで指すオブジェクトとどれほど違うのかな。
>>13 それがどんなのか分からんけど
現状のOOPLやなんかで言われるオブジェクトは
数値、文字列、ブール値、構造体、手続き、配列…など
ぶっちゃけ取り扱う全てのデータには対応する操作(メソッド)があって
その操作とセットになったものがオブジェクトって感じがするね
数値なら演算、文字列なら連結・分割・検索など、
ブール値なら条件分岐までメソッド扱いな言語もあるし
手続きの呼び出しも手続きオブジェクトのメソッド呼び出しだったり、
配列操作も配列オブジェクトのメソッドだったり。
汎用レジスタ、メモリ、スタック…などのオブジェクトには それぞれ対応するメソッド(インストラクション)が存在するね。 汎用レジスタならmovやadd、メモリなら[address]でとれる、 スタックならレジスタの退避・復帰までメソッド扱いなのもあるし 手続きの呼び出しもメモリのcallだったり、 配列操作もシングルトンなSSEオブジェクトの専用命令によるメソッドだったり。 つうかOOPLてのはユーザがクラスを作れて何ぼだろ。
>>15 クラスを作れて何ぼというよりは
カプセル化できて何ぼだと思うな
カプセル化するための手法の一つがクラス
いつもの人だけど、一応断っておくけど、俺がスレ立ててるんじゃないよ。 なぜだか知らないが、いつも誰さんが立ててくれる。多分OOPにそれなりに悪意のある人だと思う。 コメントがいつもネガティブだし。 ところで、オブジェクト自身が構造体の先頭にvtableを持つんじゃなくて、 ポインタや参照が自分がさしてるオブジェクトの型を持ってるって案はどう思う? イメージだと、ポインタは、class pointer_t{ int type; void *addr; }; こんな感じで定義して、ポインタへオブジェクトのポインタを代入したときに、 typeも一緒に書き込むっていう。 結局、ポリモはポインタや参照越しにしか行われないんだから、 ポインタや参照が自分の指してる物の型を知ってればそれで済むと思うんだが。 構造体先頭にvtable持つのって、昔のC言語のノリと相性が悪いし、 C++的にはあんま宜しくないとおもうんだがなぁ。 現状のC++がああいう実装になってるのが未だに謎。 ちなみにshared_ptrは俺の言ってる方の実装になってるんだよね。
こうしておくと、ポリモするのに対象の構造体に細工を加えなくてすむ。 vtableも要らないし、継承してる必要も無い。 だから、他人の書いた構造体や、C言語用に書かれた構造体を、手を加えずにポリモの対象に出来る。 ポインタが自分の指してる物の型を知ってて、 それに基づいて、呼び出し機構で関数がswitchするだけ。 関数呼び出しが特殊な構造になるだけで、呼び出される先の関数も素の関数に出来る。 だから、C言語用に書かれた普通の関数を、何も手を加えずにポリモのディスパッチ先にリンク出来る。 こっちのが便利だよな。
などと意味不明の供述を繰り返しており、
extern "C" HOGE baka(HOGE*hoge){return hoge;} void main(){ baka(new HOGE())->hoge(); } でクラッシュするわけだがItumono人にはそれが良いらしい。
>>17 > ポインタや参照が自分がさしてるオブジェクトの型を持ってる
それ、まさにPerlのOOPシステムじゃないか?
Perlは糞だともうが、OOPに対する姿勢は評価してる。 真面目にやる価値無しっていうね。 Itumonoってかっこいいな。 Itumono思考 IOPL なんか入出力みたいだな。
真面目に生きる価値のない奴発見
C++に対して関数テーブルを使う代わりに実行時にハッシュ引け言ってんのかアレは。
なに言ってんの? タイプ値を元にしたテーブル作るに決まってるだろ。 テーブルのサイズがでかくならないように、 タイプ値はポインタ宣言ごとに固有にする。 まーこの辺コンパイラはちょっとしんどい。 だけど、コンパイルはIOバウンディング型だから問題ないだろう。
何でも入るけど、何指してるかは保持してるvoidポインタを使ったポリモ、ではなくて、 どっちかって言うと、ポインタの共用体だな。 ( type_a | type_b | type_c ) *p; 宣言はこんな感じになるだろうな。type_aの型値が「1」で、以降連番で良いだろう。型値「0」は未代入時。 型値「0」で関数の引数に渡されたら、実行時エラーのヌルポだな。 ただ、これだと予めポリモ対象の型が全てわかってないとダメで、 所謂フレームワーク的なことが出来ないから、型推論もつける。予約語はautoで良いだろう。 auto *p; p = &type_a_inst; p = &type_b_inst; p = &type_c_inst; こんなプログラムを書くと、型推論で、pの型は勝手に( ( type_a | type_b | type_c ) * ) となる。 そのポインターの取りうる型を全て調べて、共用体風にして、頭から型値を割り振る。
だから、 auto *p; p = &type_a_inst; p = &type_b_inst; p = &type_c_inst; func( p ); こう書いたんなら、 それぞれの型を受けるfunc関数が全て定義されてなきゃ、リンクエラーだな。
( ( type_a | type_b | type_c ) * )と ( type_a * | type_b * | type_c * )の どちらの表現が適切かは議論のあるところだろか。
御託は結構なのだが、道具として全く使いやすいように見えないのは俺だけか?
まーポリモ自体はそうそう使われるものではないから。 ただ、型推論は受け入れられて良いものだと思う。
例えば、ほとんどの変数の型をautoにしておけば、 テンプレート相当になる。 auto add( auto a, auto b ){ return a+b; } void swap( auto *a, auto *b ){ auto tmp; tmp = *b; *b=*a; *a=tmp; } などなど。
>>30 ポリモには使いやすいんだろう。ポリモというItumono語をどう訳すべきかはわからないが。
重要なのは、それを使うとプログラマがどう幸せになれるかであって、 処理系の実装が(いつもの人的に)きれいかどうかなんてのは、何の価値もないんだよ。
matz曰く
> Ruby を使ったコーディングでは、見える部分では優雅に見えるけど、見えない部分では
> 泥臭いことをやっている。
>
> これを「怠惰のための勤勉」とまつもとさんは表していた。手抜きをしては美しいコードを
> 書くことは当然できない。でも、苦労を見せびらかす(表面に見えるようにする)のは
> 粋じゃない。まさに水鳥。
>
> 「全てをシンプルにすること = 美しい」ということではない。Ruby が簡潔な表現ができると
> 評価されるのは、Ruby 自身が複雑さを引き受けているからでもある。
http://d.hatena.ne.jp/LukeSilvia/20090207/p1
誰への攻撃かはわからんが、 俺の書いていることは、十分複雑だぞ。 型推論、しかも多型を取りえる共用体風型推論、それに基づいた、関数呼び出しのマルチメソッド化。 Rubyの処理系が複雑?なにそれ。 おれ自身、自分の言ってることは複雑すぎてあまり気に入っていないのにw もっとシンプルな解法があればなぁ。高速なマルチメソッドの呼び出しまで考えると、どうしてもテーブルを持つしかなく、 ゆえにコンパイラが複雑にならざるを得ない。困った困った。 まーマルチメソッドなんて無くても誰も困らんのだがな。
> 重要なのは、それを使うとプログラマがどう幸せになれるかであって、
C言語程度のことしか書かなくて良いんだから幸せだろ。 生の構造体と生の関数をどんどん定義していくだけ。 なにがどう結びつくかはコンパイラが全部やるんだから。 オーバーロードのイメージが強いね。あれが動的になったヴァージョン。
世の中のソフトウェア開発には、分析・設計や抽象化という作業があってだね。。
38の続き:
ただ、実装が泥臭いってだけで、考え方は優美だと思うよ。
生構造体 - 型持ちポインタ - マルチメソッド機構 - 生関数
<-ユーザ-><---------コンパイラ------------><-ユーザ->
<--------what----------><----------how------------>
って構造は幾何学的に綺麗だと思う。少なくともRubyよりはな。
>>39 >分析・設計や抽象化
すりゃいいじゃん。C言語にはそれらは無いとでも?
OOな分析・設計や抽象化は糞だからしなくてもいいけどな。
まず、省略してないって事。だから表現の幅がある。 少々冗長でも、何ステップか踏んでるわけだ。
まーvtable愛好家のような短絡野思考郎には理解できんだろうが。
void Hoge_init(Hoge*hoge); int Hoge_getBoo(Hoge*hoge); void Hoge_doSomething(Hoge*hoge); というものはItumono語でいうOOではないので注意してください。
そりゃそうだろ。どの辺りが「オブジェクト指向」なのか説明して欲しいぐらいだ。 オブジェクトがフィーチャーされてるか?
>>43 の例だと、
HogePiyo_proc(Hoge*hoge, Piyo *piyo);
なんてのも普通に出てきそだし、オブジェクト指向っていうよりは、普通の昔ながらのC言語、構造化言語って感じだわな。
何がクソかっていうと外を向いていないってことだね、自己完結している。 例えば後に機能追加したいときにはclass PluginBase;なんてものを作っておき、 プラグイン製作者にはこれを継承させる。 ItumonoSystemなら追加することは無い、面倒なdllをやらなくてすむわけだ。
他にも void HogeCollection::add(HogeBase*hoge); こういうのはだめ。ADLが使えない。
Itumono言語だと、 add_plugin( &framework, &my_plugin ); で一発だ。 add_pluginの定義は、 struct framework_t{ vector< auto * > plugins; }; void add_plugin( framework_t *fw, auto *plugin ) { push_back( &fw->plugins, plugin ); } だ。
複数の型が推論される場合は、それらの全ての型を含む共用体となる。 共用体にはマルチメソッドが適用される。 これを忘れてもらっちゃ困るなぁ。
50 :
デフォルトの名無しさん :2010/11/13(土) 23:48:00
晒しage
まー平たく言うと、Itumono言語はOOPLのvtableをwhatとhowで分離したものだから、 通常のOOPLで出来ることはItumono言語でも出来るよ。当たり前。 ただ、whatとhowを分離したことで、「オブジェクト」という、whatかhowか、データ構造か制御構造か、なんだか解らない曖昧なものが無くなる、 「オブジェクト」が分解されて毒素が無くなるから、Itumono言語はオブジェクト指向ではないって寸法さ。
f = (HogeBase*(*)())GetProcAddress(hLib, "createHogeEx"); HogeBase*ptr = f(); ptr->boo(); delete ptr; やっぱりdllも作ったことの無い人だったか。
通常のOOPLで、 構造体 - vtable - 関数 となってるところを、 Itumono言語では、 生構造体 - 型持ちポインタ - マルチメソッド機構 - 生関数 としただけだから、通常のOOPLで出来ることは、当然Itumono言語でも出来る。 ただ、whatをhowを分離したから、オブジェクトと呼ばれるような曖昧なものは出てこないってだけ。 少々冗長に見えるかもしれないが、間にワンクッションおくことで、表現の幅が増える。 たとえば、ダックタイピングできたり、マルチメソッドが出来たり。 はたまた、OOPの思想に沿って書くことすら出来るぐらい、懐が広い。 OOPLの上位版と言っていい。ただ、オブジェクトは出てこないし、オブジェクト指向では無いが。
言語に求められる「表現力」は、抽象化したロジックを素直に記述できることであって、 何でもできることじゃない。むしろ、できることを適切に制約できるのが良い言語。
>>52 環境を取得する関数をDllに仕込んでおけば良いだろう。
init_itumono( env_t *env );とか。
init_itumonoはコンパイラが仕込むんだけどね。
>>52 の仕様だって、vtableの暗黙の仕様に頼ってる訳で、
これは同じことだよ。
>>55 誰がbooの関数ポインタテーブルを更新するのさ?
あれが出来ない、これが出来ないと言う人がいるから、 「出来るよ」と言えば、 こんどは、出来ないほうが良いといわれる。 世の常だな。 Itumono言語の仕様は、おれ自身はバランスの良いものに感じるがなぁ。 whatとhowの分離に着目した俺は流石だと思う。 今では絶対条件のようにも思える。 だって、Unixがそういう思想で、Unixは成功していて、俺はUnixが好きで、皆もUnixが好きだから。 whatとhowの分離の進んでいない、未熟児のマックバイナリの如何に糞なことか。 #!も糞なんだがな。はまれるw
俺はコード書けないが偉いさんありがとうございました。
>>56 環境がに決まってるだろ。
でもお前いいとこついてる。俺もこの仕様思いついてから、ずっと動的モジュールのロードで唸ってる。
型値に落ち着いたのも、それが一番有りえる解法かな、と考えたからだし、細かく細分化したのもそのため。
いわば、俺の言ってることは、テンプレートを後から動的にロードするようなものだからな。
ただ、これが出来ると、言語の強みになるかなとも思ってる。
クソにほめられるとクソがうつる。
いいから早くその処理系実装しろよ。
実装したら屑だってばれちゃうじゃないですか!
実装したいのは山々なんだが、毎月70時間程度残業している一般サラリーマンには正直きつい。 だから2chでアイデアだけ書いてるってのも。ニートや学生が実装してくれるかも試練と無駄な期待をして。 時間のある学生時代にこれ思いついてれば良かったんだが、それは無理だったんだよね。 仕事しだして、物事がわかってきて、初めて色々見えてきて、分別がついてきたわけで。 皆と同じで、俺も結局出遅れた一人ってわけだ。今からじゃもう遅いんだよな・・・
そりゃ俺も学生時代はOOPは最高のものだと思ってたんだぜ。 今考えると、何もかもおかしかったのに。 だって、OOP系の教授って社会不適応者ばっかだったし。 その時点で気づくべきだったんだろうけど、 当時は何も疑問に思わんかったんだよなー。 地上の楽園とか、学生運動とか、昔の人は馬鹿だなーとか思ってたが、 俺も結局そいつらと何も変わらなかったんだな。 甘い誘惑に簡単に引っかかっちまう。歴史は繰り返すってのが身にしみるよ。
> ニートや学生が実装してくれるかも試練と無駄な期待をして。 ならせめてちゃんと仕様書くらい作れ。
>>45 >>43 は、昔からある「C言語でOOP」の例だな。
まあ、これは多態をし辛いからOOP的にはイマイチではあるけど。
ファイル処理の関数なんかはかなりOOPしてる関数が多い。
多態もちゃんとする。標準入力が渡されても、ディスク上の実ファイルが渡されても
その形態に従って適切な処理が選ばれるからな。
そりゃ open(2) や write(2) とか、「(2)」のレベルで多態になってるからだ。 言語のレベルとは話が違う。
> 言語のレベル
OOPLじゃなくてOOPの話じゃなかったの
と思いつつ
>>66 もそれなりに微妙
>>63-64 専門用語一つ社会で使われている意味で使えないで、
自分の考えを正しく伝えられないような社会不適合者がなんか言ってる。
ちんこがサラリーマンのふりをしてるだけだろ
社会で使われている意味でのOOPの意味ってなんだよ。 誰も説明できはしないだろ。 関数は大体引数取るし、引数はその関数の処理の「対象」なんだから、その関数のオブジェクトだし、 ほら、オブジェクト使ってるからオブジェクト指向だってんなら、全部OOPになっちゃう。 OOPとそうでないものの明確な線引きって何よ。 誰も答えられないだろ。 だから俺が言ってやってんだろ。 オブジェクトってのは要は言葉を濁してんだよ。 データと処理の区別がない、なんとも言えない曖昧なプログラムのパーツのことを どうとも表現できないから、「オブジェクト」なんて呼んでるんだ。 だから、データ構造と制御構造の区別のない曖昧なものが「オブジェクト」で、 それを中心に考えるのがOOで、 それでプログラムを構築する手法がOOPで、 それが前提の言語がOOPLなんだ。 でも、なんで曖昧である必要があるんだ? Itumono言語だと、データ構造と制御構造は明確に区別されるし、 区別されるってだけで、通常のOOP相当のことも当たり前に出来る。 しかも、データ構造と制御構造を明確に区別することで、 マルチメソッドやダックタイピングまで可能だってのに。 なんで、曖昧にしておく必要があるんだ? 曖昧なままだと、少なくともマルチメソッドは無理なんだぜ。 どのみちこのみち。
>>71 >曖昧なままだと、少なくともマルチメソッドは無理なんだぜ。
OOPLでもマルチメソッド出来るものはあるワケだが…
何々教えて。CLOSとか言うなよ。
ん?CLOSはOOPLというよりOOPシステムだけど、それでもいいよ? てかJavaでもオーバーロードで出来ると思うが?何を指してる?
それは、静的なんじゃないの?
へ?動的じゃないとダメなの? まあ、動的でもそのCLOSは出来るんだよね?
静的なものは通常ポリモとは言わんだろう。 CLOSをOOPと言っていいのかは微妙だ・・・ どちらにしても、みんなの求めているものはコレジャナイ。 手続き型言語が欲しいんだろ?
>>77 静的なものはポリモじゃないってんなら、Javaにポリモは無いことにならんか?
JavaのメソッドはC++で言う仮想関数だから、 vtable相当を使った単一ディスパッチは出来るだろ。 ただ、多重ディスパッチ(マルチメソッド)には対応していなかった筈だが。 オーバーロードは可能だが、静的結合だ。
というか、単一オブジェクトがvtable抱えてるから、 原理的にマルチメソッドが出来ない。 だから俺はそのvtableをどっか別のところへ持って行こうと。 構造体からvtable消して、型情報はポインタに持たせる。 ポインタの型情報を使って、関数呼び出しをマルチメソッド化する。 上手いやり方だと思うが。
>>77 ポリモとかHDDをハードと呼ぶくらいにうざいですう。
>>71 >データ構造と制御構造の区別のない曖昧なものが「オブジェクト」
わかってるんじゃないか
中身の実装を隠蔽するのがカプセル化だよ
「自分が呼び出してるのがフィールドなのか、メソッドなのかを隠す」
ってのもその一部
カプセル化する対象の実装を書くのがクラス
クラスのインスタンスがオブジェクト
このオブジェクトを組み合わせてプログラミングしようってのがOOP
そんなに難しい話じゃないでしょ
>>82 彼に、ノイマン・アーキテクチャから演繹できない概念を理解させようとしても無駄だよ。
その手の抽象化の必要性を痛感する場面に遭遇したことがないみたいだし。
・万能感がある落ちこぼれってうざいよね。 ・fopen以前を誰も知らない世代てのはいいことであるわけだけれどもなあ。 ・「全てはOOと非OOに分けることが可能である」俺理論乙「その境目は仮想関数テーブルの有無である」俺理論乙 ・LISPが式と値を曖昧なままにして――区別してないのはOOPに関係ないことくらい習わなんだのか。 ・つかCでも関数ポインタを引数にとり関数ポインタを返す関数とかあるよな。 ・型情報はポインタに持たせることにより多重継承もできるんだとさ。 ・多重ディスパッチなんて使い道は殆ど無い。使うのは実行時とコンパイル時が同じインタプリタ言語くらいだ。 ・「相対性理論は間違っている」うざい。間違っていると思うのは手を動かさず演説ばかりしてるからだ。 ・OOなんて経験知の集積だ。プログラムを書いてれば分かるもので、書かない阿呆には理解はできん。 ・何度も言われただろうが、これから何度も言われるだろう「Itumonoが便利だと思うのはそれを使ったことが無いからだ」 纏めんの面倒 後全部グローバル名前空間にぶち込むなど阿呆とかいろいろ有るけど趣味グラマでもない人には言っても無駄
>Itumonoが便利だと思うのはそれを使ったことが無いからだ なんという説得力
>>84 >・OOなんて経験知の集積だ。プログラムを書いてれば分かるもので、書かない阿呆には理解はできん。
神が居た。
>「自分が呼び出してるのがフィールドなのか、メソッドなのかを隠す」 そもそもフィールドが存在しない言語を考えれば良い。 データがスタック上 (引数やローカル変数) にしかない言語。 関数型言語がそれに近い。 (フィールドの集まりである) thisやselfがなければ、マルチメソッドなんて無駄な概念も出てこない。 ついでに、スタックとフィールドの間でデータを移動する手間も省ける。
それはそうかもな、と思える指摘もあるが、 単一継承ならまだしも、多重継承はさすがに要らないだろ。 あれこれ言う人にはこの一言だ。 C++0xはああなった。 何処まで時間をさかのぼれば失敗を取り返せるか。 そう考えるのは自然だろ。
>>87 >データがスタック上 (引数やローカル変数) にしかない
FORTRANの香りがする
>>87 それは面白い試みなんだけど、
昨今のコンピュータには膨大なメモリ空間があって、
プログラマはそれの操作をしたがってる。
副作用を起こしてな。
副作用って、数学的には不味いんだが、
コンピュータにとってはむしろ本質的なものに思える。
「メモリ操作したい!有るんだから操作したい!触らせろ」ってな。
input -> update -> output はコンピュータにとっては呼吸のようなものだろうか。
Itumono言語は「いつもの言語」だから、普通でなければならないと思ってる。
C言語+テンプレート+マルチメソッド+型推論+何らかのカプセル化機能
これで十分でしょ。
>>90 >何らかのカプセル化機能
データと処理の区別が云々はどこいったの?
型付きラムダ式でもやってれば
仮想関数テーブルを噛まさないのであれば、それほど問題とも思えん。 get_value( &hoge ); とかな。 問題は、そこで小難しいことをやろうとしたことだ。 間にvtableを挟んでな。 vtableはデータと処理の橋渡しをするが、あまりに貧弱だし、邪魔だ。 構造体の先頭に仕込むアイデアは糞以下。 ポインタに持たす仕様だったら、幾分かはマシだったろうがな。 shared_ptrはそうなってるのにな。共有ポインタがデストラクタ持ちまわる。
94 :
デフォルトの名無しさん :2010/11/15(月) 23:26:47
そろそろC++ ISOスレに名前変えるか
>>93 がどっか行って消えればいいんじゃないかな
俺が居ないとこのスレ回らないって知ってた? それから、元々アンチOOPのスレなんだぜ? 今はスレタイ端折りまわってこうなってるけどな。 OOPなんぞ、スレタイ考えるのもアホくさいってこったろ。
否定的なタイトルつけると OOPやったこともないような人が難癖付けにくるから こうしただけなんだけどね あと特にOOPに悪意は持ってないよ
いつもスレ立てご苦労様。
vtablevtableうるさいってことだよ
だけど、OOPの真髄はvtableだろ? 同時に一番のヘマだ。
>>95 誰も回してくれと頼んだ覚えはないのだが。
>>93 チューリング完全なら、実装方法が何であろうと計算能力は同等なんだからどうでもいい。
2chで長文書いてる暇があるなら少しずつでも実装しろよ 理想のOOPを実現するために 言語を作って本までだしたメイヤーさんを見習え せめて仕様書かけ。
プリプロセッサの要る要らないの話を永遠と聞きたいってのか? Q どっちのクラスに実装すべきでしょうか?A それは仕様を見ないと解らないね。 AやらBやらCやらDやら・・・ そんな展開だぜ? まー俺が来てから、俺の話題ばっかになっちゃったのはアレだけどな。
>>104 > Q どっちのクラスに実装すべきでしょうか?A それは仕様を見ないと解らないね。
それが一意に決まるなら設計・分析フェーズなんかいらんわな。
>>103 だけど、そういう人たちの熱い原動力ってなんなんだろうね。正直うらやましい。
まー実装するとしたら、インタプリタかトランスレータかJavaVMか.Netかネイティブかだけど、
最適化まで考えると、ネイティブはしんどいよなぁ。
まずは簡単なインタプリタで実装で良いかな。そんで言語仕様のアラを取ってから次の展開でも遅くはないよな。
コンパイラはエラー入力前提だから、山のようなエラーメッセージ仕込まないとダメだし、
もう、一生費やす勢いだな。俺にとってのItumonoになりそうだ。
プロジェクトファイル名もどうせ「Itumono」だろ?萎えるぜ。
そして、多分、完成しないよね。それが普通だと思う。
>>88 C++に多重継承はインターフェイスに限るなんて仕様は無いが。
「ワタシはjavaやC#もしりません」なんてことを書くんなら出てけよ。
何言ってんだか。 特にその、「インターフェース以外の多重継承」が要らない対象だろ。 ダイヤモンド継承乙
void f([HOGE*,HOGEEX*]); void g([FOOEX*,HOGEEX*]); void main(){ auto q = new HOGE(); f(q); g(q);//compile error auto p = new HOGEEX(); f(p); g(p); } 市ね。
ダックタイピングだってのに。 EXとか言われても、継承って概念が無いのにさぁ。 オーバーロードはあってもオーバーライドは無いのさ。 コードを使いまわすのなら、継承よりコンポジションだろ? 継承でのポリモは基底クラスが同じじゃなきゃダメってのが結構痛いんだよね。
だからちんこはとっととLispコンパイラ作れや
なんでLispなんだよw
Lisp処理系は実装が超簡単と言われている。 後は分かるな・・・。
Pascalのコンパイラなら書いたことあるぞ。 エラーメッセージ仕込むのがとにかく大変でな。 まーCもPascalと似たようなもんでしょ。 文法がアレな分、Cの方が大変そうだが。
void f(WndClassBase*); void g(IIconhaving*); C++での↑が void f(WNDCLASS*); void f(WNDCLASSEX*); void g(WNDCLASSEX*); void g(CWINDOW*); の動的オーバーロードでうまくいくと言っていたのは誰であったであろうか。
それだと、狭い世界で生きているんだなぁってことしか解らんよ。 とにかく、継承はないんだ。 やっても、インターフェイスの継承だろう。 インターフェイスの継承なら、ダックタイピングで十分間に合う。 テンプレートがその例だ。ただし、テンプレートは静的に結合しちゃうがな。
class WndClassBase{ public: virtual ~WndClassBase(); virtual f()=0; }; class IIconHaving{ public: virtual g()=0; }; こっちだったか。「C言語用に書かれた構造体を、手を加えずにポリモの対象に出来る」んでしょ。 でもこのくらいの類推が出来ないようじゃ失格もので・・・ でも失格者相手だから・・・
だからね、どうしても継承が欲しくて欲しくてたまらない人は、 永遠と俺のこと叩いてればいいんだよ。 俺はこう思ってるわけ。 ポリモを求める人は居ても、いまさら継承を求める人は居ない、と。 ポリモできるんであれば、継承は要らない、ダックタイピングならなお良し、と。 テンプレートのおかげでダックタイピングの便利さは一般にも広まった。 俺もテンプレートで学んだ。ダックタイピング、こりゃ便利だ。なにせ共通の基底クラスが要らないんだからな。 あとはこれが動的になればなぁ。まー普通の感覚だわな。
>>118 OO脳って怖いなって思う。
そういう風にしかもう考えられないんだろうか。
この例だと、
add_WndClassBase( &hoge );
add_IconHaving( &hoge );
要は、add_〜を呼んでフレームワークに 登録する/しない で、
その構造体のスペックが決まる。継承で決める訳ではないんだよね。
上の例では、f( hoge_t * )とg( hoge_t * )が定義されてないとリンクエラーだね。
class WndClass:public WndClassBase{
public:
WndClass();
virtual ~WndClass();
virtual int f();
private:
WNDCLASS wc;
};
class WndClassEx:public WndClassBase, IIconHaving{
public:
WndClassEx();
virtual ~WndClass();
virtual int f();
virtual int g();
private:
WNDCLASSEX wc;
};
でもItumono語でこれをするには
・「頭から型値を割り振る」(
>>27 )のをやめ全構造体で一意の数を型値を割り振り、
動的オーバーロードは配列を引くのではなくハッシュテーブルを引くようにする。
・「class pointer_t{ int type; void *addr; };」(
>>17 )を変更しtype1とtype2をもつようにする。
のどちらかを選ばなければならない。
ここまで書かれなきゃ屑だって分からんのがもうねえ。
>>120 実行時にadd_〜を呼んだかどうかで
コンパイル時にリンクエラーが発生するとか
そんな発想常人には無理だわ。
vector<auto *> g_wnd_bases; vector<auto *> g_icon_havings; add_wnd_base( auto *wnd_base ){ push_back( &g_wnd_bases, wnd_base ); } add_icon_having( auto *icon_having ){ push_back( &g_icon_havings, icon_having ); } void update() { //for_eachの仕様は適当。まだ定まってないからな。擬似言語。 for_each( g_wnd_bases ){ f( _1 ); } for_each( g_icon_havings ){ g( _1 ); } } ほらよ。 g_wnd_basesに突っ込まれりゃ「f」が呼ばれるし、 g_icon_havingsに突っ込まれりゃ「g」が呼ばれる。 ただそれだけ。対応するfやgが無きゃリンクエラーだ。 いたって単純。 継承がどうとかいちいち考えるから、頭がおかしくなるんだ。 ところで、型値はポインタ宣言ごとのローカルなものなんだけど、 ポインタからポインタへの代入時は当然型値の変換も行うんだぜ。 そりゃローカルからローカルだから、変換は必要だ罠。 だから、それ用のテーブルも作る。 グローバルな型値も、動的モジュールのロードに備えて、裏では持つだろうけど、 現段階ではポインタには持たせないつもり。
>>122 コンパイル時に解るだろ。
呼ばれる可能性があれば、呼ばれると判断する。
だから、if( false ){ add_〜 }
でも、add_〜は呼ばれるものと見なし、
対応する関数が無い場合はリンクエラーだ。
なに、これ、? もしかしてf(x)を呼ぶにはfのキューにxを登録してupdateがf(x)を呼ぶのを待つとかそういうなにそれこわい そもそもtypeid(HOGE)じゃなくて&hogeの時点でなんか変だとは……
>>124 > 呼ばれる可能性があれば、呼ばれると判断する。
そういうのはな、バグの温床って言うんだよ。
お前は静的型言語を何だと思ってるんだ。
本人が完成できないと自覚してるんだから わざわざレビューしてやることもないだろ
>>127 コードのどこかにadd〜という一文があるかないかでコンパイラの挙動が変わり、
しかも実行時にそこを通るか通らないかでプログラムの挙動が変わるとか、
迷宮入りのバグを量産する悪寒しかしないわけだが。
auto *を返す関数を遅延ロードするのに、 静的にリンカが型を解決してエラー吐くのは無理だろ。 どっちか諦めろ。 そんなことよりモジュール単位をデカくしようとする、 その方向性が俺には理解出来ん。
>>130 責務の分割を拒否する・・・というより責務という概念がないことによる当然の帰結だなぁ。
>>108 bool f((A*|B*)p){return true;}
bool f((B*|C*)p){return false;}
void main(){
(A*|B*|C*)p = new B;
f(p);
}
ダイヤモンド継承乙
多重継承で思い出したんだが Mixinってどうなの?はやってんのかな 実際に使ってる人いる?
boostにはゴロゴロない?base_from_memberとか。
>>base_from_member 検索してみたけどよくわからんかった Mixinとたんなる多重継承の違いってなに?
>>129 何言ってんの?
C++のテンプレートも触ったことないの?
それ以前に、
コードのどこかに何かが有るか無いかでコンパイラの挙動が変わるのは、当たり前だし、
実行時にどこを通るか通らないかでプログラムの挙動が変わるのも、当たり前だ。
挙動が変わらなきゃ、一体どうするんだよw。もうどうでもいいや。
>>130 コンパイル時にもリンクエラーを吐き、
動的モジュールロード時にもエラーを吐くのさ。
どっちか諦めるのではなく、どっちもする。
動的にライブラリロードして、目的の関数が無かった場合に
実行時エラーになるのは、当たり前の挙動だわな。CやC++でも同じ挙動。
読み込んだライブラリにバグがあったんだから、仕方ない罠。
それ以上はどうしようもない。
>>132 (A*|B*) と (B*|C*) と (A*|B*|C*) はそれぞれ別の型で、何の関連性も無い。
だから、f(p)はリンクエラーだね。
正しくはこう。
bool f((A*|B*)p){return true;}
bool f((B*|C*)p){return false;}
void main(){
((A*|B*)|(B*|C*))p = (A*|B*) new B;
f(p); //true
}
まーこんなコードを許すかどうかは言語仕様次第だが。
する奴居ないでしょ。面白いがな。
>>135 mixinをやる方法の一つが継承なだけで、マクロでできるのもあるし、言語によっては専用構文あるし。
違いはアップキャストを目的としないのがmixinと言えば良いのかな、
各ボタンクラスはButtonBaseを継承するのが単なる継承というようなものなら、
RectangleButtonクラスにRectangleクラスを継承させるのがmixin。おお、古くて新しいw
>>136 >上段
「要は、add_〜を呼んでフレームワークに 登録する/しない で、その構造体のスペックが決まる。」
とか言われたら普通は実行時にスペックが決まると思うがな。んで、
typedef (A*|B*|C*) IHoge;
で継承みたいなことができるのに継承は無い継承は無いと。
まあ、Itumono人は頭が悪いから聞く方が読み替えたり補ったりするべきとはそうなんだろうが。
残りは分割コンパイル不可能て話。
>中段
>>52 、
>>56 と同じ話。
(HogeA*|HogeB*|HogeCInDllWhichCreatedAfterThisProgramCompiled*)
>下段
プログラミング経験が無いのが分かっているのにも関わらず
itumono人がプログラミング経験を持っていると、あれだけでもう理解できると考えたこちらが悪かった。
>(A*|B*) と (B*|C*) と (A*|B*|C*) はそれぞれ別の型で、何の関連性も無い。
斬新な発想だ。
f(A*);
f((B*|C*));
g((A*|B*|C*)[3]ar){
f(ar[0]);
f(ar[1]);
f(ar[2]);
}
>>136 > C++のテンプレートも触ったことないの?
テンプレートに、そんなユーザを混乱させる機能があるとは初耳だが。
>>139 ちょっと具体的な混乱の例挙げてみてよ
無ければ無いで別にいいけど
>typedef (A*|B*|C*) IHoge;
>で継承みたいなことができるのに継承は無い継承は無いと。
あくまで共用体の扱いだからな。基底クラスが無い以上、継承とは言えんわな。
>残りは分割コンパイル不可能て話。
出来る出来る。その辺は最初っから考えてある。
まー、ライブラリロード時に関数テーブルやらの拡張処理とリンク処理が入るがな。
リンク処理相当は、通常のDLLロード時にも起こるものだから、
テーブルの拡張だけが、Itumono言語特有だな。
あともうややこしいから、適当な内部コードを今から書くよ。
どこかのアプロダにそのうちアップする。それで良いでしょ。
>>139 std::vector< hoge_t > hoges;
としたとき、hoge_tにコピーコンストラクタが無いと、
コンパイラはエラー吐くでしょ。
hoge_tのコピーコンストラクタが無ぇって。
それは、std::vecotr内で、hoge_tのコピーコンストラクタを呼び出しているからだ。
プログラマが混乱するってのは概ね当たってるんだけど、
コンパイル出来ないから、バグったままプログラムがリリースされることは無い。
そういう意味では、バグを量産するって事は無いな。
なんでこう自分が答えられると思うことに対してだけ答えて、 答えられなさそうなことにはだんまりを決め込むのかね。
>>137 >違いはアップキャストを目的としない
なるほどアップキャストかー
納得した。ありがとう
>>140 大量にあるコードのどこか、プログラマAが担当している部分:
//if (isHoge()) { ← デバッグ中で付けたり外したりしている
add〜();
//}
大量にあるコードのどこか、プログラマBが担当している部分:
hoge_t* a = ...;
f(a);
<プログラマA>: やっとバグが取れたぞ〜^^ 来週旅行行くからあとはよろしく^^
<プログラマB>: なんかビルドする度にバグが再現したりしなかったりするんですけど;;
>>144 いや、知りたいのはそこじゃなくて、答えられないのにもかかわらず
自分のほうがよく物を知っているんだという態度をとり続けているとこ。
(A*|B*)foo1();
(B*|C*)foo2();
(C*|A*)foo3();
void hoge(){
(A*|B*|C*)p1 = foo1();
(A*|B*|C*)p2 = foo2();
(A*|B*|C*)p3 = foo3();
}
>>123 >ポインタからポインタへの代入時は当然型値の変換も行うんだぜ。
らしいけどハッシュでも引くらしい
あーと、collectionはs要るんだっけ? つけてねーや。忘れて。
>>147 見れば単なるオフセットの足し引きじゃ実装できないと分かるやろに。
それとも(A*|B*)から(A*|B*|C*)へのキャストは出来ないと?
> あと、例のバグ大量君はもう無視でいいでしょ。もうわけわからん。 ^^;;;
マルチメソッドはどこいったのか
>>136 >遅延ロード云々
auto *func()が遅延ロードされるとき、
pfunc = dlsym(dll, "func");
auto *p = pfunc();
local_func(p);
なるコードで、静的に動くリンカは、
・pの型をどのような共用体(的な何か)として解釈するか
・local_funcをどのように解決するか
世間では遅延ロードの有無によらず
実行時に解決だと思うがどーか?
>>151 > Bertrand Meyer : "OO入門"はOOの聖書. 絶対に読むべき.
らしいから別人じゃね?
素のCでOOというと今は亡きSUNのXViewを思い出す(w
>>153 欲しい?でもコード見れば何時でも対応可能なことは解るよね。
ここまで下地がありゃ後はどうとでもなる。
そして今悩んでるのはこれ。
auto *p;
p = (a*|b*)NULL;
p = (b*|c*)NULL;
のとき、pの型を
( a* | b* | c* )にするか、
( (a*|b*) | (b*|c*) )にするか。
前者はポリモ時のオーバーヘッドが少ないが、文法に整合性がない。汚い。
トップレベルの共用体に限り、纏め上げられる、とか、適当なただし書きが必要だからな。
加えて、ポインタ代入時に型値変換も必要。
後者は分法に整合性があるし、直感的。
型値変換も必要ないし、コンパイラ書くのも楽。
ただし、ポリモ時のオーバーヘッドがデカイ。
加えて、ポリモが何か気持ち悪いことになる。
逆共用体化演算子とかも用意したくなるしな!
記号は@が良いだろうな。あーややこし。プログラマの混乱の元になりそうだ。
>>154 ロードしたときに、auto *pの型が拡張される。
具体的には、型値変換テーブルと、関数テーブルが拡張される。
加えて、local_funcの有無もロード時に確認する。
ランタイムにそれなりの仕込みが必要なんだけど、
ロード時にリンクエラーやらなんやら事前に調べてくれたほうが
プログラマは嬉しいだろう。
それから、向こうのスレの人は俺しらねーぜ。 そのスレ自体しらん。今から読んでくる。 ・・・読んできた。 リファクタリングの本だけ読んだことあるなぁ。 えらい分厚いくせに、そのほとんどがコード例で、しかも当たり前のことしか書いてない奴。 たしか、結構なお値段だったような。俺は研究室に置いてあったから、タダ見だが。 読まなくても解ってる奴は解ってるし、 解ってない奴は、読んでも解らん。そんな類の本だった記憶が。 あ、Rubyは美しいとか言ってるw Pythonねぇ。selfはキモイだろう。 構造体にCスタイルの関数を突っ込めます。第一引数は自動でわたりますってアイデアは悪くないのだが、 なにか釈然としない。 全部読むと頭がおかしくなるからもう読まない。大分マズイ方向へ行ってる人だね。
>>150 >>148 で上げたデモで、まったくそのまま、それをやってるよ。
テーブル用意して変換してる。
なんかOOPって深くやればやるほどめんどくさくなるよねえ。 再利用とか隠蔽なんかしなくていいから、俺はパッと見てわかりやすいソフトが作れればいいや。
>>161 規模の大きなソフトウェアや、メンテナンス時に地獄を見る発想。
俺はパッと見てわかりやすくするための、 隠蔽なんだがw で、それをするってことは、その単位が再利用しやすくなってるわけで。
166 :
デフォルトの名無しさん :2010/11/18(木) 10:06:51
さんざんテンプレートやら型推論、ダックタイピングがどうのこうの言ってたのに いまさらパッと見で分かりやすいとか言われてもね
本当は静的型とOOPは互いに独立したモジュールであるべきだった しかし、言語レベルでOOPをサポートし、それをしない言語との差別化をはかるために 静的型レベルのOOPが生まれた
>>167 ALGOLで十分だったということかな?
しかしjavaもc++もobjective-cもだいたいマルチパラダイム
170 :
168 :2010/11/18(木) 11:10:03
ぱっと見てわかりやすい云々はいつもの人が言ったんじゃないから。 それはそうとして、コード上げたら叩かれなくなった。 やっぱ手を動かした人は批判の対象になりにくいのな。 何事も口先だけじゃダメってことか。 そんで、色々考えたんだけど、 ポインタ代入時にいちいち型値変換するのもあれだなぁと。 だから、 auto *p; p = (a*|b*); p = (b*|c*); のとき、pの型は、(a*|b*|b*|c*)と推論されることにしようと思う。 この場合、b*が重複してて、その分関数テーブルが少しでかくなるが、 型値変換を単なるオフセット計算で済ませられるのは美味しい。 それから、共用体風に拡張できるのもポインタに限定してしまおうと思う。 だから、(a*|b*)じゃなくて、(a|b *)になる。 ポインタの指す型は複数ありえますよって意味合い。 そんで、型持ちポインタと普通のポインタも明確に区別したい。 だから、型持ちポインタは*でなくて、@を使おう。 auto *p; //型自動の普通のポインタ。推論される型が複数ある場合はコンパイルエラー。普通のポインタ。 auto @p; //型自動の型持ちポインタ。推論される型が複数でもOK。 とてもわかりやすくなったね。 あんま複雑なことしても意味ないし、これで十分かな。
>>171 > それはそうとして、コード上げたら叩かれなくなった。
> やっぱ手を動かした人は批判の対象になりにくいのな。
> 何事も口先だけじゃダメってことか。
だから最初からずーっと言われてたろ。仕様書上げろって。
プログラマにとってはコードや仕様書が何より説得力のある言葉なの。
>>164 作る機能単位ごとに分割して作れば規模が大きかろうと小さかろうと別に地獄など見ませんが。
バグがあってもどの機能の中のどの部分かは仕様で決めてあるので場所を絞り込めるし。
OOP以前から普通にやってたことだと思いますけどね。
>>174 上2行はOOPでやればよりやりやすいというだけ
批判派の人はよく「OOP以前もやってた」というけど
OOPはOOP以前の手法を土台にしてるんだからあたりまえのこと
>>174 > バグがあってもどの機能の中のどの部分かは仕様で決めてあるので場所を絞り込める
簡単に書いちゃってるけどすっげー難しいんじゃね?
>>175 機能単位に分割するのと、オブジェクト単位に分割するのは
まったくの思想ではないか。
178 :
177 :2010/11/19(金) 09:28:10
"別の"思想
>>174 マジレスすると機能単位はシステム工学で一番やっては駄目な方法。
システム工学では機能単位では無くデータ単位に行なうが良いとされている。
オブジェクト指向はもちろんデータにそれ専用の機能だが
構造化でもPOAよりDOAが優れている。
>>177 「機能単位」の粒度にもよるけど
まったく別ってことはないと思うな
>>179 >>164 をどのように評価するかだ。
大きいことが悪いのだ、という評価もあるわけだから。
>>171 何傘?
結局のとこItumono人がItumono語の初心者から初級者への道を一歩進んだだけやん。
>>132 まで戻って実体の多重継承はItumono人が理解できる段階に進んだだけで何か解決したこと無いし。
注意して使えば問題ない?C++が多重継承を残してるのは注意して使えば問題ないからやの。
れとも実体の継承を禁止、
f(A*);
f((B|C*));
g((A|B|C*)p){
f(p);
}
を禁止してるのか知らん。
>>173 sys.environment.value["PATH"] += ";C:\hoge\lib";
append(find(value(environment(sys)), "PATH"), ";C:\hoge\lib");
え〜173は下派に鞍替えったの?
>>171 言葉で言っても理解できないじゃんあんた。
auto fp = ((HogeA|HogeB|HogeCInDllWhichCreatedAfterThisProgramCompiled*)(*)())dlsym(dll, "func");
これは無理で
auto fp = (auto@(*)())dlsym(dll, "func");
auto@で受けなければならないとはわかるな。じゃあ
auto f1p = (auto@(*)())dlsym(dll, "f1");
auto f2p = (void(*)(auto@))dlsym(dll, "f2");
f2p(f1p());
変換テーブルを作ってみろ
>>158 >逆共用体化演算子
ダウンキャスト言え。
>ロード時にリンクエラーやらなんやら事前に調べてくれたほうがプログラマは嬉しいだろう。
実行時の自己書き換えやテーブルでCPUキャッシュを使い込むのをやめてくれたほうがうれしい。
大卒!?論文を読み論文を書くことが教えられる場所にいてああなの?
OO、生産性やソフトウェア工学のの論文や研究者なんて山ほどあるだろに。
あんたにとって教授の言ったことが全ての世界なの?
OOはメッセージングである、という世界しか知らずに育ち、
その外側では過ごしたことが無くほとんど知らないから、
前スレでは藁人形叩きをやって、ポリモとかいう誰も使わない省略形を使って、
>>183 の下派なのか。
子供なら社会の被害者とかいうけども、もう一介の社会人なんだからただの
>>184 まず初めに断っておくけど、
関数を一つ一つ手動でロードするスタイルはとらないつもり。
load_lib( "lib.dll" );
こんな感じで一気に全部読み込む。
そんで、プログラムを再リンクする。そのとき、変換テーブルや関数テーブルも拡張する。
だから、ごく軽い再コンパイルのようなことが起こる。
ので、dllからのロードだからって、変な制限とかが付くことは無い。
だって、最コンパイルするんだからな。ある意味なんでもあり。
といっても、コードを最コンパイルする訳ではないぞ。あくまで、各種テーブルを拡張するだけ。すぐ終わる。
だから、再リンクと言ったほうが適切だな。
再リンクに必要な型推論の型の伝達関係は、予めdllに仕込む。
Itumono仕様のdllには何か特殊な環境取得関数が仕込まれてて、
load_libはそれを呼び出して、型の伝達関係etcをもらう。
環境取得関数の無いItumono仕様でないDLLをload_libすると失敗する。
Itumono仕様でないDLLはCスタイルで読み込むことになる。
その場合は型推論やポリモは適用されない。問題ないだろう。
俺にはまるでわけわかめ
189 :
デフォルトの名無しさん :2010/11/20(土) 06:23:59
もう一週間終わっちまったぜ
プロトタイプベースはクラスの概念ないってよく聞くけど 継承の仕方が特殊なだけでクラスは使ってるよね プロトタイプベースの言語はjavascriptしかしらんけどさ
そりゃ概念は言語とは無関係だからな
>>190 プロトタイプを使ってるからクラスは確かに存在しないはずだが
>>192 クラスそのものとまでは言わないけど
(javascriptの)コンストラクタはクラスみたいなものでしょ
似てるってことは違うってことじゃん?
>>195 >設計図そのものは親のインスタンスに求める
継承してるインスタンスはこのイメージですんなり納得できる
でも継承元のインスタンスを作るときは構成を書き出さなきゃならんわけでしょ?
呼び名が違うだけで「オブジェクト初期化子」も「コンストラクタ関数」も
クラスと(設計図としての)役割は変わらないと思うんだよね
もちろんクラスそのものじゃないから、いろいろ違いがあるのはわかるけどさ
>>196 ちょっと暴論かなぁ、と思う。
JSはそれほど知らないんんで間違えてるかもだけど、
JSのコンストラクタは手続きを記述出来るだけで型を定義しない。
クラス構文は型を定義する。
JSのコンストラクタ(等?)を使ってプログラマはオブジェクトに
クラス型を持っているかのような振る舞いをさせることができるけど、
クラスに関する言語のサポートはなくて、自前で実装する必要がある。
結局クラスまわりの構文さえサポートすれば、 実装が連想配列のコピーでもクラスベースな気がする
それはその通りでしょ。 言語のパラダイムはソースコード上の表現の話で、 処理系の実装は関係ない。
クラスベース言語の利点としてメタクラスが使える。 クラスの概念があるからメタ化出来る。 これによりオブジェクトを高度に抽象化出来る。 これがプロトタイプベース言語では出来ないと思っているが 俺が知らないだけで出来る言語もあるかもしれないが。 (インタプリタは言語の仕様上難しいような気がする) クラスはオブジェクトを作るだけじゃなく高度な多態性を提供してくれている。
まーどうでもいいよね。 メタ化は研究者のオナニーみたいなもんだし。
プロトタイプベースのクラスベースに対する最大の差異は、 「制約がつけられる」か否か、なのではないの?
メタ化は、javascriptを出力するcgiみたいに、文字列ベースでやるのが一般的。 OOPはなぜか文字列を敵視したり型理論を信奉したりしている。
>>203 その理屈で行くと、既存の処理系の上に俺言語的(DSL?)なものを構築するのもメタって言うのかなぁ。
>>204 が何をイメージしているのか良く分からないけど、
「メタプログラミング」っていう言葉はあるよ。
まーC言語も機械語に対するメタ言語だしな。 メタプログラミングって何の意味も持たない言葉だな。 文字列ベースのメタプログラミングの話が出てたけど、 Cのマクロって確かに便利なんだよな。なんでもありで。その分危険だが。 そして誰も興味ないよ、この話題。 どうせ、メタ言語の、そのまたメタ言語も必要かどうかって話になって終わるに決まってる。
>>203 メタっちゃメタなのかもしれんが, 手法的には全然柔軟性に欠るよな.
新しいシンタックス導入するの大変だし...
CL や scheme の macro は文字列ベースじゃないけど, 遥かに柔軟で扱いやすい
>>204 メタの定義をプログラムを吐き出すプログラムって意味とするなら, メタじゃないか?
>>206 抽象化されたアセンブラでって意味ならそうだが, メタプログラミングとは言わんと思う
C++ のテンプレートメタプログラミングなんて, とても涙ぐましい努力をしていると思う
# メタプログラミングにマッチした文法じゃないんだよ, 手続き型ベースの言語は...
メタプログラムとメタクラスは別物なんだが。
メタプログラミング=プログラムを生成するプログラム 通常はコンパイル時の問題、少なくとも トランスレータ、マクロやテンプレートのようなものを利用したものはそう メタクラスはただのクラスのクラス、クラスはメタクラスのインスタンス 実行時のオブジェクトとして普通に扱えるもの メタとか言っても全然違いますよ Lispは強力なマクロ(メタプログラミングの道具)を備えていると同時に メタオブジェクトプロトコルも備えている Javaや.NETのような言語のごく普通のユーザも、リフレクションや イントロスペクションの恩恵に当たり前に浴している 別になんも難しくも無いし怖くも無いよ
>通常はコンパイル時の問題 とは書いたけど、勿論実行時のメタプログラミングも可能で evalがあればごく簡単 Cのような言語では、実行可能なメモリ領域に機械語を書き込むような形になるけど そうそう、データについてのデータをメタデータと言いますね
モノに指示を与える概念で書ければわかりやすいよというシンプルな話だったはずなのに いつの間にか仮想とかメタとかめんどくさいものになってしまった。 こんなんじゃこれ以上普及するはずがない。
めんどうくさいことになったのは、元の発想が間違っていたからかもしれない、と気づけるかどうかだな。 設計屋してたらわかるでしょ。変な事したら面倒なことになってくって。 もっとシンプルでも誰も困らないのにな。 どうしても本を売りたいらしい。
OOPの本質が仮想とかメタというわけじゃない シンプルに保ちたいならそうしたらよい。
ちなみにOOPの本質って何ですか?
異論は出ると思うが カプセル化じゃないか? 実装の隠蔽
もうちょい広く、抽象化だろ。
・フィールドを隠蔽する ・メソッドをオーバーライドする いずれにせよ、名前空間か辞書のようなものを操作している。
>>215 他の多態性や継承と比べて何が利点だと思うことは?
あとOOP歴とその内容(規模や開発が新規がメインか改修がメインかなど)を教えて。
多分OOPをどうのように活用しているかで本質と思うものが変ってくると思う。
俺はOOPで大規模なプログラムを5年以上改修しているから
差分プログラムがOOPの本質だと思う。
抽象化も差分プログラムの為のツールの一つだと考えている。
新規がメインの人は、複数の人間との並行作業が続くから
影響されにくい「実装の隠蔽」が大事だと思うだろうし
そもそも差分プログラムを行なう機会も少ないはず。
>>218 以下はクラスベースの話ね
よくOOPの代表的な機能として
カプセル化、多態性、継承の三つが上げられるけど
多態性と継承はカプセル化(クラス)あっての技術
カプセル化を使用しなくても多態性と継承は実現できるかも知れないけど
クラスベースの言語でわざわざ別の手法は使わないだろうし
何が利点かというよりもこれがなければ始まらない
そういう意味でOOPの本質はカプセル化
>OOP歴とその内容
5年くらいで、新規がメイン
全部publicでも、継承や多態は出来ると思うけれども。 クラスがそれらを同時に提供するからそのように使うだけで 「クラスベースの本質はクラス」以上のことは言えてないように思う。
malloc/freeの抽象化じゃないかな?
「隠蔽することが本質」か「委譲することが本質」かという問題だが いずれにせよ、オブジェクト指向の本質を動詞一個だけで表現するやつはアホだ
>>219 考えは分かったけど、俺とじゃカプセル化の考えが少し違う。
カプセル化は構造化言語でも一部の言語では導入している。
構造化言語+カプセル化=構造化言語とされているが
多態性、継承は構造化言語では導入されていない。(多態性はOOP的狭義な意味の方で)
多態性、継承をは構造化言語に導入するとそれはOOPに近く構造化言語では無いと判断される。
構造化言語+(多態性、継承)=オブジェクト指向言語と考えられる。
話が長くなったけどつまり、カプセル化自身がOOP特有の機能ではないと思っている。
OOP特有の機能でもないものがOOPの本質と言われても...、となる。
> 5年くらいで、新規がメイン
それだと自分で作ったクラスの継承もほとんどしないでしょう。(共通クラスの継承とか別にして)
改修をメインにやっていると品質が一番になってくる。
デグレードが一番嫌われし、その為にOOPを活用すると別の側面(本質)が見えてくると思う。
ひたすら複雑に考えるのが好きな人がやるのがOOPなんですね
カプセル化+動的ディスパッチ、ということでいいのではないかなあ
動的型言語では動的ディスパッチは当たり前なので、やはりカプセル化のほうに
本義があると思う
ISA継承は静的型言語で動的ディスパッチを実現するための仕組みの一つに過ぎないよね
http://en.wikipedia.org/wiki/Object-oriented_programming ここにも
Object-oriented programming (OOP) is a programming paradigm that uses "objects" data structures consisting of data fields and methods together with their interactions to design applications and computer programs.
と書いてある
public staticとprivate staticは非OOと実質同じだから、 public/privateよりも、「staticではない」ことが重要。
>>220 >全部publicでも、継承や多態は出来ると思うけれども。
「フィールドをすべてpublicで公開しないこと」はカプセル化に含まれるが
それが全てではない
>「クラスベースの本質はクラス」以上のことは言えてないように思う。
言われて見ればそんな気がする
>>223 OOPに特有かどうかをOOPLと非OOPLで比較するのはいかがなものかと
>>225 それは特徴が書かれていると思う、日本語の「本質」とは意味が違うよね?
あと、全体的にOO・OOP・OOPLの話が混じってない?
信者どうしで潰しあいするのが彼らの特徴です。 放っておけば、喧嘩し始めます。 なぜか?定義が無いからです。議論すら成り立ちません。 つまり・・OOに「本質」は、有りません。 しいて言えば、オブジェクトをフューチャーすること。 その程度です。
まーこうなるの解ってて、OOPの本質は?とか聞いたんだがな。 この不毛なやり取り、これが現状ですよ。
そうやって「なぜなぜ坊や」を一生やってれば?
>>218 てか、利点がつまり本質であるわけではないので、
それは「OOPする目的」を聞かないと。
そもそも聞いているものが違う。
本質とか言い出したのは俺じゃないから。 >213 名前:デフォルトの名無しさん[sage] 投稿日:2010/11/22(月) 08:17:01 >OOPの本質が仮想とかメタというわけじゃない >シンプルに保ちたいならそうしたらよい。 彼がそういうから、じゃ、本質って何?って聞いたんだが。
OOには色々疑問点があるかもしれないが、OOPL上で利点を使ったOOP は良い物だと思うぞ。仮に無理矢理答えてみると。 本質? ≒ 過去の経験から出てきたノウハウを有効に使える、1つの方法論。
データの分割統治を明示的にやれることじゃね 一言で表す言葉はないんじゃないかな あったら「[本質]指向」と呼ばれてる
>>234 過去の経験とは、非OOPの経験のことだろ
いわば、猿が進化して人間になった
不満があるとすれば
猿と人間の境界がはっきりしないことと、進化の仕方が何通りもあることだろう
じゃーC言語はサルで、OOは人間ってこと? でもこの前テレビでやってた番組では、 チンパンジーは「物」にしか興味を示さなくて、 一方人間の赤ちゃんは人間の「行動」にも興味を示すんだってさ。 人間は行動を理解できるから人間・・・ 行動・・関数・・手続き・・・アレアレ? チンパンジーは物しか理解できない、行動は理解できない猿頭・・・ アレ?オブジェクト指向?進化?なにそれ。 アレアレアレ?進化って退化の事なの?
静物が構造体で自意識を伴うのがオブジェクト、かな 言葉遊びしたいなら経験則のない世界行った方がいい
猿とか人間とか、進化がどうとか言い出したの俺じゃねーし。 またこの展開かよ。
>>237 物を物としか捉えられないより
物と行動を結びつけて両方に着目出来るほうが
進化してると思うぞ
だけど、 物→行動 じゃなくて、 行動→物 でしょ。
それは表記法の話? OOP自体には表記法の順序は関係ないぞ
>>237 物は「物」単体でしか捉えられないのがサルの赤ちゃん
人間の赤ちゃんは「物」に加えて「物の行動」にも興味をしめすんだろ?
OOP的なのはどっちなんだろうな
概念記述が目的の道具なんだから、「物=物理的な物体」なんて前提は無意味。
物の行動じぇねーよ。他者の行動だよ。 だいたい、物の行動ってなんだよ、意味わかんねぇし、物が動いてたら、チンパンジーだろうと人間だろうとそりゃ興味示すだろ。 そういうことじゃない。 人間の赤ちゃんは、 「他人」の動作を真似するのな。 他人がfunc( obj1, obj2 )してたら、自分もfunc( obj1, obj2 )する。funcって面白そうだなーって同調するのな。 物そのものよりも、funcに興味を示す。だから引数も道具として複数取りうる。 funcが目的で、objは道具なんだ。 一方チンパンジーは、物を投げてその跳ね返り方とかを見たりして喜ぶ。 まさにobj.action()って感じだな。これは何だろうの世界。 なんだか解らんからとりあえず投げてみる猿頭。 ちなみにチンパンジーは他のチンパンジーが居ても同調せず、我関せずらしい。 手渡されたオブジェクトに夢中w有る意味し合わせ。 俺にも経験あるぜ。クリスマスプレゼントに何かもらったら、もうそれに夢中なのな。 でもしばらくすると、だんだん飽きてきて、これ、他のことにも使えるんじゃないかって模索し始める。 obj.method()からfunc( obj1, obj2 ) に思考が切り替わった瞬間だな。
つまりね、それが「創造性」ってこと。
obj.method()ならコード見ただけで何やろうとしてるか想像しやすいが、 func( obj1, obj2 )だとどういう動作するのか把握しにくい。 中で何やってるかわからないとそれを知るために追いかけていかなきゃなんなくなる。 デバッグしたり改変するのに必要だからね。 書いた人間だけがわかりやすいと思って書いたコードを保守させられるのは苦痛。
複数オブジェクト間に跨る処理は複雑だってことでしょ。 でもそれ、OOPでも関係なくない? 全ては要求仕様で決まることでしょ。
詭弁の特徴のガイドラインでも張っとくべきなんかな。
>>247 何々を何々せよ。という構造が一番
わかりやすいから、命令文は
そうなってるのではないか?
>>250 はたとえば「1 2 +」が一番わかりやすいと主張するのかな?
obj.method()かfunc( obj1, obj2 )なんてのはOOPとは関係ない 表記法の事で議論したいならよそでやれよ
>>251 obj.method() は objをmethod()する、と読めるし、
func(obj1,obj2) は obj1,obj2に対してfunc() しろ、と読めるし、
1 2 + は、1 (に) 2 を + しなさい、読める。
述語の位置が前でも後でも意味は明解。だから、端的に意志を伝えたい
命令形はこうなる。ここにあげた三つのパターンのどれにも優位性が
あるとは思えない。
forthの表記法って日本人には解りやすいと思うけどな
どっかの日本語プログラミング言語もFORTHをベースにしてたっけね 確かに相性は悪くないと思うが、プログラミング言語界ではちょっと異端な仕様なんだよな
表記法は、宗教的儀礼なのだ チンパンジーは神を信じないが、人間様はそういうことにこだわるのだ
いや判らんぞ。チンパン神とか言う神を信仰してるかも知れん。
>>247 それは、OOPLのよくある表記法がそうなだけで、OOPがどうかって話じゃない。
>書いた人間だけがわかりやすいと思って書いたコードを保守させられるのは苦痛。
これ自体は同意だけど、結局前任とどれだけセンスが似てるかの問題だと思うよ。
代表的には演算子のオーバーロードとか。
大事なのはモジュールの独立性なんじゃないの?
クラスの独立性 + メタクラスの共通性 という人もいるし extern "C" のように低レベルの共通性があるからメタクラスいらねぇという人もいる 表記にこだわるのは前者
構造体の初期化関数と開放関数を押し進めたらOOっぽいスタイルになっていくよね 外からは初期化関数呼べば実装はどうあれ初期化できる 多態だって、外から関数呼べば型はどうあれ適切に動作する、と その中と外をばっさりやらせるのがOOPL、という程度の認識
>>260 オブジェクトは作成時からデータの整合性がとれているから
それだと外部からコントロールされる受動的なイメージになるから違うと思う。
オブジェクトは能動的だと思う。
ふつうのオブジェクト指向言語では、大抵のオブジェクトは受動的だろ 能動的に動作する「もの」とその関連で構築されるのは、 プロセス計算とかアクターモデルとか言われるものだけだろう JavaやC#あたりの言語では、スレッドに対応するオブジェクトだけが能動的で、 他は全部そこから呼ばれる側だから、受動的と言える メッセージパッシングがただの関数呼び出しだしな 少なくともそうした言語でのstackやqueueを能動的なオブジェクトと捉える人は いないんじゃないの
>>281 初期化前には触らせない、ってのはOOPLが押し進めた部分ということで
受動的か能動的かは別にして(言葉の問題な気がする)、自律的ではあるね
Cでも
>>260 で同じことは出来るだろ
>>260 の言う「初期化関数」が生の型ではなくいわゆるopaque pointerを返し、
操作はそのポインタと操作関数を通して行うようになっていれば、
カプセル化/data abstractionは容易に達成できる
つーか、よくある「ハンドル」の類は全部それだ(stdioのFILE*はモロ出しだが)
その程度ならOOPLに限った話ではないよ
>>262 オブジェクトを受動的に作るのは違うと思う。
「能動的」か
>>263 の言うような「「自律的」や「主体的」(いろいろ言葉はあるが)に作る。
外部よりコントロールされないように作るもの。
>メッセージパッシングがただの関数呼び出しだしな
メッセージパッシングは、メッセージの通知で手順になってはいけない。
「最初に初期化してから、その後機能1を実行する」など
メッセージに手順が入り混んではいけない。
手順が入り混むと、外部から受動的に操作される。
だから、メッセージパッシングを
単純な関数呼び出しと同じに考えるのは違うと思う。
>>265 それはオブジェクトをデザインする場合の指針の話で
上のはオブジェクトというものの定義や性質、あるいは(言語レベルの)実装の
話じゃないの
ちょっと次元が違う話のような
「手順になってはいけない」は大いに結構だが、
実装として、C++の系統の「オブジェクト指向言語」においては、
それはただの(場合によっては動的ディスパッチつきの)関数呼び出しだろう
いや待ってよ。 obj.method()とfunc( obj1, obj2 )は、表記の問題でしかなく、意味は等価だって言ってるの、 わかるんだけど、必ずしもそうとは言い切れなくない? センスがどうとかじゃなく、もっとほら。何か違うでしょ。 多くのOOPLは単一ディスパッチなので、、多態は、第一引数に基づいてのみ、行われる。 だから、第一引数だけ、「特別」なんだよ。 obj.method()とfunc( obj1, obj2 )の違いはそこなんだ。 前者は、メソッドがobjに関連づく。メソッドにとって、objは特別なもの。 後者は、関数はobj1とobj2を等価に扱う。obj1とobj2のどちらに属すると言うものでもない。 あくまでfuncが目的で、その道具として、引数にobjを取る。 そこらへんの思考形態の違い。 百歩譲っても、OOPはマルチメソッドじゃなきゃおかしいんだよ。 JavaとかC++とかはどうかしてる。 人間の思考形態を退化させる洗脳装置だよ。あまり関わるな。 単一ディスパッチなので、単一のオブジェクト/クラスにメソッドが関連付けられるから、 どうしても思考回路が物中心になる。だから、「オブジェクト指向」なんて言われる。 だいたい、第一引数だけ特別扱いすることに、何の整合性がある? 引数は、第一だろうが第二だろうが、等価に扱われるべきだろ。それが自然だろ? 不自然なことすると、どっか歪んできてやがては破綻する。しわ寄せが出来る。 ちなみに、C++やJavaが単一ディスパッチなのは、それが便利だからじゃないぞ。 単にパフォーマンス上の理由と、コンパイラ実装コストからの物だ。 基底クラスを使っての多態もそう。 要はそれが手っ取り早かったってだけ。 出来るなら、ダックタイピング+マルチメソッドの方が便利に決まってる。 ちなみに、慎重派のLISPer達は、CLOSでマルチメソッドにしてる。流石だな。
>>266 構造体と関数だと手順になる。
260 >外からは初期化関数呼べば実装はどうあれ初期化できる
の「「外から」が手順になってしまう。
オブジェクトは作成時からデータが初期化されているから
いつでも「オブジェクト」ならメッセージパッシング出来ると思う。
『注意、えさを与えないでください』
久々にメッセージパッシングが話題にあがったな オブジェクト指向に出てくる言葉の中でこれが一番わからん。 単なる関数呼び出しとの違いはなんなの?
>>268 意味が分からん
初期化関数というのは、コンストラクタと等価だぞ?
初期化関数を呼ぶ前はオブジェクトがなくて、関数がオブジェクトをこしらえて、
それを返す
fopen()を考えて欲しい
C++系統のOO言語だと、たとえば Stack stack; stack.push(x); のように書く Cのような言語では関数名の衝突を避けなければならないので、 通常もっと長い名前が必要になる stack_t stack = create_stack(); stack_push(stack, x); のような感じになるだろう ここで典型的なclass指向のOO言語のclassが、少なくとも 適度な名前空間としての機能を果たしていることが分かる 表記の違いではあるが、名前の衝突を気にせず短く書けていいですね、というわけだ
273 :
272 :2010/11/23(火) 19:28:47
ところでC++にはオーバーローディングの機能があり、静的に決定可能な 関数呼び出しについては、型のパターンマッチをコンパイラが行ってくれるので、 非OO的に記述する場合にも、長い名前を使う必要は無い、つまり stack_t stack = create_stack(); push(stack, x); のようなインタフェースであっても問題はない 「コンストラクタ関数」だけはパターンマッチは効かないが、 操作する関数については、どこかにある void push(stack_t stack, int x); のような関数を、コンパイラが探してくれるわけだ push()という(短い)名前は勿論衝突するかもしれないが、 引数の型が違えば別の関数として扱われるので、問題は無い よって、オーバーローディングを持つ静的型言語であれば、 クラスの提供する名前空間が実は必要が無いことがわかる
C含めたプログラミングの歴史から得られた 望ましいモジュール化・抽象化の表現を推奨するのがOOPであって、 Cではできない革新的な何かを目指すものじゃないんじゃないかな
275 :
272 :2010/11/23(火) 19:30:04
これはコンパイル時ポリモーフィズムの一例で、 「全ての引数について」ディスパッチが行われているという点では レシーバのみに適用される動的ディスパッチ(C++系のOO言語で 言われるところの「ポリモーフィズム」)よりも優れているとさえ言える このパターンマッチを実行時に拡張すれば、全ての引数についてのディスパッチが 可能であることは容易に理解できる 実行時型情報をサポートする言語であれば、特に実装上の問題も無いだろう 関数探索はハッシュテーブルのルックアップのような形を 取らざるを得ないだろうから、効率面ではvtblに劣ると考えられるが 特定の関数呼び出しにおいて実行時ディスパッチを行うかどうかを 何らかの方法で指定可能であれば、特に大きな問題は無いように思える
276 :
272 :2010/11/23(火) 19:31:03
以上、Itumono人の主張らしきものをまとめてみた 俺はスレの住人ではないのでいい加減だがw こんなもんで合ってるのかな
277 :
272 :2010/11/23(火) 19:40:27
ちなみに俺の考えを言うと、大筋では理解できるし同意するが、 C++のISA継承とvtblによる「ポリモーフィズム」とこの方法の違いは、 C++の「ポリモーフィズム」は探索に失敗することはない、すなわち 呼び出せる関数が存在することが保証されている点にある この点について適切な解決策を出せないのなら、静的型言語でありながら、 動的型言語のように実行時エラーが連発するという結果に終わる 一方動的型言語ならどうかというと、その種の引数には型を指定しないのだから この種の「引数型によるディスパッチ」がそもそも不適当になる 最後に、現状のC++流儀のOO言語が、IDE(主に補完機能)と非常に 相性が良いことは知っておく必要があるだろう(C++自身は別だが)
>>271 コンストラクタはクラスの機能だから
「オブジェクト」間の呼び出しは手続きにはならないと思う。
OOPだとクラスとオブジェクトが分かれているけど
関数だとその区別がないから駄目だと思う。
オブジェクトは処理途中の状態を外に見せずに、 データの整合性を保っていろんなメッセージに対応できるようにしておくべき、って話ならわかる モジュールの理想方針としては妥当だろう でも「クラスとオブジェクトが分かれてるけど関数だと区別がないから駄目」云々ってのは 日本語として意味がよくわからん
>>278 もはや何を言いたいのやらさっぱりわからんな、話がどんどん横道に逸れているし
だからカプセル化はCでも出来るんだってば
構造体と関数を使う場合であっても、
内部で使う構造体定義をヘッダに書いて外に見せなきゃいいだけ
そうすりゃ中身を弄りようがないから
構造体の定義は.cに書く、あるいは複数のソースで使うのなら、
internalな、外には見せないヘッダに記述する
fopen()だのCreateDIBitmap()だのと
コンストラクタによるオブジェクト生成で、本質的に何が違うと言うの、
同じだろ?
データの中身を見せないのなら、その一貫性も外に見せる関数によって
保てばよい、そこで考えればよいということになる
C++との本質的な違いはコンストラクタではなくて、
デストラクタを自動で呼び出してくれるかどうかと、
opaqueな(外には見せない)型の場合はオブジェクトをスタックに配置できない
ことぐらいだよ
多分コード上で表現出来るかどうかを重視してんじゃないかな。
個人的には
>>280 寄りの意見。
OOPの考え方そのものは言語から切り離せるもので、
不完全だったりプログラマが気をつけることが増えるにせよ、
非OOPLでも実装は出来る。
ただ
>>266 とはちょっと違って、スタイルが似てるからって、
「オブジェクトたるか?」どうか考慮してないモジュールは
オブジェクトじゃないと思う。
>>280 関数fopen()と関数fread()の場合は、
fread()呼び出し時にファイルオープン済みであることを保証できません。
fopen()を呼んでからfread()を呼ぶという手順を知っている必要があります。
メソッドfopen()とメソッドfread()の場合はコンストラクタ内でfopen()を呼べば、
メソッドfread()呼び出し時にファイルオープン済みである事を保証できます。
デストラクタ自動呼び出しでユーザのfclose()呼び出しが不要になるのは利点ですが、
コンストラクタ強制呼び出しでユーザのfopen()呼び出しが不要になるのもまた利点です。
「○○はXXで出来るから○○は不要」の話はもう飽きた。 ↑を言うやつは、アセンブラでやれ。何でも出来る。
284 :
デフォルトの名無しさん :2010/11/23(火) 21:44:01
計算の抽象化の話しだしたらLISPに勝てると思ってるの?
>>279 オブジェクトを扱っている時点でそのオブジェクトはデータの整合性が取れているのが分かる。
でも関数なら初期化前か後か分からないと言いたいだけなんだが。
>>280 >だからカプセル化はCでも出来るんだってば
カプセル化は出来ると思う。カプセル化自身がOOP特有の機能じゃないから。
もとの話は構造体と関数でOOっぽいスタイルと言う話だったから
カプセル化がOO特有だと思っていないから意識してなかった。
だから構造体と関数でオブジェクトに似ていると考えた場合の違いを書いている。
カプセル化の話だったのか! すまない勘違いしていた。
> 内部で使う構造体定義をヘッダに書いて外に見せなきゃいいだけ 外に見せる用の構造体と、内部用の構造体を用意して、両者を同期するって言ってる?
>>286 不完全な構造体宣言だけ書いて全部ポインタ経由で操作するってことじゃね
スタック変数とかは作れないけど、
必ずhoge* hoge_create()みたいな関数経由でオブジェクトを作らせれば初期化前の状態は見えない
目的は依存性の整理であって、それを実現するためのモデリング手法がOOA/OODであり、 さらに、それを効率よくコードに落とす手段がOOP及びOOPLだ、という簡単な話が何故ここまでこじれるのか。
289 :
デフォルトの名無しさん :2010/11/23(火) 22:01:57
>>267 逆に、俺はCLOSのようなマルチメソッドの世界は、
総称プログラミングであってオブジェクト指向ではないと思う。
stream.write(text);と書けば、streamとtextは対等ではなく、streamが主語、textが動詞に見えてくる。
そして、概念的にはstreamは別プロセスで動いていたりしてもかまわない。
そういうのが狭義のオブジェクト指向だと思う。
>>287 > 不完全な構造体宣言だけ書いて全部ポインタ経由で操作するってことじゃね
C言語ってそんなことできるんだっけ?
どっちみち、そこまでするなら素直にOOPL使えばいいじゃん、という話ではあるが。
できる。そういうAPIを持ったCのライブラリはたくさんある。
>>290 出来るに決まっているだろう
不完全型が扱えないのなら、
struct node {
struct node *next;
};
もコンパイルが出来ない
というのはさておき、別にvoid*でもいいんだよ、外に見せるのは
苦肉の策でその様にしている、所謂ノウハウ。 だから何?って感じだが
>>282 コンストラクタ関数であるfopen()を呼ばずにそれを使うということは、
コンストラクトしていないオブジェクトに何かしようとしているのと同じだ
C++で言えば、
istream *stream;
stream->read();
とか書くようなもんだ
こう書けるし、コンパイルは通るぞ?
C++でも
>>295 初期化してない変数(≠インスタンス)のメンバ関数を呼ぶのは単純にバグと言いませんか。
>>296 FILE*オブジェクトが得られていないのに、それを使った操作を行おうとするのも
単純にバグだろ
>>287 これが分からない奴がこんだけいるというのがもう凄いな
オープンソースの世界はLinuxのカーネルと言わんでもCのコードだらけだが
ちらっとでも読んだことも無い奴がこんなにいるのか
また、ずいぶん昔に出来たソフトを例に挙げても。
多くのオープンソースで、GNUとかLinuxが出来た時代はOOPLがまだ無い、 または、まだ広まっていない時代だから。非OOPでいろいろなノウハウが当然ある。 そのノウハウで、今もCで書けと言うのか? 好きにしろ、俺はやらん。
例挙げるまでもなく、今時Cやらされる人は
>>287 やるだろ
腹の中で「OOPL使わせろよ…」って思ってるんだから
struct hoge_;
typedef struct hoge_ *hoge;
hoge *hoge_create(void);
void hoge_hello(hoge*, FILE*);
void hoge_destroy(hoge*);
>>301 そうそう
でもイディオムだのノウハウだのというが、C++も一緒だよ
>>301 のやりかたではhogeモジュールが実際に扱っているデータ構造が
完全に外に見えないから、データ構造の変更に強い
それをdata abstractionと言う
C++で同等のものが欲しければ、普通に書いていてはダメで
pimplのようなイディオムが結局は必要になる
それでもコンパイラを越えたABI互換性がひどく脆弱で無いに等しいのが
C++だけれども
おまいらCを老人言語のようにいってるが、 PythonやRubyのような現在のオブジェクト指向スクリプト言語の インタプリタもたいがいはCで書かれてるんだぞ
なんか妙に上から目線なところに横槍すまんが、
ヘッダに書くのは構造体の定義じゃなくて宣言と違うか?
とりあえず
>>301 には定義は出て来てない。
>>301 あー、理解した。
しかし、「OOPLでやれよ」だな。
>>300 カーネルみたいな速度が最重要な世界では、C言語の出番はある。
ただ、全てのプログラムで速度が最重要ではなく、
むしろ可読性や柔軟性の方が重要な場面の方が多い、というだけの話だな。
>>307 もしかして
>>301 が出した親切な例の意味が分かってない?
>>301 においては、struct hoge_の型の定義が書かれていないので、
「不完全型」になっている
Cでは不完全型のポインタを扱うことは出来るので、型の定義を知らなくとも
上の3つの関数を扱う分には何も問題はなく、コンパイルは通る
勿論内容が分からないからメンバにアクセスはできない
struct hoge_型の変数を普通にスタック上に配置することもできない(サイズが
不明だから)
よって、このインタフェースを提供している実装側は、実際にはその
ポインタが指す構造体の定義を、外に見せない形で別に持っているわけだ
309 :
308 :2010/11/23(火) 23:14:35
ちなみに構造体型の定義をどこにおくべきであるかという決まりは無い
複数のソース(.c)から参照する必要がある場合は、それは当然ヘッダに置かれるのが
普通だ
が、ユーザにも見えるヘッダに定義を書いた場合には、ユーザにデータが
見えてしまうことになる
(stdioのFILEはそうだ)
>>301 の例では、ユーザに見えるヘッダには定義は書かないことで
データを隠蔽しているわけだ
スマン。 >内部で使う構造体定義をヘッダに書いて外に見せなきゃいいだけ の意味が分からんかっただけ。 ちなみに今も分かってない。 まぁ別にどうでもよさげだな。
ヘッダに書いて外に見せない 正:(ヘッダに書いて外に見せる) をしない 誤:(ヘッダに書く) をして (外に見せない)
またつまらないことでスレが伸びてるなぁ。
俺の名作文
>>267 が流れるじゃねーか。
マルチメソッドはOOP的じゃないって言ってる人が居たが、俺もそう思う。
単一のクラスやオブジェクトにメソッドがぶら下がらない時点で、
オブジェクト中心って感じじゃないもんな。単なる型スイッチだもん。
マルチメソッドはハッシュ引くことになるとか意見があったが、
そうしなくて済むコード例は前上げたよな。コンパイラががんばればいいよ。
そんでも、デストラクタぐらいは有ってもいいと思うぜ。
いちいちrelease_hogeするの面倒だしな。
コンストラクタは要らないな。
暗黙の型変換とかの話が出てくるし。
これはオーバーロードと相性が悪いんだよ。
そこはC++はミスったね。案の定変な予約語で誤魔化したし。
コンストラクタは普通の関数でも問題ない。init_hogeとかでいいよな。
あと、関数のスタイルは何をどの順に呼び出していいかわからないって池沼が居たけど、
それ、OOPでも一緒だろ。なんせ、手続き型言語なんだからなw
こんなアホの相手してやるお前ら親切だな。俺は無視だぜ。
かわいそうだから池沼とか言うなよw 関数型や論理型のようなパラダイムを知らず、OOに幻想を抱いているタイプの 人なんだろう まだいたのねって感じはするけど
>>312 関数型は副作用がなくて機能が関数で完結するからいいんだよ。
なんでいまさら手続き型の機能単位をデカくしようとするのか教えてくれ。
一人で小規模に作るんなら書き散らせる方が便利だろうが、
仕事でやるには堅く書けるのが大事なんだ。
結合で出る問題を減らすにはモジュールがきっちり分かれてる必要があるの。
なんでいまさらそんなサポートの少ないショボい言語が要るの?
OOPにゃこだわりはないけど、プログラムの機能を分割する機能をよこせ。
>>312 > 関数のスタイルは何をどの順に呼び出していいかわからない
× 分からない
○ 制約を付けられない
>>314 完全同意。
> 関数型は副作用がなくて機能が関数で完結するからいいんだよ。
つまり、副作用がある前提で書くなら、機能の整理を支援する何らかの仕組みが必要なわけだね。
そして、その方法のうちの一つがOOパラダイム。ここテストに出るよー。
>>314 何言ってるのかちょっと解らないんだけど、
カプセル化の話なら、マルチメソッドでも出来るぞ。もちろんCでも。
void func( obj1_t *obj1, obj2_t *obj2 )
{
set_value( obj2, get_value( obj1 ) );
}
ほら、何の問題も無いだろ?
ただこのとき、funcは2つの引数を取ってるけど、 マルチメソッドだと、この二つの引数の型を元に、funcの呼び出し先を型switchすることさえも出来るってだけなんだが。 C++やJavaの単一ディスパッチみたく、第一引数のみに基づいて型switch可能って、なにやら変だろ? 何で第一引数だけ特別なのかと。 C++にしろJavaにしろ、オーバーロードは全ての引数の型に基づいて決定されるのにな! 動的多態は第一引数の型のみってのは変だろ? そんなに第一引数のみでやるのが便利なんだったら、オーバーロードも第一引数に基づいてのみ決定する仕様にすりゃいいのに。 まー不便だわな。 今現在、単一ディスパッチが主流なのは、単に、実行コストとコンパイラの実装コストが高いから。 基底クラス使って多態するのも同様の理由。 ただそれだけ。利便性とかは関係ないのさ。 まー当時はメモリもCPU時間も貴重だったからな。 今だったら、マルチメソッド+ダックタイピングが良いわな。 あとはどう速く実行するか。ハッシュとかは嫌だからね。
でもこの、第一引数でのみ多態するって手抜き実装が変な思想を生み出しちゃったんだよな。 第一引数でのみ多態するってことは、メソッドは第一引数に依存するから、 メソッドそのものが第一引数ありきになちゃって、やがては、第一引数中心で考える、 所謂オブジェクト指向になっちゃったんだ。 とにかく、C++やJavaでは、そういう第一引数志向なコードしか走らないんだから、 そういう風に書くしかないので、そういう風に物事を考える癖がついて、OO脳になる訳だな。 これは恐ろしいことだね。 日本語もその毛色があるね。 目的語の後に述語がくる並びだから、物を大事にする文化が育った。 というか、元々物を大切にする気質だったから、目的語→述語の並びになったのかもしれんが。卵と鶏だな。 英語なんかは逆だよね。だから機能主義。わかりやすいよねー。
>>262 オブジェクトが能動的なのが良くて受動的なら関数呼び出しと同じだから悪いなんて
考え方自体おかしい。各オブジェクトが勝手に判断して能動的に動かれたりいたら
ますます何やってるかわからなくなる。
各オブジェクトの動作まで完璧に把握してないと危なくて使えない。
各オブジェクトが勝手に動き回った結果、相互作用で生じた不具合なんて想像すらできない。
そんなのデバッグすんの無理だから。
みんないろいろ意見言ってるけど、結局OOPは概念が決まってるようで決まってないみたいだな。 人それぞれ解釈のしかたによっていろんな書き方ができる。いろんなレベルで書ける。 C++ならCと同じようにも書けるし、混在した形にも書ける。C++の機能だけをフル活用した書き方もできる。 自分が納得したレベルで、自分が書きやすい形で書いてればいいんだろうな。 いろいろ書いてれば、そのうち経験値が上がっていって自然にコーディングレベルも上がってくるんだろうと思った。
要するにOOPとはインターフェイスのことなのですか?
>>322 機能単位を「安全に」外部へ公開するための手段がインタフェース。
そして、機能分割を適切に行うための手法がオブジェクト指向分析/設計であり、
それをコードに落とすときに、インタフェース等の枠組みを使って適切に制約を
加えながらプログラミングするスタイルがオブジェクト指向プログラミングであり、
それを容易に行えるようにプログラマを支援する仕組みを持った言語が、オブジェクト指向言語。
>>321 その結果として辿り着くのはオブジェクト指向ではないかもしれないが、
少なくとも、Itsumono言語でないのは確かだな。
モジュールを肥大化させる方向性は明白に誤りであり、経験値がある人間がまず避けるやり方。
>>323 間違えてないと思うけど、ちょい言い過ぎ。
クラスベースの話だろ。
>>270 メソッドでないメッセージはあり得るのですか?
>>320 オブジェクト指向のオブジェクトが「能動的だ」とか言ってる奴に
つっこんでるだけで、誰も能動的でないのが悪いとは言っていないよ
まあ、お前がErlangのような言語やπ計算のようなモデルについて
全く無知なのはよくわかった
自己紹介乙
>>326 アクターモデル
>>325 プロトタイプベースはよく分かんないけど、「クラスベースほどの厳しい制約は必要ない」
という立場なのかな、と今思った。
>>329 タイトルはそのものズバリなんだが
なんか内容薄いね、この記事
>>329 いやだから、設計論は何でも適用できるから、OOPとは区別しないと。
OOは設計論かもしれないけどな。
>>332 だから、デザイン(設計)だったらOOもOODでなくてもいいだろ。
と言われて終わりだろ。普通のデザインとOODの違いを明確にいえるのか?
>>332 プロトタイプベースやメッセージングにマッチするOODの手法って
見たことないけど例えば何がある?
さしあたりクラス図が出てこない手法を教えて欲しい。
>>335 1. モデルを定義する数式をでっちあげる
2. 数式が解を持つことを証明する(特殊解でも可)
3. 数式の各項を分解する
4. 分解した各項に対して 2, 3 を適用する
5. 十分小さな単位まで分解できたら, 使用する言語のシンタックスに置き換える
すげえ、議論すればするほどどんどんあやふやになっていく・・・w
だってあやふやにしようとするひとがいるんですもの
現代的なオブジェクト指向が目指すもの、という意味では
>>329 でFAでしょ。
どの要素技術がオブジェクト指向的か、なんて議論にはほとんど意味はない。
記事にもあるように、オブジェクト指向の代表的な要素技術と看做されている「継承」が、
最近は「不必要に用いるべきでない」とされるのも、「疎結合」を目指す、という方向性とズレるから。
クラスライブラリ自身、継承しまくりでできてるのも止めろと?
>>340 >>329 の記事を読むと1970年代のモジュラープログラミングとどこが違うの?という
疑問が生まれるな。マイヤーズ/国友らの著作。彼らは「〜を〜する」の『機能主義』
だとは思うけれど。
343 :
282 :2010/11/25(木) 10:02:41
>>312 >あと、関数のスタイルは何をどの順に呼び出していいかわからないって池沼が居たけど、
>それ、OOPでも一緒だろ。なんせ、手続き型言語なんだからなw
>こんなアホの相手してやるお前ら親切だな。俺は無視だぜ。
コンストラクタの目的という基本的な事を説明した人達は全員池沼でアホですか?
>>315 を具体的に説明しているのをあなたが理解できなかっただけですよ。
>>342 構造化プログラミングもモジューラプログラミングもオブジェクト指向も
目的は大規模なプログラムを作る事で、方法が違うだけです。
>>329 の記事は目的の話しかしてないのだから区別できないのは当然でしょう。
「目指すもの、という意味では
>>329 でFA」に同意します。
>>329 が書いてるのは、オブジェクト指向以前の大前提だと思うけどなぁ。
>>345 「オブジェクト指向の本質」というタイトルと内容が一致していないのは確かですね。
このタイトルからはこれがあればオブジェクト指向だという内容を期待しますが、
実際には「本質」でなく大前提である「目的」しか書かれてないですから。
>>345 いや目指すものはその通りだろ。
「OOとは、の記事」としてOOの特色が取り上げられてないないから
表題に対して内容が薄っぺらいだけで、
OOPの実利的な面は、結合度と凝集度の延長線上にある。
>>343 コンストラクタが何か特別で素晴らしいものだと思ってるのは
残念ながらお前だけじゃね?
Stroustrupは何かそれを素晴らしいものだとして宣伝したかもしれないが、
より高い抽象度から見れば、それはただの生成「関数」と同じ物なんだよ
Lispのconsはコンストラクタの略でもある
CLOSやJavaScriptなど、世の中には色んなオブジェクトシステムがあり
関数型のクロージャは概ねオブジェクトと等価だ
抽象化の方法論も色々なんだから、もっと視野を広げるこった
C++の系統の言語でも、オブジェクト生成をより抽象化したければ
ファクトリ「関数」を用いることになるしな
>>347 open/close principleとかを念頭に言ってるんだと思うが
少なくともC++に関して言えば、それを非常に重視しているようには見えないな
たとえprivateメンバであっても追加や変更を行えば、それを使用してる側に
影響を与えてしまう
脆弱なスーパークラス問題って奴な
勿論それを解決する方法はあるが、Cと一緒で、要は言語レベルでは問題は
何も解決されていないわけだ
Javaの系統も同様で、インタフェース、ファクトリ、実装クラス、を
「自分で」作って分離しなければ結合性を弱められない仕組みになっている
>>349 OOPLはオブジェクト指向開発を容易に実現するための道具に過ぎないんだから、
言語処理系のレベルで全てが提供されている必要はないと思うが。。
道具は組み合わせたっていいんだよ。むしろその方が拡張性は上がる。
>>351 私は
>>349 ではないけれど、プログラミング言語を道具という感覚には
ついて行けない。言葉と思考は一体のものだな。先行して「目的」が
あるというところが何かあやしい。
>>352 道具云々はともかく、目的もなく作業したって意味がないじゃない。
>>329 疑問に思った事は
「OOPではスパゲティコードで作らないことが必須」なのか?
もちろんスパゲティコードにしない方がいいが
OOPにはそんな制約はないし
メソッドのコードをスパゲティコードで作ってもOOPは実現出来る。
OOPを誤解している人の多くは、いままでの経験上の延長線で
OOPを考えている人が多いと思う。
(情報隠蔽(カプセル化)こそがOOPだと主張する人とか)
OOPは構造化とは別次元の考えでパラダイムシフトだと思うけど。
>>354 すまん、もう少し主張を整理してもらえる?
OOPも構造化も関数型も分割統治を重んじているという点では同じ目標を持ってると思うけど
ああ、何が言いたいか分かった。けど、それは原因と結果が逆だ。 「コード間の依存関係」が高まることの結果として生まれるのが、 メンテナンス不能のコード、即ち「スパゲッティコード」であり、それを防ぐには、 依存関係の低い状態である「疎結合」を保たなければならない。 オブジェクト指向の様々なコンセプトは、その意味では特別なものではないし、 逆に、それらのコンセプトの裏にある「本質」を無視して書かれたプログラムは、 たとえオブジェクト指向言語で書いたとしてスパゲッティになる。 という内容でしょ、あの記事は。
>>357 特別な意味じゃないのは「疎結合」という目的のほうだろ
でも、疎結合って、OOPあんま関係ないと思う。 フィールドへのアクセスは、かならずアクセサを通す。 引数に取るのは、intやdoubleなどの基本型のみ。 この二つを守れば、どうやったって疎結合になるよ。 OOPだからどうだってんじゃ無くて、C言語レベルの話でしょ。
どんな言語を使おうがスパゲッティプログラムは作れるわけで。 また、どんな言語を使おうが機能的・データ的に「祖結合」が有用なのは 変わらないわけで。 それを用いてOOPの何たるかを語る事自体が意味がない。 結局の所一時期のOOブームで、まるで銀の弾丸のように説明して 分野を広げすぎた事にOOの問題を感じる。 OOPLによる、OOPはいいものだけどな。
>>355 分かり難いか、すまない。
簡単に書くと、「メソッドでGOTO文を使っても良い」ということ。
構造化では禁止されているけどOOPではそんな制約はないし
GOTO文を使ってもOOPは実現出来る。
そもそもGOTO文を「使う使わない」とかとは観点が違うと思う。
>>359 いや、クラスで囲ったとしても、機能的に簡単にスパゲッティはできる。
>>359 相手のフィールドの存在を意識しなければならないというのは密結合の度合いが強めな証拠
>>360 だから、ここで最初の結論に戻る。
「オブジェクト指向設計無くしてオブジェクト指向プログラミング無し」
オブジェクト指向言語という有用な道具を生かすには、相応の設計が必要だってこと。
C#なんかはメイヤーさんが言うところの統一記法(だっけ?)をサポートしてるから フィールドなのかメソッド(アクセサ)なのかコードを見ただけだとパッと見はわからない しかしIntellisense使うときにでるアイコンでばれる。残念
オブジェクト指向が、従来の手法と何が違うのかを考察するなら、 「コード間の依存関係」を整理する、という目的に対して、 オブジェクト指向がどんなメリットを提供しているかを考えるべきだろう。 少なくとも、言語の文法レベルの話をしてもあまり意味がないだろう、というのが俺の意見。 例えば、オブジェクト指向に、なぜ依存性注入(DI)のような手法が登場したかを説明できない。 私見では、疎結合に保ちたい状態の操作を、オブジェクトの提供する「サービス」として 見せるあたりがキモだと思うけど。
>>357 疎とか密とかは方針としてわからなくはないけど、実際のプログラム開発では気にしない。
たとえばよくあるWebプログラムで言うと、サーバーサイドスクリプトをA、データベースをBオブジェクトを作り、
相互に必要なメッセージをやりとりして、結果をクライアントに応答するように書くけど、
A,B間でメッセージのやりとりをする部分をわざわざ疎にしようとか密にしようとかは考えない。
なぜならどういう機能をどれだけ盛り込むかは要求仕様で決まるから。
疎にするために機能を削るというのは非現実的。何しろお客の要求なんだから。
A,B間で連携して処理する作業が多ければA,B間の関係は自然に密になってしまう。
これが良くないからと言って疎にできるんだろうか?
無理じゃね?
え?
>>367 メンテナンス性とは違うが、スケールアウトできるようにA,B間を疎結合に、
というのが、むしろ最近の流れじゃない? 二つが密結合になってると、
そこがボトルネックになるからね。
本題に戻ると、その例で言えば「DAOはやめてModelを作るべき」みたいな話はあるよね。
スキーマをインタフェースとして直接露出するDAOではなく、
ビジネスロジックとして自然なインタフェースを定義して、制約を作りこんでModelとし、それ経由で永続化を行う。
ま、この辺のやり方は色々と議論があるところみたいだが。
あと、密結合にせざるを得ない部分があるにせよ、その部分全体を外部に対して疎結合に
するようにプログラムすることはできるわけだし。
疎というのは、互いの依存性の話であって、機能の多い少ないとは直接の関係はないよ。
>>367 A, B間の連結を疎にするというのは
Bが扱うデータベースがGDBM(Key-Valueストア)から突然MySQL(RDB)に変わったとしても、
Bの変更だけで済むようにするということ。
具体的にはAがDBのスキーマを意識してSQL文吐くのでは無くて、
B.get○○などのインターフェースを通じて必要な情報を取得するようする。
パフォーマンスの問題はついて回るかもしれないが、
プログラマに人件費かけるくらいならマシンにかけた方がマシ
そうして失敗したのがswing
OOPはまだ人類には早すぎたのだ
前はあまり同意を得られなかったけど この流れなら カプセル化とそれに伴うインターフェースと実装の分離が オブジェクト指向の中心的な技術(手法?) と言ってしまってもそんなに違和感がないのでは? 本質はいいすぎな気がするから「中心的な技術」に言い換えちゃうけど
>>373 いいんじゃね別に、本質つっても。
成り立ちから考えろ、シミュレーションが本質だ!つって息を荒げる人以外は同意するんじゃね?
実装とインタフェースの分離は、どっちかっつーと、
モジュール性ってレベルの話題の一つかもしれんが。
個人的にはやっぱり多態がOOPって感じるなあ。 当然、多重ディスパッチも充分OOPの要素たりえると考えてる。 んなわけでOOPを否定するためにマルチメソッドを主張する思想は全く理解できない。 だってそれらは、両立するどころか、むしろ相性の良いものだと思ってるから。 強いて言えば、それ以外の…個人的には多態ほど重要ではないけど やっぱり一応抑えておきたい要素である、カプセル化との相性が若干疑問かな。 名前空間を適切に分離してやれば解決できそうではあるけど。
どうでもいいが議論してくれ
OOPのキモは「オブジェクト」という概念を用いてシステムを構築すること。 別にそれ以上の意味は無くて、多態だの分離だのはデザインパターンの範疇。
>>377 IBMのSystem/38そのものではないか。だからどうということもないけど。
プログラミングではないが、今時のOSも割とオブジェクト指向してるよな。 アプリからファイルを開く、も出来るんだけど ファイルに「開く」って指令を与えてやると、適切なアプリで開いてくれる。
>>377 OOPにおいて「オブジェクト」とはどういう概念なのよ?
>>381 オブジェクト = データ + メソッド
>>382 「データ + 手続き」か「フィールド + メソッド」でないと変だと思います。
C言語プログラマ向けなら「変数 + 関数」という説明もありですね。
このスレを読んで主観的な印象は、こんな感じ。 オブジェクト指向の経験が長く、改修の多い技術者は 差分プログラムが重要だと考えている。 オブジェクト指向の経験が長く、新規案件が多い技術者は 多態が重要だと考えている。 オブジェクト指向の経験が少ない技術者は カプセル化が重要だと考えている。 この三種類が重要だと考える人が多いけど 経験や業務の差で意見が分かれていると思う。
そうだな、これだけ書いている奴の意見が違うのは OOPの問題じゃなく、その人間の差だな。
>>384 > オブジェクト指向の経験が長く、改修の多い技術者は
アジャイル開発みたいに「要求はどんどん変化するし、それは必然だ」という立場を取るなら、
新規開発だろうが改修だろうがこっちになるけどね。
あと、「差分プログラミング」と呼ばれるとしっくり来ないな。
「モジュールを切って疎結合なインタフェースを定義する」という方針を一語で表す言葉って何だろ。
つまり、要求の変化に強いコードを書くのが目的なのであって、差分開発によって工数を減らすという
のは、結果的に享受できるメリットのうちの一つでしかない。
この立場では、(継承以外の)オブジェクト指向の各コンセプトは「道具として」重要だ、となる。
カプセル化は、オブジェクトの利用者に対して事前に設計した制約を強制することができるし、
多態は、制約を与えつつも柔軟さを生み出すのに有益。
「ある程度の規模のソフトウェアを」「複数人で」開発する必要があるかが分かれ目かな、と思う。
俺の意見では、一人でやる場合でも有益な考え方だと思うけど。
387 :
デフォルトの名無しさん :2010/11/27(土) 11:12:29
関数の呼び出し関係にあまり依存しない設計ができるのはオブジェクト指向の大きな利点だと思う。例えば if (confirm("Q1")) return input_text("Q2"); return NULL; のような手続きをイベント駆動に書き直すとなると、当然call treeは全く違ったものになる。 手続き指向や関数型なら、プログラムの設計を大幅に見直さなければならない可能性が高い。 ところがオブジェクト指向でうまく設計してあれば、クラス同士の依存関係、 インスタンスの所有関係などはそのままに、メソッドのインターフェースを変えるだけで済んだりする。 この利点は、オブジェクト指向でスパゲティを作るとデバッグが非常に困難になる問題と表裏一体だが。
>>386 >アジャイル開発みたいに「要求はどんどん変化するし、それは必然だ」という立場を取るなら、
>新規開発だろうが改修だろうがこっちになるけどね。
開発中の仕様変更・追加と改修を一緒だと考えるのは無理があるのでは?
>つまり、要求の変化に強いコードを書くのが目的なのであって、差分開発によって工数を減らすという
>のは、結果的に享受できるメリットのうちの一つでしかない。
「要求の変化に強いコードを書くのが目的」それは新規開発時の目的では?
その目的で作られたシステムを改修していく時には別の目的があると思うが。
あと、差分が「工数を減らす」だけとしか考えられないはどうかと。
>「ある程度の規模のソフトウェアを」「複数人で」開発する必要があるかが分かれ目かな、と思う。
>俺の意見では、一人でやる場合でも有益な考え方だと思うけど。
その考え方自体が、新規開発時を想定していないのか?
>>388 ウォーターフォールのような、完全な設計を作ってから開発に入る系の開発手法ならそうなるね。
ここでは、ウォーターフォール vs. アジャイルみたいな話に踏み込むのはやめておくが。
>>384 OOPナニソレ?→デカイ案件→設計とは何ぞや、柔軟な設計とはなんぞや
→デザパタとは何ぞや→ポリモの旨み→差分でやる旨み→OOPの旨みってなんぞや
→モジュール性を高めるにはどうしたらいいか→どうしたら理想の設計に近づくか
→もっともっと有用なクラス設計をしたい→使いやすい単位でやりくりしたい
→もっともっとカプセル化 ←今ここ
カプセル化ってのは、privateメンバに対してアクセッサを設けることではなく、
非privateメンバ、関数を増やさないことだと今は思ってる。
protectedすら、無いほうがいい。
自分のことだけに集中させればさせるほど、使いやすい単位になる。
使いやすいオブジェクトを実行時に組み合わせてラクするのが極意だと思ってる。
>>386 KISSの原則と真っ向から対立する考え方ですね。
一人でやるなら汎用的なクラス+差分プログラミングより
シンプルなクラス+リファクタリングで単純なクラス構成を目指したくなりませんか?
業務プロジェクトの場合は「動いているものをいじるな」という圧力が大きいですが
ソースを引き継ぐ人には歴史的経緯による複雑なクラス構成は迷惑なだけだと思います。
>>389 >ウォーターフォールのような、完全な設計を作ってから開発に入る系の開発手法ならそうなるね。
ウォーターフォールを誤解しているのでは? ウォーターフォールでも前工程への後戻りも認められている。
>>391 横からだけど、デザパタがどうの、OOPがどうの、
という前にKISSを徹底したほうがよっぽど効果出るといつも思う。
>>391 「変化に強いコード」は、どんな要求が来ても予め対応できるようにしておく(汎用的)こととは全く違うよ。
むしろ、あなたの言うとおり、クラスのインタフェースやクラス構成をシンプルに保つことが一番重要。
>>392 けど、実際には、ウォーターフォールでの手戻りの発生は多大なコストを伴うよね?
特に、開発がある程度進行してからの手戻りは凄惨の一語。
いくつか具象クラスを作って初めて、「これ、抽象クラスにできるんじゃね」って発見をすることはよくある。
これを別の事に例えると、例えば民主主義は「自由・平等・博愛(友愛)」が大事でその優越は ・アメリカ人なら、新大陸で身分制度のないアメリカでは”自由”を大事する。 ・ヨーロッパ人なら、貴族社会があって革命により民主主義になったから”平等”(社会民主主義)を大事する。 ・日本人なら、お互いが助け合う(年功序列や終身雇用など)”博愛”を大事にする。 こんな感じかで、本当は優越をつけるものではないのかもしれない。 一番大事なのは他を否定することじゃなくバランス感覚を持つことかも。
「要求は変化する」という考え方に基づくなら、「汎用的なクラスを作って差分プログラミングする」 という考え方は、つまり「汎用性」と言った時の文脈を予め固定して考えることであるわけで、むしろナンセンス。 本当の意味で文脈に依存しない汎用的なものは、多くの場合はフレームワークとして世に出てる物を使えばいいわけだし。
各モジュールを疎結合にすることで 要求の変化に応じて変更しなければならない領域がなるべく狭くなるようにします。
>>398 フレームワークを汎用的と言われると違和感がある。
フレームワークは特定の業務や環境に”特化”しているもの。
限られた部分での汎用性はあるが、OOPとは別次元。
そもそもフレームワーク自身がOOPで作られている。
つ モジュールの独立性を高める 構造化設計時代の言葉。
いまでも有効でしょ。
>>398 も
>>400 も何を言っているのかよく分からん。
>>398 多分フレームワークは
>>398 本題じゃないんだろうけど。
フレームワークに乗っけて開発プログラムに特化した部分を
実装していくのはまさに
「汎用的なクラスを作って差分プログラミングする」
という行為に見える。
極端に言えばフレームワークを自分で作るか、
外部から調達するかだけの差であって、
フレームワークがフォロー出来る範囲が違う程度。
>>400 「環境」って例えば何?
言語とかの開発環境?
OSとかの実行環境?
OOPで使うフレームワークは、OOPで作られてるというより、
OOPによる実装の、よくある一部分を汎化した物じゃないのか?
そもそも実装において、範囲を限られない汎用性なんて有り得るの?
404 :
デフォルトの名無しさん :2010/11/27(土) 18:19:21
>>396 逆に、将来を見越したつもりで具体例が乏しいままに抽象化すると、
セマンティクスが曖昧になって逆に拡張性が無くなってしまうこともよくある。
UNIX関係でありがちな、ユーザーに自由がありすぎてプログラムの側が何もできない状況も同根。
405 :
373 :2010/11/27(土) 20:01:45
>>384 論点(というか本質の定義)にズレがあるような気がします
>>373 は
「オブジェクト指向をオブジェクト指向たらしめている技術」
という意味での発言です
「オブジェクト指向を使って実現することが出来る技術」
ではありません
406 :
398 :2010/11/27(土) 20:58:00
>>403 や、もちろん「汎用的なクラスを作って差分プログラミングする」が適切な場合はある。
けど、それをやるべきケースはわりと限定されているのでは、というのが俺の意見。
特に、「汎用的なクラスを作る」の部分は、車輪の再発明と化す場合も多い。
407 :
398 :2010/11/27(土) 21:04:05
もっと言えば、個人レベルでそういうのを自作する必要があるケースは、 それだけで一個プロジェクトが立ち上げられるレベルなんじゃないかな。 あるいは、多人数開発で、少数の優秀なアーキテクトがプロジェクト全体の開発プロセスを 統制する目的で注意深く作成する、みたいなケースか。
汎用的なクラスという言葉から神クラス並の危険を感じる。
神、すなわちゴッドクラス。
具体的な処理から制約を削っていって汎化すると大変なことになる そろそろ処理構造の汎化の正規化とか誰か作らないかな
コードスニペット?
それでね、単一ディスパッチのOOがどういう立ち居地かというと、 わりとデータよりの発想で、だからバランスが悪いと俺はね。 マルチメソッドにしろというのはそういうこと。
いつもの人は理解できないなら黙っててくれないかな^^;;
マルチメソッドはダメだろう。オブジェクトが2個のときでさえ、相互に関係する処理がいくつかあれば それを処理するメルチメソッド関数が何個も必要になる。3個、4個と増えればそれらの相互関係を処理するために 幾何級数的にマルチメソッド関数が増える。しかも1個でも書きもらせばバグになる。いたずらに複雑になるだけで わかりやすさとはほど遠い。見た目がただの関数にしか見えないのもOOPらしくない。
マルチミソ自体は別に悪くはないと思う 関数の数は、例えばオブジェクト2個なら片方をObjectか何かで取って 多態を使って変換してやるだけだろうし ただいつもの人の場合は手段と目的がぐちゃぐちゃ ただ批判したいがために出してる感じ
いや、その理屈はおかしい。 だって、お前らオーバーロードは受け入れているんだろ? あれは、全ての引数の型に基づいて関数を決定するぞ。 あれがよくて、なんでマルチメソッドはダメなんだ? 普通に機能強化なんだから、問題ないだろ。 OOPが好きな奴も嫌いな奴も納得できる、良い落しどころだろ。 テンプレートが便利なのも、いまや誰もが認めるところだろ。 あれが動的になるだけじゃん。 マルチメソッド+ダックタイピング、良いね。 次のスタンダードになりうると思うよ。
>>411 ワークフローエンジンなんかは、いくつか出てるね
>>418 プログラマを楽にすることに全く貢献してないから。
「あれもできる、これもできる」というのは、使いやすさとは関係ないんだよ。
>>418 あるクラスのメソッド呼び出しで、引数型をみて(ダックタイピングでも)
動的ディスパッチするだけなら特に問題はない。
動的言語としちゃ普通に便利だろ。
# ある開発において、動的と静的のどちらが向いてるかの問題はある。
いつもの人は
「クラスは無くして全てマルチメソッドで表現すべき」
などと言うから頂けないんだ。
クラスなくしても、型があるんだから良いだろ。 それに、マルチメソッドなのに、「クラスメソッド」って呼び名は変だろ。 オーバーロードの関数を、クラスメソッドって言うか?
マルチメソッドって、マルチ「クラス」メソッドってことだろ。 複数のクラスに属しているメソッドだから、クラス定義部に書くことは出来ないぞ。 クラスメソッドって言えるか?
>>423 もう一度言うぞ。
「機能等価であることと、使いやすさや読みやすさは関係ない」
それは屁理屈だろ。なぜ関係ないかも説明せずにか。 機能等価の方が汎用性があっていいに決まってるじゃん。
便利だから便利だからと言って色々追加したのが、今のC++なんだよ。 あのカオスをまた増殖させるのか?
マルチメソッドにすると、オーバーロードと多態が統合されるんだから、 より一層シンプルになるわな。
オーバーロードと多態消えるならな、どうせ残ってるだろ
マルチメソッドはクラスを作る側ではなく使う側に属している。 カプセルの外から、総称アルゴリズムでオブジェクトを扱うためのグルーだ。 クラスを作る側がメソッドを提供する場合であっても、 マルチメソッドのインターフェースを決めるのは使う側で、 それをフックする考え方になる。
両方消えたら、ただのCじゃないか。 それがよければそちらをどうぞ。超シンプルだぜ。 多態がオーバーロードに吸収されて、オーバーロードとして残る。 動的オーバーロード=動的多態=マルチメソッド ってだけじゃん。何が複雑なのか解らない。
あのね、1つの機能を実現する方法が複数有っただけで。 どれだけの弊害が起こるか想像できないんだね。 君は、一人だけでプログラムを作ってる人だと、見え見え。
>>426 プログラミングにおいて、過剰に汎用性がある機能は逆に使いにくい。
理由は色々あるが、一つは、その機能を使って書かれているコードの意図が曖昧になるから。
他人が読んだときに分かりにくいコードなんて、第一級のバグの温床となりうる。
多くのオブジェクト指向言語が、「オブジェクト」にメソッドを従属させているのは、
ある機能群をグループ化できるということの他に、使う側がそのメソッドを使っている文脈を明確化できるから、だと思う。
何いってるのかわからない。 オーバーロードも多態も全て動的オーバーロードで解決しようって言ってるのに、 >1つの機能を実現する方法が複数有っただけでどれだけの弊害(ry になるのか解らない。なんで逆を言うの? 方法が複数?一本化しようって言ってるのに? なんでなんで。
>>433 だったら、多態も差分プログラミングもカプセル化も全部同じ文法の、
C++やJavaはもっとダメだね。
オブジェクト=変数+関数 ↑これが過ちなんだろうな。 クラスベースOOPLで言うと、 クラスの実装をしてる時は、変数+関数を扱ってるんだが、 クラスの実装が終わったあと、さぁOOPでラクしようってときに、 外からそのオブジェクトを見たときは オブジェクト=インタフェース=型とメソッド名と引数と戻り値 こう考えられるからこそ、使うときラクできる。 変数も関数の実装も、考えなくていい。開放される。
それは、 func( obj1, obj2 ); でも同じだろ。 funcの実装も、obj1とobj2の実装も、何も気にしなくて良い。 つーか、そんなのOOPの話じゃなくて、Cレベルの話だろ。
>>435 同じ文法って何の話だ?
それに、別のレイヤの話をごちゃ混ぜにして何が言いたい。
まだわかってない人がいて困るんだけど、 マルチメソッドの問題は、コンパイラの実装が困難なこと。 使い勝手が悪いって方向から攻めても無駄なんだよ。 オーバーロードはOKで、マルチメソッドはNGって主張は、 説明がつかないんだよ。 だから、マルチメソッドをどうしても否定したいなら、 コンパイラの実装について言及するのが正しいんだ。
>>432 結局それなんだろうな。
コードを書くという事の本質的な困難は、機能をコードを落とす所それ自体にはないというのは、
大規模なコードを書いたり、複数人で開発したりする経験がないとなかなか分からないのかも。
>>439 実装のできない処理系とか、プログラマ的には完全に無意味だと思うんですが。
自分が全知全能なら混沌とした世を平らげられるのに、と妄想してる中学生と何が違うの?
実装例はこのスレで上げたはずだが。わざわざコード書いてな。
>>437 例えばstrlen()を使うとき、
char obj[]の中身が'\0'で終わっている事を気にしなくちゃいけない。
それは、関数の実装により強いられていることで、
渡す引数もそれに対応して準備しなきゃ使えない。
一方、OOPでのstringクラスは、終端文字がどうであるかは問われない。
string#size()を呼び出すときも何も気にすることが無い。
>>442 妄想処理系の擬似コードがいくらあっても、お腹はいっぱいにならんのですが。
「さきほど光ルータの話がありましたが、もし仮に、明日光よりももっと速い、光を使わなくても速くて、熱効率も良くてですね、 そうしたものがどっかからポンと出て来た時に、これは続けられるんですか?」論だな
>>443 len( string );
append( string, "hoge" );
で、何か問題があるの?
(len "abcde") (append "abcde" "hoge") の方がすっきりしているとはおもわないのかね
良いね。ただ、括弧も省略できると良いね。 len "abcd"; append "abcde" "hoge";
表記法とコンパイラの実装はどうでもいいってば
>>446 ああそうか。そうやってすれば結局は同じか…。
privateにはならないだけで。
Cは関数のオーバーロードできないから、
名前はどんどん苦しくなってくると思うけど。
問題はそれくらいのもんか。
そのstruct stringは、stringクラスを作った場合の、
メンバ変数を全部網羅してるものと考えていい?
いっぺんC++やC++派生以外のOOPLやってみれば言いと思うよ 考えて言うだけより考えて実行するべき 何言ってるのかわからないが
>>450 概ねそんな感じ。
ただ、マルチメソッドがあれば、Cと違って名前が苦しくならないね。
privateの問題は・・・まーカプセル化は何か特別な構文を用意すれば良いだろう。
ネームスペース単位でアクセス権を設けるとかさ。
自クラスからじゃないとアクセス駄目ってのも、苦しい場合がある品。
実際、結合度の高いクラス同士だとfriendとかするしな。
ネームスペース単位の方がむしろ柔軟かも試練。
>>449 どうでも良くないって。
obj.method(obj2);って表記だと、マルチメソッドに対応するのが難しい。
>>451 単一ディスパッチ系以外の手続き型OOPでなにかお勧めある?
出来ればマルチメソッドの解決にハッシュ引かないのが良いんだが。
実装に興味がある。
>>452 それって、新しい記法のOOPLを作るだけじゃないのか?
マルチメソッドはスパゲティプログラムになりやすい。 オーバーロードは静的に統合されるから大丈夫。
>>454 その新しいOOPL記法がfunc(obj1, obj2)。
なにか馴染みが有る気がするが、気にしない。
>>452 >どうでも良くないって。
>obj.method(obj2);って表記だと、マルチメソッドに対応するのが難しい。
ここはコンパイラスレじゃないんだから
実装するのが難しいかどうかは関係ないしどうでもいい
マルチメソッドの話題自体は歓迎するけど
自分の考えた処理系を披露したいなら別なとこでやってくれ
>>452 > 実際、結合度の高いクラス同士だとfriendとかするしな。
しねーよ。
デバッグ機能とテスト機能以外でfriendが必要なんて
クソ設計もいいトコだ。
設計から見直せ。
あるオブジェクトへの操作を提供する別のクラスとかは friendクラスで作ったりするけどなあ。
>>459 その部分が密結合になってることのリスクを正確に理解した上でならいいかもしれないけどな。
俺なら、まず「設計を見直せ」とアドバイスする。
いつもの人は、密結合であることがどれほどリスクが高い状態か理解できてない時点でお話にならん。 ちょっとしたアプリケーションを作ろうとしたら、一人で書いてたとしてもすぐぶち当たる問題だと思うんだけどな。 不思議だ。
操作要求を溜め込んだクラスから、 どんな操作があったか実際に読み出せるのは、 その操作対象のオブジェクトだけ。だからfriend。 さあどうやって設計を見なおそう
>>462 それだけだとよく分からんが、不精せずに操作要求を受け渡す窓口を作るべきなんでは。
ノートPCメーカがマザボの部品の型番や接続方法を全部公開しているわけではないだろ かといってノートPCメーカ内部でそれらの仕様を非公開のまま製造するわけでもないだろ メンバへのアクセス制御で、利用者によって変わってくる部分の制御にfriendは使うべきってことなんじゃない?
>>463 外部には操作要求以外の事をやってほしくないので、
操作対象のオブジェクトはconstで提供されるわけだが、
constメソッドでは外部から操作要求を達成できない。
かといってmutable使うのは何か違う気がする。
どうしよう。
private, protected, public ではちょっと物足りないってのはあるよな。
>>465 constじゃなくて、操作要求しかできないインターフェースを渡すようにすればおk
>>467 その操作要求用のインターフェースクラスから
どんな操作要求があったかを取り出すには?
当然、操作を受け付けるオブジェクト以外には見えないようにしたい。
>>468 操作要求を取り出せるインターフェースと取り出せないインターフェースの2つを用意して、
操作を受け付けるオブジェクトには前者、それ以外には後者を参照させるようにすればおk。
>>466 OSGiみたいなモジュール単位で制御する仕組み欲しいよね的な話はわりとあるよね。
>>468 DBオブジェクトとトランザクションオブジェクトがあって、
コミットするときにDBオブジェクトから要求の中身を取り出すような状況?
だとすればfriend賛成。総合的にはカプセル化を強めることができる。
同じような意味で、Factoryパターンとfriendは相性がいい。
>>471 そういう話なら、SpringのTransactionの中身を調べてみるとかいいかもね。
>>469 操作要求を取り出せるインターフェースと取り出せないインターフェースのデータのやりとりはどうすんのよ
>>473 public interface ReadableQueue<T> {
T get();
}
public interface WritableQueue<T> {
void put(T request)
}
public class RequestQueue implements ReadableQueue<Request>, WritableQueue<Request> {
... (実装)
}
RequestQueue queue = new RequestQueue();
ReadableQueue readable = queue; // 読み出し側にはこのインタフェースで渡す
WritableQueue writable = queue; // 書き込み側にはこのインタフェースで渡す
friendより継承の方が結合強いって知らんのか
476 :
474 :2010/11/29(月) 00:46:10
俺に言ってる?
多重継承・・・
478 :
474 :2010/11/29(月) 01:08:06
インタフェースを複数実装するのは多重継承とは違うぞ。。
いつもの人だが、C#やるな。少し見直した。 だが、 >ちなみに、 「dynamic の内部実装」 を呼んでもらえるとわかるんですが、 dynamic が内部的にやってることは、この if (s is ...) を動的に生成してるだけだったりもします。 これはいただけないね。 だけどここで興味深いのは、マルチメソッドの呼び出し文法だな。 (obj1, obj2).method()ではなく、func( obj1, obj2 );が採用されてる。 C#は、マルチメソッドを、動的オーバーロードとして実装したわけだ。 まー普通そう考える罠。 だけどどんどんカオスになるな。 obj1.method( (dynamic)obj2, (dynamic)obj3 ); ↑3引数での多重ディスパッチ。 将来のことも考えれば、普通に、 func( obj1, obj2, obj3 );って書けたほうがよいよな。 そんで、参照に型情報持たせて、関数テーブルで多重ディスパッチできるようになるといいな。 C#に期待しとくか。
とはいっても、単一ディスパッチを前提としたクラス単位のvtableとマルチメソッドの相性は最悪だから、 これからどうするんだろうね。 真面目にマルチメソッドをやるなら、俺の言ってる、参照に型情報を持たせる&型推論しかありえないのだが、 いまさらそんな魔改造は無理だよな。全部捨てるしかw
× C#
○ .NET Framework 4.0
.NET 4.0で動的型言語(IronRuby, IronPython, etc..)を正式にサポートするようになったが、
dynamicキーワードは、C#側から動的型言語のオブジェクトと連携するための機能。
http://ufcpp.net/study/csharp/sp4_dynamic.html C#自体が静的型言語である以上、多重ディスパッチは「そういうこともできる」という以上の意味はない。
つうか、C#自体の設計は変わってないんだからfunc( obj1, obj2 )としか書きようがない、というだけの話。
まぁ、素直にPythonかRuby使っとけ。
なんだがっかり。MSもマルチメソッドにやる気なしか。 ifelse実装とか変だと思った。期待しないでおこう。
>>481 > 参照に型情報を持たせる&型推論
そこまではC#の例も一緒なんだが、型情報使って分岐する以外に
コンパイラはどういうコードで動的にディスパッチすれば良いんだ?
つかな、そもそも多重ディスパッチがどうとかいう問題じゃなくて
グローバルなネームスペースで対等なオブジェクト同士が協調する時、
メソッドが
途中で書いてもた。 メソッドがどのオブジェクトにも属せず宙に浮くのが問題なのであって、 マルチメソッドそのものはあまり問題じゃない。
>>482 実際のところマルチメソッドもダックタイピングもグルー言語位でしか
使い道がなさそうだしな
>メソッドがどのオブジェクトにも属せず宙に浮く 1.ネームスペースに属す。 2.Cでいうstatic。ファイル単位のグローバル空間。 3.動的オーバーロードだから名前が衝突しても問題なし。 C++のテンプレートは静的オーバーロードに頼った多態を多用するけど、 何か困ったことあるか? std::findとかstd::sortとか。
あ、 >2.Cでいうstatic。ファイル単位のグローバル空間。 は、ファイル単位でのグローバル空間に属するようなことも出来るだろうってことね。 ファイル外には公開しない奴な。
>>487 状態やコンテキストがごっちゃになることを防げない。
>>487 単純にOOとPOを混ぜると設計の一貫性が無くなって分かりづらい。
std::findとかstd::sortとかはコンテナのメンバ関数から呼ぶか、
OOPしない時に使うか、のどっちかじゃない?
vtableとマルチメソッドには共通点もある。 それは「オブジェクトの型を (明示的に) 調べてはいけない」というルール。 このルールにより、古いコードに新しい型を「結合」できる。 マルチメソッドが密結合であるとは限らない。
新しい実装クラスが増える度に明示的に定義しないといけないなら以下略。
Acceptorが増える度にVisitorを修正しないといけない問題がそのまま残る。 そのまま。 結合度が高くなったとは言えない。
何が言いたいのかよく分からないんだが。
結合度っていうより参照度?
>>494 今さらなにを言ってるんだ
OOPがよく分からないのは当たり前だろ
お前に100点
>>489 マルチメソッド対応言語だからといって、シングルディスパッチしてはならないわけではないぞ。
update( obj )とか好きにすれば良い。
void func( obj1, obj2 )
{
set_value( obj2, get_value( obj1 ) );
}
C言語でもやってたことだろ。
ただ、関数の型に応じて関数がswitchするってだけだよ。
だいたい、
単一ディスパッチはOK、
静的オーバーロードもOK、
マルチメソッドはNG、
って主張は説明がつかないよ。
C++やJavaが単一ディスパッチなのは、単に手抜きってだけだしな。
MS的には、COMとの絡みもあるし、アレなんだろうが。
かなり昔にまで遡らないと、流れを正せないな。
まーお得意のマーシャリングでなんとかするのかね。
マルチメソッドを導入することでOOP的には どういうメリットがあんの? マルチメソッドの機構よりもそっちを説明してくれよ
OOPでなくなるのがマルチメソッドのメリットだから、 OOP的にはメリットが無い。 OOPの縛りが無くなって、普通に戻る。ただし、OOP以上の機能は有している。 それだけ。
クラスというか型を定義したりそれのインスタンス使ったりしないの?
使うんじゃない? struct hoge_t{ int piyo; }; init( hoge_t *hoge ){ hoge->piyo = 0; }
OOP以上の機能は有しているつーよりも
OOPにマルチメソッドついただけだな
>>482 じゃないがRubyかPythonつかえばいいじゃない
でも困ったことにデストラクタだけは欲しいんだよなー。 あれだけはOOPの功績だよ。 GCは微妙だなぁ。 いつ開放されるか解らないし、メモリ以外のリソースが絡むと役に立たないしな。 C#も開放周りはカオスだしな。 開放用のメソッドが、スタックが巻き戻る時に呼ばれるのと、GCから呼ばれるので二つあるんだっけか。 とくに後者はいつ呼ばれるかも解らないから、バグるとデバッグ困難だしなぁ。 結局メインメモリのリソースしか面倒見てくれないってのもなんだ中途半端な感じだしなぁ。 もうちょっと上手いやりかたは無いもんかね。 CGは糞だね!って言えるような代替アイデアが思い浮かばんから困る。
もう一度、疎結合の重要性について演説しないとならないか。
しかも、どの順番で開放関数が呼ばれるか解らないってのも、痛かったり。 手続き型ってのは手順が明確だから良い・・・というか、それが前提なわけで。 どの順で呼ばれても良いように書かなきゃならないのは、しんどいな・・・。 C++でグローバルオブジェクトの初期化順が不定で、使い物にならないのと同じ臭いがする。 手続き型手続き型手続き型あれあれあれあれ。
>>499 RTTIで一々型判別しなくても良くなります
動的言語の場合、とりあえずポインタで間接参照すれば疎結合になる 動的じゃない場合、ポインタで指せないものが色々あるので密結合になりがちである
疎結合、密結合ってそういう意味なんだったか?
オブ脳な奴って、どうすれば判断できる?
オブ脳とか言い出さない奴。
得意な言語にJavaとC++を挙げる奴。
オブ脳あるって奴のクラス図みたら、クラスがすべて機能。 失笑。
OOPはDOAとは違うんだし、機能に傾倒してもいいんじゃね?
乳揺れ?
>>509 疎結合とは、コンポーネントが他のコンポーネントの定義をほとんど知らないこと。
ダックタイピングは、外部のコンポーネントに一方的に条件を突きつける。
外部で実際には何が定義されているかなど知ったことではない。
ダックタイピングはぶっちゃけハッシュ辞書(連想配列)に関数突っ込んだものと一緒だからな キーが見つかればそれを呼ぶ、無ければ値がないから呼べない、という感じ その際、相手の型なんて気にしていない、キーが存在するかどうかだけ …というかJavaScriptがホントに連想配列とオブジェクトを同一存在として実装してるんだよな x["hello"] = function(){ alert("Hello") } x.hello() なんてコードがマジでまかり通る
>>518 ん?一緒か?
RubyのHashにキー追加してもそれはメソッドにならず
Objectにメソッド追加してもHashとしては使えないと思うが
それともダックタイピング共通の要素の部分について言ってる?
外見から内部を想像して凝り固まってるんすね
だけどハッシュだと遅いし、単一ディスパッチのvtableの優位性を壊せないから、 JavaやC++信者に変な言い訳をする余地を与えてしまう。 「マルチメソッドは便利で、対象性があって綺麗かもしれないけど、 単一ディスパッチの方が、たとえ非対称でも実行効率が良いし、 目的に応じて使い分ければいいんじゃね?」 とか言い出しかねない。 だから、ハッシュじゃなくて、単純なテーブルを使った hoge_func_vtable [ ptr1->type ][ ptr2->type ]( ptr1->pointer, ptr2->pointer ); の方が良い。 オブジェクトにvtableを持たせるのではなく、 ポインタに自分の指してる型の型情報を持たせるってのがポイント。 C++のshared_ptrで使われてる手法。 とにかく、従来のオブジェクトにvtableを持たす方法は、何の将来性もないし、 不自然だし、まずいやり方だと言うことを認識させて、改めてもらうこと。 そんで、単一オブジェクトのvtableに頼った設計も糞だと発見してもらうこと。 ポインタに型情報を持たせる方法だと、intやdoubleといった基本型での動的多態すら可能。 インスタンスが型情報を持ってるわけではなく、ポインタが型情報を持つからこれが出来る。 それが便利だって言ってる訳ではないぞ。いかに自然かって事。基本型で多態できないのは、不自然だろ。 自然な言語仕様だから、自然な思考回路になり、自然な設計が出来るというもの。 対象性のある言語に対象性のある設計。非対称性はカオスの元。 解ってて使う分には構わないのかもしれないが、毒されりゃそりゃOO脳だ。 第一引数だけ特別扱い病。第一引数に機能ぶら下げ病。 プログラム設計するときに、クラスやオブジェクトのvtalbeが頭に浮かんで、 設計=vtableを組み立てること、ってなったらもう終わり。すっかりOO廃人。
OO脳だがvtableなんて意識したことないな。 その論だと、むしろ意識しちゃってるおまいが一番のOO廃人なんじゃね?
多態なりなんなり(機能)が重要なのであって、vtable(実装方法)とかどうでもいいわけだしな。
自然な言語って料理のレシピみたいな手続き型で機能中心指向なもののことか
手続き型はコンピュータにとっても自然だしな。人間からコンピュータまでフラットってことだよ。
マルチディスパッチ自体が悪いんじゃなくて、 「マルチディスパッチがあれば、オブジェクト指向を置き換えられる」という発想がおかしいんだな。 func1(a_t val1, b_t val2) { ... } func2(a_t val1, b_t val2) { ... } ... これらの関数は、どう逆立ちしたって a_t や b_t に密結合したものにならざるを得ない。 もし、どれかのデータ構造やアルゴリズムが変わったら、関連する関数を全て修正する必要が出てくる。 関数の種類 × 型同士の組み合わせの数だけそういう箇所が出てくるんだから…後は分かるな? 「メソッドはただ一つのオブジェクトに結びつく」というのは、責務を一つのオブジェクトにのみ負わせることで、 疎結合を実現するための手段なんだよ。機能を実現するために依存するオブジェクトが増えれば増えるだけ、 コードのメンテナンスは困難になる。
>>525 NAND回路<・・・
全加算器<・・・
なんで、マルチメソッドだと単一ディスパッチが使えないって発想になるのかがわからない。 func1(a_t val1, b_t val2) { set_value( val2, get_value( val1 ) ); } とかすりゃ良いだろ。ただ、多重ディスパッチも出来ますってだけで。 第一、静的オーバーロードは既に普及している訳で。
>>527 そんなもんは、電卓にすらある。
プログラマブルってことは、プログラムカウンタがあるってことだ。
=手続きってことだ。
530 :
526 :2010/12/01(水) 21:14:56
>>528 その例だと、set_valueに依存性の問題を先送りしてるだけのように見えるが。
>>530 だったら、obj->set_value( hoge_t hoge )でも同じことだよ。
>「マルチディスパッチがあれば、オブジェクト指向を置き換えられる」という発想がおかしいんだな。
この発言のアホさ加減がわからないの?
単一ディスパッチは多重ディスパッチに含まれるんだよ?
多重ディスパッチで無理なことは、単一ディスパッチでも無理だよ。ちょっと考えれば・・・考えなくてもわかることだろ。
どうしたら良いんだろうね。
>>529 Haskell<・・・
というのはともかく、コンピュータの本質は論理回路であり、
そして、論理回路そのものに手続き的な概念は存在しない。
現在のコンピュータで手続き型が自然に扱えるのは、
手続きが自然に扱えるようなアーキテクチャを持ったコンピュータが主流だから、というだけのこと。
「手続き型は手続きでプログラムできるアーキテクチャにとって自然だしな」なら使っていい。
スレ汚しでしかない
>>531 マルチディスパッチという方式について、
>>526 のどこで批判しているのか、
具体的に指してくれないか。
自分の書いた文章ぐらい自分で読めるだろうによ・・・ こんなのしか居ないんかい。
>>535 一行目で、
> マルチディスパッチ自体が悪いんじゃなくて、
> マルチディスパッチ自体が悪いんじゃなくて、
> マルチディスパッチ自体が悪いんじゃなくて、
と書いてあるのは読めるんだけどなぁ。
つーか、俺、お前がマルチディスパッチに否定的だって言ってないよな。
>「マルチディスパッチがあれば、オブジェクト指向を置き換えられる」という発想がおかしいんだな。
この一文に言及しただけで。
俺がむしろ聞かなきゃならんのか。
>>534 について、俺がいつそんなこと言ったんだって。もう何もかもがおかしいよ。
出鱈目すぎて会話が機能してない。
a_tとb_tは型変数なんだろ 型は変数に入れられないと考えるから密結合になる 型変数という発想ができないと疎結合は難しい
それは、C++やJavaも同じじゃねーか。
多重ディスパッチの話題は荒れるだけでなにも得るところがないな すぐ実装よりになるし
なぜ荒れるんだろうな。不思議不思議。 完全なOOPなら、マルチメソッドも実装されててしかるべきだし、 C風のスタイルが好きな人にも受け入れやすい仕組みと文法のはずなのに。 誰もが納得できそうな仕組みなのになぁ。不思議不思議
マルチメソッドって何だかめんどくさそう もし引数をk個とる関数があったとして、型がt種類あったらtのk乗個のメソッドを書かなくちゃいけないの? 例: 型a, b, cのいずれか2つを取るfuncがある場合、 func(a, a) func(a, b) func(a, c) func(b, a) func(b, b) func(b, c) func(c, a) func(c, b) func(c, c)通りの組み合わせが考えられる。 引数の組み合わせ爆発で大量のメソッドを誘発する臭いがぷんぷんするのはどうにかならないわけ? 一体何がスマートに書けるのかよくわかんね。
要求仕様上、組み合わせ爆発が起こったときに、それを記述するためのものだからね。 要求仕様がそうなら、もう仕方ないでしょ。爆発に付き合うしか。
>>543 そもそも、それを記述できるようにしなければならないという発想が余人には理解し難い
>>543 共通インターフェースを作って多態させる
従来のシングルディスパッチの方がスマートに書ける気がする。
>>542 それマルチメソッドかどうかに全然関係なくないか?
ふつーのOOPLでその要求を満たそうとすると、
型a, b, cにそれぞれa, b, cを引数に取るオーバーロードされたfuncを作るんだろう
つまり
a#func(a), a#func(b), a#func(c)
b#func(a), b#func(b), b#func(c)
c#func(a), b#func(b), c#func(c)
こうなる
全くおなじ話だと思うんだが
>>545 記述できたったて何の問題ないだろ。問題の無さこそが重要なんだと思う。
>>547 そそ、概ねそういうことが言いたかった。
要求仕様が複雑だと、どう書いても、複雑になるんだ。
問題の抱えてる本質よりは、どうあがいてもシンプルにはならないんだ。
仕様が爆発してたら、プログラムも爆発する。
言語でどうにかなるのは、せいぜい記述性だけだろう。
対象性のある言語の方が制限が少ないから素直に書き下せる可能性が高いってだけ。
>>546 その要求仕様は、共通のインターフェースを作れるってことは、爆発してないんだよ。
マルチディスパッチは単一ディスパッチもサポートするんんだから、
共通のインターフェースを作って纏めたい場合は、それを使えばいいじゃない。
>>548 なぜ、仕様だけは運命論的に受け入れるべきとなるのか。
責務君は、自分の責務のことしか考えない、自己カプセル化野郎だから、 コミュニケーションは無理なんだよ。
>>551 自分のやりたいことや、顧客からの要求なんだから、仕方ないだろ。なんじゃこりゃ
>>552 × 自分の責務のことしか考えない
○ 全ての責務を一手に引き受けて調整しようとする試みは必ず破綻する
>>553 要求仕様から、実装しやすい設計を考えればいいじゃない。
とりあえず、マルチディスパッチで、疎結合を実現しながらオブジェクト指向の方法論を 排除するにはどうすればいいのか教えてください。
つか、ディスパッチが静的か動的かはどうでも良いんだよ。 全体的な記述の統一感という理由だけじゃ、 OOであれなかれ、クラスという強力な機構を外すには 説得力が無さ過ぎるんだ。
>>550 マルチディスパッチ派って
どんな場合でも共通のインターフェースとかアクセサメソッドを作らない設計を推進してるんだって。
>>521 で
>そんで、単一オブジェクトのvtableに頼った設計も糞だと発見してもらうこと。
って言ってるのはつまり、インターフェースに頼る多態もクソって言ってるんでしょ。
>>556 ん?クラスってそんなに強力なものだったっけ?
C++触ってると、テンプレートとダックタイピングの方が強力に思えるんだが。
強力ネェ。
というか、マルチメソッドの方がより一層強力なのになぁ。よーわからん。
ダックタイピングにしたって、JavaScriptなどのスクリプト系言語で採用されてるのを見ると、
「強力」だから採用されてるんじゃないの?スクリプト言語ってそういうものでしょ。
クラスが強力ねぇ。俺にはコンパイラの都合の制限制限で貧弱に見えるなぁ。
単一ディスパッチにしてもそうなんだけどさ。コンパイラの都合でしょ?
多態時に共通の基底クラスを要求したりさ。
強力なのかねぇ。
>>554 >要求仕様から、実装しやすい設計を考えればいいじゃない。
マルチメソッドが有ればそれ使えってことでしょ
>>558 > クラスが強力ねぇ。俺にはコンパイラの都合の制限制限で貧弱に見えるなぁ。
ダイナマイトじゃ井戸は掘れない。
クラスの「強力さ」は、能力を適切に制限し、それを利用者に強制できること。
> >要求仕様から、実装しやすい設計を考えればいいじゃない。
> マルチメソッドが有ればそれ使えってことでしょ
マルチディスパッチが利用できようができまいが、メンテしにくいコードは書くべきではない。
> >そんで、単一オブジェクトのvtableに頼った設計も糞だと発見してもらうこと。 > って言ってるのはつまり、インターフェースに頼る多態もクソって言ってるんでしょ。 そそ、その通り。共通の基底インターフェースが要るからな。糞だな。 マルチメソッドだとこう書くだろうな。 int get_value( a_t *a ){} int get_value( b_t *b ){} *p //←a_tかb_tか実行時にしか決定できないポインタ int result = get_value( p ); //マルチメソッドで型を吸収 基底クラスが要らないってのが良いね。 Cの構造体や基本型も多態の対象に出来るし、 何の関係も無い複数のライブラリ同士で、似たような機能の型が同じ基底クラスもってて纏めたい場合でも、 いちいちアダプタクラス作る必要も無いしね。 マルチメソッドのありがたい副産物だね。 ということで、単一ディスパッチする場合でも、多重ディスパッチのある言語の方が楽。 何でこうなるかって言うと、多重ディスパッチが出来るってことは、それだけ歪無いってことだから。 歪んでないから、それ以外の事するにしても、上手くいく。応用が利くんだね。 掃除しとけってこった。
>>559 つまり、単一ディスパッチの制限下にプログラマを縛ることが、
「クラスの強さ」?
なんじゃそりゃ。それ、言語ですることか?
設計ルールでもコーディングルールでも好きに作ればいいのに。
うっかり使っちゃった!って類のものでもないだろ。
562 :
訂正 :2010/12/01(水) 23:16:38
ごめん、反対の意味に書いちゃった。これは痛い。 > 何の関係も無い複数のライブラリ同士で、似たような機能の型が同じ基底クラスもってて纏めたい場合でも、 ↓訂正 何の関係も無い複数のライブラリ同士で、似たような機能の型が同じ基底クラスもって無くて、纏めたい場合でも、
>>561 元の発言者は「クラスを外すこと」に対して疑問を呈しているのであって、
ディスパッチ方式については何も言ってないぞ。
それはともかく、
> 言語ですることか?
少なくとも、「言語でサポートすべき機能だ」と判断した言語制作者は少なくないとは言える。
言語処理系でサポートする利点の一つは、ルール違反を静的に検出できること。
必要ないという立場は当然ありうるが、開発が大規模かつ多人数で遂行するものであれば
あるほど、「静的に検出できる」ということのメリットは増大する。
>>563 >少なくとも、「言語でサポートすべき機能だ」と判断した言語制作者は少なくないとは言える。
スクリプト系言語では、ダックタイピングとかが主流なのに?
コンパイラの都合じゃねーの?
>「静的に検出できる」ということのメリットは増大する。
何が検出できるの?
マルチメソッドは型に基づいて行われるんだから、
たとえクラスがなくなっても、型は残るんだよ。
つまり、型チェックは行われるんだよ。
引数に対応する関数が無い場合はリンクエラーなんだよ。
クラスを外すことへの言及なんだよね。
クラスと型(struct etc)の違いって何?
フィールド変数へのアクセス制限の有る無しだよね。
だけどそれは別の仕組みを用意してもいいんだぜ?
例えば、ネームスペース単位でのカプセル化なんてどうだろう。
まーアクセス制限は簡単に実装できるから、どうとでもなるよな。
しかし、マルチメソッド=動的型言語ってイメージはついて回るね。 俺は静的型言語+マルチメソッドこそが本物だと思うよ。
>>564 ちょっと、君の論点を箇条書きにしてもらえるかな。
>>560 >>564 それってOOPじゃなくて完全な構造化プログラミングだよね。
構造化プログラミングするんならマルチメソッドはきっと便利なんだろうね。
OOPとは全く関係ないね。
・単一ディスパッチのOOPLは、誤った進化を遂げた あれ、一項目で納まった。 なんせ、単一ディスパッチである必要性がまったく謎だよね。 普通に考えたらマルチメソッドの方が良さそうに思えるものだろ? だって、マルチメソッドでも単一ディスパッチは出来るんだから。 なんで単一ディスパッチに特殊化する必要があるんだ? その非対称性はおかしいよ。 だって、オーバーロードは全引数に基づいて決定されるのにさ。 こっちは普通なのも謎だよな。そんなに単一ディスパッチが良けりゃオーバーロードも第一引数だけ見りゃいいのに。 (要は手抜きなんだろ) 特殊化ってのは不自然なんだよ。だから爪あとが残る。 たとえば、多態に共通の基底クラスが必要だったりな。 これは、単一ディスパッチに特殊化したときのオマケだ。 変なことするからどんづまる。 普通に進化しときゃ良かったのに、なんで特殊進化を採用したんだろうな。謎。 オーバーロードは対称性があってまともなのがまたこれ。
OOSEでも読めよ なんでそうなったか書いてるから
OOSCな
やったー。マルチメソッドはOOP関係ない認定を受けた。 これだよこれ。 普通であれば、OOP信者であればあるほど、マルチメソッドはすばらしいものに思えるはずなのに、 あえて蹴飛ばす。この謎現象が俺は大好きなんですよ。 第一引数のみによる単一ディスパッチの多態を愛する彼らは、第一引数病なんだとおもう。 第一引数に何もかもがぶら下がってる。まさに第一引数=Objectで、これぞOOPって感じだな。 マルチメソッドにするとOO臭が減るんだよね。 なんせ、関数が複数のオブジェクトに関連づいて、関数の所有が明確でなくなるからな。 だけど、それがいいんですよ、俺みたいなC言語とテンプレートとオーバーロードを愛するものにはな。 関数はインスタンスとインスタンスの間に割って入ってなんぼ。 関係を取り持つのが関数。それが機能(function)の本質。尊いよね。 嫌でも逃げることは出来ないんですよー。定めだからねー。その厳しさがまたなんとも。
>>571 これでこのスレを卒業できるな
おめでとう
>>569 だから、手抜きなんだろ?
マルチメソッドの上手いやり方は有るんだけど、当時じゃちょっと思いつかなかったかもね。
Cの構造体に関数ポインタ突っ込んでたのが元ネタだし、変なミスリードしたんだろうね。
当時の状況からして、とりあえず動きゃそれで良かったんだろうし。
その辺の事情は俺も汲み取るが、もう限界じゃね?0xが大変なことになってるぞ。
テンプレートもまずかったちゃまずかったかもな。
ああいう仕組みは型推論で実現したほうが素直だっただろうな。
明示的に型引数を与えるやり方も嫌いじゃないがね。
読んだことあるの?
いやないけどさ。それ読んで俺が納得できると思う?
できるかどーかは知らん。 でも読めば大体わかると思うよ
>>571 は Lisp で CLOS 使えばいいんじゃないか?
買ってみるもの一興ではあるんだが、 どうせ、実行コストがどうとか書いてあるんだろうなぁとか。 テーブルがでかくなりすぎるとか。 当時ではポインタに型情報を持たせて、型推論と上手く組み合わせるアイデアが思いつかなかっただけなんじゃないかと。 あと、分割コンパイルと動的モジュールのロードまわりとか。
そもそも規模、複雑さ、要件変化などから 構造化設計、手続き指向の限界が来て、DO、OOと時代が流れて来たのに、 その解決案もないまま時代に逆行して、賛同されるわけがない。
>>577 手続き型じゃないと嫌だよ。
LISPはOOPとは別のベクトルで頭がおかしくなるよ。
もっと普通なのが良い。高級アセンブラぐらい普通なのが良い。
時代に逆行ねぇ。長い歴史で見れば、OOPってどうなんだろうね。 オブジェクトをフューチャーした思想って、胡散臭いような。 八百万の神というか、擬人的というか。古きよき日本文化を思い起こさせる。 馬鹿にでも使えるようにってのはあるんだろうが、 創造性とはまた別だよなぁとか思ってる。
>>568 それは論点じゃなくて結論やー(ペシッ、と突っ込むのはもはや無粋だろうか。
まぁ、結果的にだが、いつもの人への反論を組み立てる過程でOOの立ち位置を再確認
できて、個人的には結構有意義ではあったりする。
というわけで、いつもの人も少しはそういった原典にあたって勉強してみてはどうか。
>>581 だから、この質問に説得的な論を示せればいいんだよ。
555 名前:デフォルトの名無しさん[sage] 投稿日:2010/12/01(水) 22:40:02
とりあえず、マルチディスパッチで、疎結合を実現しながらオブジェクト指向の方法論を
排除するにはどうすればいいのか教えてください。
だから俺は最近のAppleの流れには非常にまずいものを感じてるんだよねー。 わざとやってるのか天然なのか。悪意があるのか無いのか。う〜む。 Macバイナリ作ったような所だしなぁ。 誰しも社会の機能よりも自分の方が大事って悪しき心は持ってるし、 そこへ引っ掛けられるとなぁ。まー他人のビジネスに口出しするのも今風ではないんだが。 自分が引っ掛けられないように気を確かに保てば良いんだからなぁ・・・ってのもそれはそれで身勝手なような。 結局同じだったりするんだろうかね。 アメリカ風社会ってのはなんとも言えない味だな。 そう考えると、論点はソフト屋のコモンセンスの無さとOOPの関連性についてってことになるのかね。
586 :
デフォルトの名無しさん :2010/12/02(木) 01:06:45
> 長い歴史で見れば、OOPってどうなんだろうね。 「初期はばかでもプログラム組めます」ってのが売りだったな > OOP でも現実は馬鹿には手に追えない者だった
ソフト屋ですらない奴がソフト屋のコモンセンスを問うとか何のジョークですか?
ん?マルチディスパッチは共通の基底クラスを必要としない点で、C++なんかの多態より疎結合だし、 オブジェクト指向って言うほど、オブジェクト中心の考え方でもないんだから、 「どうすれば」とか言われてもなぁ。普通に使うだけでしょ。
>>588 マルチディスパッチでは多態させるためにfunc1( oo, xx )シリーズが組み合わせ爆発でずらずらと並ぶ。
カプセル化による内部データ隠蔽があるのか無いのかはっきりしないが、
無いのだとすればどれか一つのデータ型の構造に変更が加わるだけで、
そのデータを引数に取るfunc1を全て改修しなければならない。
多態のメリットをまるごとつぶしてるようにしか見えない。
>>586 歪んでるからな。一見簡単そうに見えるものほど実は複雑だったり。
簡単そうに見せてるだけって場合がほとんどだからな。
しかも簡単そうにみせるための仕組みで余計複雑怪奇になってたり。
だって、難しいものは簡単にはならんだろうよ。難しいものは難しいままで良いんだよ。
良くあるのは一部だけ見せるってやつな。最近のGUIで多いよね。メニューバー隠したり。
過去には1ボタンマウスってのがあったな。アレは最悪だった。
今はセンサーでやってるんだっけか。もっと最悪だな。何で隠すんだろうな。
とりあえずホイールは画期的だったね。
OOPで言えば、オブジェクトを前面に持ってきたってのがなぁ。
アイ何とかって感じだよな。
したたかにCにマルチメソッドでも実装してればよかったのに。
>>573 C++が大変なことになってるのは一番最初から。
Cとの互換を目指したのがC++最大の間違い。
OOPLとしては最も腐ってるものを引き合いにして
OOPLを語られても困る。
>>590 アクセサ通してアクセスすりゃいいじゃん。
単一ディスパッチで纏められる要求仕様なら、纏めればいいじゃん。
マルチメソッドは単一ディスパッチも出来るんだぜ。
ただ、マルチディスパッチと言う飛び道具もありますよってだけで。
マルチディスパッチ自体が重要なんじゃなくて、
マルチディスパッチをサポートすることで言語仕様に対称性がでることに意味がある。
たとえば、多態するのに共通の基底クラスが必要なくなったりする。
多態のことなんか何も考えてないCの構造体で多態できたりもする。
もちろん基本型でも多態出来る。凄く自然なんだよ。
そういう自然さが大事。
オブジェクトにvtable持たせたのが運のつきだね。
多態はポインタ越しにしか行わないんだから、
型情報はポインタに持たせれば良かったんだよ。ポインタががんばる。インスタンスは何もしない。
構造体→型持ちポインタ→マルチメソッド機構→Cスタイルの関数。
こんな単純な仕組みで良かったんだよ。継承とか要らなかったね。
>>592 互換性なんて微塵も無いのにな。
だって、継承なしのCの構造体では多態できない。
オーバーロードは機能するがな。
マルチメソッドだと、継承なしのCの構造体でも多態できるし、vtableみたいなゴミも付かないし、
そっちのが互換性あったのにな。
システム増築するときって、元のシステムにはなるべく手を加えないようにするもんだろ。
何勝手に構造体にvtableとか追加してんだよ。
新しく、動的型持ちポインターとか増設して、そっちで多態なりなんなりすりゃよかったのにな。
その型持ちポインターからマルチメソッドのテーブル通してCの関数にリンクさせりゃ良かった話じゃねーか。
本当に、なんでああなったんだろうな。
>>593 マルチディスパッチがあってもいい理由としては分かったが、
オブジェクトが要らない理由にはなってないよ。
アクセサ(というかアクセサはメソッドの役割のほんの一部だぞ)があっていいなら、
特定の関数群をオブジェクトという単位でまとめてはいけない理由は何?
『プログラムはデータとそれを操作する関数として記述されるべきであり、
「特定のデータに属する関数」という存在はナンセンスだ』というのが君の主張だったよね。
むしろ、あるオブジェクトの状態を操作する関数が一箇所に記述されていることが
言語として保証されていた方が、コーディングをする側としては見通しが良くなるよね。
「あるオブジェクトを操作するメソッドは、あるクラスの中に書かれている物以外に存在しない」
ということに確信が持てるからね。
>>593 は?
C++でCスタイルの構造体に、vtableなんてついてないぞ?
クラスのスタイルで書いたら特殊なクラスになるだけだ。
>特定の関数群をオブジェクトという単位でまとめてはいけない理由は何? vtableを持つ羽目になるからだ。それでも動的型言語ならまだマシなんだが、 静的型言語だと継承しなきゃ多態できない。 しかもvtableを構築するためには継承しか手段がないから、 クラス設計者以外は多態のあり方を決めれない。 クラス設計者がインターフェースを決め打ちするわけだ。 よって利用者はインターフェースが気に入らなけりゃ、アダプタクラスを作る羽目になる。よくある光景。 初めから多態前提で設計しなきゃ多態出来ない。 でも、そのクラスがどう使われるかまでは、クラス設計者にはわからない。 クラス設計者は、クラスの内のことは解っても、外のことはまるで解らないだろうに。 なのにクラスの中で多態の仕組みを構築する。。おかしいだろ。 多態は、どう使われるかって言う、外の世界の影響を色濃く受けるのによ。 外の世界の都合で決まるものを、内で定義するのは変だと言って・・・あー眠たくて文章が支離滅裂気味 要は、多態は外でやれ。共通の基底クラスなんてもってのほか。 >むしろ、あるオブジェクトの状態を操作する関数が一箇所に記述されていることが カプセル化はまた別の仕組みでやりゃ十分だと思うがね。 ネームスペース単位のカプセル化なんて勝手が良さそうに思うが。 クラス単位だけってのそれはそれでしんどいでしょ。
>>596 構造体にvtableが有ったり無かったりする訳だよ。
まー別にC++のRTTI構造体がCのそれと同一である必要はまるで無いのだが、
同一でなくする必要もまた無かったんだよ。ポインタに型情報を持たせりゃそれで済んでた。
あえて違わす必要も無かっただろ。互換性重視っていうならなおさら。
Cの構造体で多態できるようにもなるしな。
・classをやめてinterfaceにすれば疎結合になる ・interfaceにはフィールドがないのでprivateもprotectedも不要 ・interfaceにはコンストラクタもデストラクタもない まずは「classはせいぜいstructと同程度の価値しかない」ということを確認し その後でマルチメソッドについて議論すればよいと思います
マルチメソッドが有れば、インターフェースなんぞいらん。 名前が同じ関数は、全て同じインターフェースだ。 ひとたび呼び出せば引数の型に応じて正しくディスパッチされる。 ただそれだけ。
>>597 君が今言ったそれをひっくり返すと、それがそのままオブジェクト指向で書くことの
メリットになるってことには気付かないかな。
> クラス設計者がインターフェースを決め打ちするわけだ。
> クラス設計者は、クラスの内のことは解っても、外のことはまるで解らないだろうに。
だからこそ、オブジェクト間の疎結合が実現できる。
それが、オブジェクトの外側に対して一切責務を持たず、インタフェースが固定されていることの恩恵だ。
多態は、無理に使う必要は全くない。
よくあるパターンは、インタフェースである HogeService と、唯一の実装クラスの HogeServiceImpl だな。
んで、単体テスト時に、HogeServiceImpl の代わりにモッククラスの HogeServiceMock を使うことで
テスト容易性を高めることができる。
> よって利用者はインターフェースが気に入らなけりゃ、アダプタクラスを作る羽目になる。
いいんだよ、それで。無理に丸のまま再利用する必要なんかない。
>>600 少なくとも、オブジェクト指向の文脈ではそれをインタフェースとは呼ばんよ。
interfaceでない引数はディスパッチと無関係ということにすれば 組み合わせが多すぎるという問題が起きにくいと思います
>>519 Rubyのハッシュを使って関数を実行するとこんな感じになるね。
def func1
print "hello"
end
x = { "hello" => func1 }
x["hello"] # これでfunc1()を実行したことになる
クラスをまるごとハッシュに入れることも可能。
class FuncClass
def func1
print "hello"
end
end
func_obj = FuncClass.new
x = { "hello" => func_obj }
x["hello"].func1()
func(obj1, obj2)ってやっぱりわかりにくいだろ。 funcにobj1,obj2を渡して、それがどう処理されて、どういう結果になるのか仕様書見ないとわからない。 戻り値があるのかないのか、エラーはどこに返されるのか、結果はobj1,obj2に入って返されるのか、 それとも左辺に出てくるのか、どういう形式で返ってくるのかなどいろいろ調べなきゃならない。 obj.method(obj2);なら、objオブジェクトがどういうことをするオブジェクトかが大体わかっていれば、 そのオブジェクトにmethodというメッセージを投げているのはすぐわかるし、 そのmethodを実行させるためにobj2が必要なんだなということまではわかる。 他人が書いたソースを読むときの読みやすさが全然違うと思うんだけど、どうよ。 マルチメソッド使わせたいなら、どれだけ簡単に書けて、どれだけコードが読みやすくなるかという メリットを示さないと広く使われることはないだろうな。
流れ読んでないが、一言。 両方の型でポリモしたいようなときはobj.method(obj2);じゃ正直まんどいよな。 だからダブルディスパッチに、苦肉の策でVisitorパターンなんか使うわけで。 A, B, C, D, Eクラスがあって相互に衝突検出を使用とした時とか。 そこに追加でFクラスが来たとき、全部のクラスに追記が必要だし、 AとBの衝突を「どっちに書くのか?」という問題もあり、 A.衝突(B)とB.衝突(A)に矛盾がないようにしようとするなら、 互いに実装について申し合わせてないといけない? これはなんとかなる? Visitorパターン使ったとしても、やったことあるやつなら分かるが煩雑。 あーしてこーしてこう。そんなんするくらいならマルチメソッドとやらで、 衝突(A, B)と書かせてもらうほうがよっぽどラク。よっぽど自然。 これは、ダブルディスパッチせざるを得ない状況が設計として悪いのか、 どうなのか、ちょっと先に考えてみたい気もするが。
>>607 衝突(a,b)なら
interface 衝突インターフェース {
衝突する(<衝突インターフェース> 対象)
衝突される(<衝突インターフェース> 何に衝突されたか)
// その他、衝突処理内での通信に使うメソッドをいくつか
}
んで、A〜Eクラスは衝突インターフェースを実装。
衝突(obj) は内部で必ず obj.衝突される(self) を呼び出すものとする。
これでお互いのオブジェクトを参照可能になるので、あとはお互いの衝突処理をする。
どっちに書く、ではなく、どっちも自分についてのみ書く。
相手に何かして欲しいなら、インターフェースに書かれたメソッドを使って「○○して」と頼む。
ところで、自分で書いてて思ったんだがこれって何てパターンになるの? OOPLはよく使うけど、デザパタは良く知らんのだが。
カプセル化による共通インターフェースの提供を否定するダブルディスパッチは多態じゃないから。 引数をvoid*で受けてRTTIかその他の識別コートを解析して処理を決定するのと大差ない。 文法定義が関数定義に置き換わったパーサと同義。 その上で「じゃあ多態じゃなくてもいいや」というのは至極真っ当な判断。多態に拘る必要は無い。
オブジェクトa, bの衝突を判定する責任を負うのは誰か?と聞かれたらa, bのコレクション(あるいはその所有者)になると思う。 コレクション.衝突判定() みたいなのがあって、その中で全オブジェクトの衝突を判定するわけ。 a,bを含む各オブジェクトは位置、形状、サイズなど、衝突判定に必要な情報を持たないといけない。 その条件付けを決めるのがインターフェースや基底クラスの役割。 その上で、矩形同士、円と円、円と矩形など、特定の矩形の組み合わせの場合に計算を簡素化(最適化?)できる場合がある。 この時、無理に共通インターフェースと称して各図形をポリゴンや矩形の組み合わせなどで近似したり、 形状ごとにifやcaseで分岐するよりも マルチメソッドを使って場合分けすればシンプルに記述できるのではないか。 interface 形状 {}; class 円 implements 形状 { 中心 x,y; 半径 r;}; class 矩形 implements 形状 { 幅 w, 高さ h; }; interface 星 { 形状 getShape(); } class コレクション { 星 hoshi[]; 衝突判定() { for (int i=0; i<hoshi.length()-1; i++) { if (衝突判定(hoshi[i].getShape(), hoshi[i+1].getShape())) { /*衝突してたときの処理/* } } } 衝突判定(円, 円) { /*円同士の衝突判定*/ } 衝突判定(円, 矩形) { /*円と矩形の衝突判定*/ } 衝突判定(矩形, 円) { /*矩形と円の衝突判定*/ } 衝突判定(矩形, 矩形) { /*円同士の衝突判定*/ } }
>>611 横からだが。
if (衝突判定(hoshi[i].getShape(), hoshi[i+1].getShape()))
↑これじゃあ狙い通りにディスパッチできないよね?
衝突判定(形状, 形状)
を↓に割り振る仕組みが、Visitorパターンだったりする。
衝突判定(円, 円) { /*円同士の衝突判定*/ }
衝突判定(円, 矩形) { /*円と矩形の衝突判定*/ }
衝突判定(矩形, 円) { /*矩形と円の衝突判定*/ }
衝突判定(矩形, 矩形) { /*円同士の衝突判定*/ }
だから、ディスパッチするだけで不毛なステップを要する。
>>611 > 衝突判定() {
> for (int i=0; i<hoshi.length()-1; i++) {
> if (衝突判定(hoshi[i].getShape(), hoshi[i+1].getShape())) { /*衝突してたときの処理/* }
> }
> }
上記を下に訂正^ ^;
衝突判定() {
for (int i=0; i<hoshi.length()-1; i++) {
for (int k=i+1; k<hoshi.length(); k++) {
if (衝突判定(hoshi[i].getShape(), hoshi[k].getShape())) { /*衝突してたときの処理/* }
}
}
>>612 >if (衝突判定(hoshi[i].getShape(), hoshi[i+1].getShape()))
>↑これじゃあ狙い通りにディスパッチできないよね?
多重ディスパッチをサポートしてる言語のつもりで書いたんだけど、それでもだめかな?
> 多重ディスパッチをサポートしてる言語のつもりで書いたんだけど おk把握。
OOP + マルチメソッド が最強ということだな
>>607 その例は、マルチディスパッチが必要とされる場面の代表的な例だね。
そういうコーディングが必要な場面はあるにはある。
けど、そこからオブジェクト指向は云々というのは論理の飛躍と言わざるを得ない。
だって、A, B, C, ...がオブジェクト指向的に作られていることと、マルチディスパッチは矛盾しないから。
いつもの人の主張は、A, B, C, ...の内部状態の操作は、個別のオブジェクトに属させず全て衝突()に書くべき、
というもので、それが疎結合の実現という観点から言って問題がある、という点は既に指摘した通り。
また、衝突()でA, B, C, ...を操作する際に各オブジェクト専用に定義したアクセサ関数を経由するようにするなら、
なおさら、オブジェクトにメソッドを属させるというコンセプトや、カプセル化といった便利な機能を手放す理由はない。
静的型言語なら、形式的なルールをコンパイラが静的にチェックしてくれるというメリットまでついてくるのだからなおさら。
マルチメソッド編はこれにて一件落着だな 次はダックタイピングか?
次はVisitorパターンだ。 Visitorパターンの主張は、 obj.accept(visitor); objに属するメソッドはaccept()だけで他は全てVisitorとして独立するべき、 というものだ。
マルチディスパッチの代用品だし、そんなに積極的に使うべきパターンというわけでもない。 とりあえずメリットを言うなら、「データからアルゴリズムを分離し、新たな操作の追加が容易になる」こと。
>いつもの人の主張は、A, B, C, ...の内部状態の操作は、個別のオブジェクトに属させず全て衝突()に書くべき、 何でそうなるんだよ。衝突判定の関数の中から、別の関数を呼んでも良いし、 その別の関数とやらが、多態性を持っていたってかまわないし。要は自由なんだよ。 結合度は書く人次第だよ。 単一ディスパッチで出来ることは、マルチメソッドでも出来る。 マルチメソッドで出来ないことは単一ディスパッチにも出来ない。 結合度についても同じなんだ。 単一ディスパッチの方が結合度が下がる仕様条件なら、単一ディスパッチですれば良い。 マルチメソッドは単一ディスパッチもサポートしてるんだからな。
でさ、マルチメソッドは言語の対称性があがって綺麗になるが、 そんなに出番は無いだろう。基底クラスを持たなくても良いから、その分楽になるってのはあるが。 いつも何か思いつく俺だけど、今度はGCについて思いついた。 メモリを勝手に管理してくれるのはいいが、OSのリソースの面倒までは見てくれない。 仕方ないからメモリに括り付けて、CG発動時に開放されるようにプロシージャを仕込んどく。 だけど結局いつGCが発動するか解らないから、結局こまめに手動で開放したりする。 でもさ、俺おもうんよ。面倒見れないんだったら、初めからノータッチでいいだろ。 メモリブロックの種類を2種類に分ければいい。 メモリのみのリソースを含むものと、メモリ以外のリソースを含むものに。 前者はメモリしかリソースを含まないって言ってんだから、CGで回収すりゃいいし、その際、開放関数をコール必要も無い。 後者はメモリ以外のリソースも含むのだから、CGでは回収しない。手動で開放する。 しかし、マーキングは行い、メモリリークを検出する。ログかなんかに吐き出す。 何処からも辿れないメモリ断片があるぞ。開放忘れてんじゃねーかって。 マークアンドスイープnew、マークnew、普通のnew、と言う風に、newのバリエーションが3種類になる。 ちょっと煩雑すぎるかネェ。
>>620 多態を使うか使わないか、単一ディスパッチかマルチディスパッチかは、
結合度の話とは関係ないのだが。
マルチディスパッチを使うと結合度が上がるんじゃなくて、複数のオブジェクトの状態を
一つの関数内で同時に操作しようとすると結合度が上がる、という話。
>>620 自由自由というけど、どのくらいの規模のソフトを
何人ぐらいで作るのを想定しとんの?
>複数のオブジェクトの状態を
>一つの関数内で同時に操作しようとすると結合度が上がる
それは、そのプログラムの要求仕様から導き出された設計仕様だろ。
要求仕様が複雑だと、設計仕様も複雑になるっていってるようなものだ。
何も言ってないんだよ、お前は。
マルチメソッドも、OOPも、何もかも関係ない。
>>526 をよく読み返してみ。支離滅裂だろ。
>「マルチディスパッチがあれば、オブジェクト指向を置き換えられる」という発想がおかしいんだな。
>これらの関数は、どう逆立ちしたって a_t や b_t に密結合したものにならざるを得ない。
とお前は言うが、その例だと、マルチディスパッチが無い場合でも、密結合になるだろう。
何の証明にもなってない。
マルチディスパッチでも密結合。単一ディスパッチでもOOPでもCでも密結合。なんも変わらん。
人間の思考って過去の経験を肯定するほうを選択するよね。 だから何を言ってるかより誰が言ってるかのほうが重要。
>>625 > それは、そのプログラムの要求仕様から導き出された設計仕様だろ。
要求仕様を「素直に」実装すると密結合になるなら、疎結合になるように設計を変えればいいじゃない。
単一ディスパッチはレキシカルスコープの代用品だ。 だから設計思想的に安定している面もあるが、 単なる代用品を超えて「過去の経験」を打ち破ってほしい面もある。
どう言えば彼は納得するんだろうな。 彼の言ってることは、 「複数の引数を取る関数は、その引数について密結合になる」ってことでしょ。 でも、それは、マルチメソッドとは関係が無いよね。 そもそも、マルチメソッドは呼び出しの方式だから、ディスパッチ先の関数の結合度には関与しない。 なんつーかさ。仮に int func( a_t a, b_t b)って関数があったとする。これは、引数のa_tとb_tについて、密結合だったとする。 この関数を呼び出す方式が、マルチメソッドだろうが、単一ディスパッチだろうが、静的呼び出しだろうが、 この関数自体の密結合には関係が無いよね。あくまで呼び出し方式の違いなんだから。 どう呼び出そうが、ディスパッチ先の関数の結合度は変わらないよ。 どういえば伝わるんだろうね。無理かもね。
>>672 で、その疎結合になった設計は、
マルチメソッドを実装した言語でも記述できるんだろ?
だとえば、インターフェースそろえて単一ディスパッチに正規化しましたってんなら、
それでいいじゃない。マルチメソッドは単一ディスパッチもサポートするんだから。
マルチメソッドは、OOPの置き換えにならないってことにはならないだろ。
含まれてるんだから。
アンカー振られても反論としての意味がわからない。
>>632 >>616 > だって、A, B, C, ...がオブジェクト指向的に作られていることと、マルチディスパッチは矛盾しないから。
> いつもの人の主張は、A, B, C, ...の内部状態の操作は、個別のオブジェクトに属させず全て衝突()に書くべき、
> というもので、それが疎結合の実現という観点から言って問題がある、という点は既に指摘した通り。
> また、衝突()でA, B, C, ...を操作する際に各オブジェクト専用に定義したアクセサ関数を経由するようにするなら、
> なおさら、オブジェクトにメソッドを属させるというコンセプトや、カプセル化といった便利な機能を手放す理由はない。
>手放す理由は無い マルチメソッドがOOPの置き換えになるって、もう自分で気づいてるじゃねーか。 理由は無いってだけで、「出来る」んだろ? 置き換えになるじゃねーか。
> いつもの人の主張は、A, B, C, ...の内部状態の操作は、個別のオブジェクトに属させず全て衝突()に書くべき、
こんなことも言ってないしね。
それもかなり初期の段階でコードまで書いて示してる。
>>528 でな。
そもそも、君がマルチメソッドマルチメソッド言い出したのはそれをやるためだったと 記憶しているのだが、忘れたか趣旨替えしたのなら、まぁいいや。 んで、互いに置き換え可能(?)な構文を作るのはいいんだが、 ところで、オブジェクト指向で書くとダメな理由はどこへ行ったの?
>そもそも、君がマルチメソッドマルチメソッド言い出したのはそれをやるためだったと どこで書いた?単一ディスパッチを使うことを否定した覚えは無いが。 マルチディスパッチが出来ないことや、vtableの方式を否定しただけで。
638 :
デフォルトの名無しさん :2010/12/03(金) 00:51:21
マルチディスパッチって 宣言型プログラミングの場合はどういうことになるんだろう・・・
静的オーバーロード扱いになるんじゃない?ちょっと良くわからんが。
マルチメソッドの話はもう飽きたし、俺は使わないから他の話にしてくれないかな。 マルチメソッド使いたい人は自分だけ使ってればいいだろ。
>>634 横から
曲解しすぎだろ
「便利な機能を手放す理由はない」がなんで「置き換え可能」になるんだよ
あと単一ディスパッチとOOPを等号で結ぶのもやめてくれ
単一ディスパッチは多重ディスパッチで置き換え可能
と
OOPはマルチメソッドで置き換え可能
は別物だろ
>>637 > そもそも、君がマルチメソッドマルチメソッド言い出したのはそれをやるためだったと
「それ」=obj1.func(obj2)という記法は誤りで、func(obj1, obj2)が正しいということを正当化すること
な。
643 :
デフォルトの名無しさん :2010/12/03(金) 09:44:35
それオブジェクト指向となんか関係あんの?
無いだろうね 記法は記法でしかなく、仕組みでもないんだし
記法は実はもっとOOPらしさに関わってるような気もする。 cat foo | grep bar | sort | uniq uniq(sort(grep(cat(foo), bar))) cat foo.grep(bar).sort.uniq メソッドの連結が思考の流れと近いのが好ましいのかもしれない。
とはいえ、非OOPLでも命令や手続きを後置する言語あるのがなあ FORTHなんかがそうだし、日本語プログラミング言語とかには割と多い 逆に、OOPシステムでありながら前置するCLOSとかもあるし
指向の流れに一番近いのは手書きイラストだろ常考
手書きイラストで何をどないせーっちゅーねんw
FORTHやMIND(やPostScript)は前置後置というよりスタックマシンが生で見えてるだけだろ。
"foobarbaz" sb // string buffer append(append(append(sb, "foo"), "bar"), "baz") sb.append("foo"),append("bar").append("baz")
>>648 画面にファイルのアイコンとディスプレイのアイコン書いて
フリーハンドの線で矢印ひいたら矢印の向きにデータ転送が行われるとか
652 :
デフォルトの名無しさん :2010/12/03(金) 12:38:56
それってポリモーできないんじゃない?
前置後置はさておき
>>630 操作の主体たるオブジェクトを特別扱いするのはOODの根本で、
あるオブジェクトを特別扱いすることが出来ないのは
OODによる設計を実装する言語としては二流。
OO開発手法を否定するならともかく、
いつもの言語はOOPLの変わりにはなれない。
あとマルチメソッドは言語機能でOOPは実装手法なんだから
比べるのは無意味で置き換えもクソもない。
人月の神話を実現する言語としては。
「え、神話?」 「はい。神話です。敵全員に大ダメージを与えます。」
人月の神話、っつって話が通らないような会社からは全力で逃げるべきだなJK
いまごろこのスレ知ったので前スレのログがあればだれかupしてくれぬだろうか?
カプセル化が変数を隠蔽するだけでも相当美味しいと思うけどな。 構造体を第一引数に渡してOOPと同等のことができる〜みたいな論調もたまに見るが、 アクセスできない、とアクセスしなければ同等、とには無限の隔たりがある。 前者はそれを前提に、次のステップへ思考を移すことが出来る。
カプセル化すると内部データ構造を後から簡単に変更できる場合がある。 やっぱ配列やめて連結リストにしようか、とか。
>>660 インタフェースと実装を分ければ、インタフェースが外部に対して約束している挙動を実現している限り、
実装を自由に変えることができる。リスコフの置換原則、でググってみるといい。
また、言語処理系がカプセル化をサポートしていれば、上記のことを確実に保証できる。
「プログラマが気をつければ問題ない」と思うかもしれないが、バグの多くは、
プログラマのちょっとした勘違いや、プログラマ同士のコミュニケーション齟齬によって生まれている。
機械的な方法を導入すれば、こうしたヒューマンエラーに基づくバグを根絶できるのだから、
積極的に導入しない理由がない。
>>659 foo-private.h
#include "foo.h"
struct foo {
int foo1;
char foo2;
...
};
foo.h
typedef struct foo *foo_t;
int get_foo1(foo_t bar);
void set_foo1(foo_t bar, int baz);
char get_foo2(foo_t bar);
void set_foo2(foo_t bar, char baz);
...
とかやっておいて, foo-private.h を使用者側に公開しなきゃええんちゃう?
# そうゆう問題とちゃってたらごめん
>>662 カプセル化のコストとしてはどんなことを計量すればよいのでしょうか?
スコープってあるじゃん。 なんで全部グローバル変数にしないかっていうと、 あるいはなぜグローバル変数を消極的に使うかっていうと、 プログラム全体に変数が散らばっていくのを避けるためだ。 頭が超良くて、どんなに複雑でも瞬時に理解できるノイマンみたいなやつだと、 グローバル変数多用しても、実は問題ないのかもしれない。 しかし脳が非力な一般人はそうはいかない。できるだけ複雑にしたくない。 変数がプログラム全体に晒されるようなこともしたくない。 OOP、ここで特にクラスベースのそれでは、privateなメンバ変数は、 クラスの中だけに隠しておくことができる。アクセスは局所化しうる。 従来のスコープという概念に加え、クラスの内外というレベルでの制限ができる。 とくに生存期間が中期、長期のものは、それが生きている間、 いろんな場所を渡り歩く間、ずっと隠されるメリットは大きい。 もしこれが丸出しだったら、デバッグ時、渡り歩く箇所全部がデバッグ対象となる。 変数が小さくアクセスされるようにするのが正義。 カプセル化のおいしさも、結局そこにあるんじゃないか。
>>665 変数を隠すのはいいんだが
変数を包む型や変数を初期化するコンストラクタを隠さなくていいのか?
>>663 概ね正解(*foo_tの宣言時にfooって居なくていいんだっけ?)。
けど、言語処理系のサポートがあれば、もっと簡潔かつ柔軟に記述できる。
例えば、この場合はfoo-private.hを他のプログラマに渡すか渡さないかで制御しているわけだが、
オブジェクト指向言語なら、一つのクラス/オブジェクトに全てを記述できるので見通しが良くなるし、
protectedみたいな芸当もできる。
>>664 外部に公開するインタフェースを吟味するコストとか?
>>666 依存性注入(DI)だな。そういうフレームワークは存在する。
利用者はインタフェース型だけ利用でき、インスタンスはDIフレームワークから受け取るのみとする。
実装型の知識やオブジェクトのインスタンス化は、全てDIフレームワーク側に設定ファイルとして持たせる。
>>667 言語処理系のサポートがあった方がいいのは確かだけど
オブジェクト指向かどうかはあまり関係ないよな
>>669 オブジェクト指向プログラミングの道具立てである個々の要素技術は、
オブジェクト指向に特有の概念ではない、という意味ではそうだね。
プログラムをオブジェクトという単位で考え、それを組み合わせて構成することで、
疎結合を実現する概念のことを「オブジェクト指向」と呼んでいるだけの話。
そして、オブジェクト指向でのコーディングをサポートするオブジェクト指向言語には、
多くの場合、カプセル化などの機能が備わっている。
>>670 オブジェクト単位ならば疎結合で、メソッド単位ならば密結合ってことかな?
この主張がさんざん物議を醸していたわけだが
>>671 メソッド単位じゃなくてモジュール単位だな。
で、俺も
>>670 の疎結合という言葉に引っかかる。
>>526 からずっとおかしいし、疎結合の意味を取り違えているかOOに偏狭しているように思える。
>>671 オブジェクト単位といってもオブジェクト間のやり取りはメソッドでやるんだから
その比較はあまり意味がないのでは?
>>673 継承のことを言ってんじゃないか?
それにしても継承の事はあまり話題に上がらないよね
このスレ
実装はクラス単位 やり取り=インタフェースはメソッド単位 「結合」に関与するのは実装ではなくインタフェース クラスとインタフェースは類義語ではなくてむしろ反意語 だからクラス寄りのOOPとインタフェース寄りのOOPがある この比較は意味がある
また頓珍漢な説がでてきたな…
前にも言ったことだが OOPが頓珍漢なのは今に始まったことではない それと、そうやって確信的に頓珍漢だと断定するのは形容矛盾だ
>>671 既に指摘されてるけど、メソッドは対称となる概念ではないかな。
あえてメソッドに絡めて言うなら、あるオブジェクトの実装が、他のオブジェクトの
メソッド「のシグネチャ」にのみ依存しているなら疎結合だし、
メソッド「の実装」に依存しているなら密結合、ということになる。
>>672 確かにあまり厳密な使い方はしてないけど、一般的な用法からそんなに外れてないと思うよ。
早い話が、一方の実装が他方の実装に依存してない状態を指して言っている<疎結合。
このとき、一方に手を加えたり別の実装と取り替えたりしても、他方は一切変更する必要がない。
>>676 JavaやC#みたいなinterfaceキーワードがあるオブジェクト指向言語なら、
実質的には「クラス=実装クラス」として使われるから、そういう意味なんじゃない。
『インタフェースに対してプログラミングせよ、実装に対してプログラミングすべきでない』
679 :
デフォルトの名無しさん :2010/12/04(土) 22:02:37
まーた始まった
>>678 相変わらず
>>526 の意味が分からない。なぜ関数形式にすると密結合になるのか。
関数形式でもモジュール単位でアクセス制御すれば、OOと同程度に疎結合にできるはず。
>>671 が指摘したかったのもその辺りのことなんじゃないかと思って672を書いた。
>>675 に関しては中2行が酷過ぎて話にならない。
>>681 もうちょい具体的に書けよ
>>682 なってないし、どの部分が説明になっていると考えたのかも分からない。
>>683 アンカーはしょったのが悪かったな
681は
>>679 宛てだ。レスが間に挟まっただけ
679が君の発言じゃなければ特に関係なし。
>>680 非公開であると宣言するクラスと、宣言したものは素直に公開するインタフェース
どっちが酷いだろうか
>>683 >>526 は一般論として「関数形式にすると密結合になる」と言いたかったのではなくて、
>>616 の後半で書いた通り、いつもの人の(以前の?)主張に対する反論として書いたものなので。
正直、彼はモジュール単位でアクセス制御するという発想があるかも怪しいし。
あえて言おう 非公開メンバーであると
>>685 何を言っているのか全く分からない。
誰もそんな話はしてないよ。
>>686 例の人に対する反論だとしても
>>526 の意味は通らないと思うが。
それと例の人はモジュールという言葉は使わなかったかも知れないが、
>>597 で同じ意味のことを書いている。
>>688 >>616 の後半に書いてあることが全てなので、もう一度読んでくれとしか言えないなぁ。
いつもの人については、いつの間にか主張が変わってたみたいなんだよねぇ。
まぁ、いいけどさ。
>>689 >>616 にこうある
>疎結合の実現という観点から言って問題がある、という点は既に指摘した通り。
この「疎結合の実現という観点から言って問題がある」と考えた理由が聞きたいの。
「既に指摘した通り」というからにはここでは書いてないってことだろ?
あと、オブジェクト単位の方がモジュール単位よりも柔軟なアクセス制御ができるとは思う。
以前、「オブジェクト指向の本質はマルチプルインスタンスだ」という趣旨の文章を書いて
物議を醸してた人がいたけど、モジュールより柔軟な運用ができるのがオブジェクト指向だ、
という趣旨に限って言えばその通りかな、と思う。
いちおう張っとく。
http://kmaebashi.com/programmer/object/
>>690 いや、単に
func(A obj1, B obj2)
{
obj2.a = obj1.a;
obj1.b = "...";
obj2.c = 1;
}
みたいなコードがあちこちにバラまかれてたら、AやBのデータ構造やアルゴリズムが変わる度に
大変なことが起きるよね、という程度の話なのだけれども。
>>226 >public staticとprivate staticは非OOと実質同じだから、
>public/privateよりも、「staticではない」ことが重要。
>>599 >classはせいぜいstructと同程度の価値しかない
>>692 たぶんここで根本的な勘違いをしている。
例の人の考えた言語がCに似ているから勘違いしたんだろうけど、例の人の考えでは
おそらく構造体のフィールドをデフォルトで非公開として(というかドット記法が存在せず)、
アクセサ関数を通してのみアクセスできるという仕様を想定しているはず。
そしてアクセサ関数はモジュール単位で公開・非公開を制御すればいい。
これは特別なものではなく、例えばHaskellのような(というか俺は関数型はこれしか知らないが)
言語でもそうなっている(はず)。
こう考えると
>>526 からの間違いも全て説明がつく。
>>694 正直、本人の居ないところで、他人の考えをあれこれ推測しながら喋っても不毛だと思うんだけども。
まぁ、少しだけ言うと、アクセサ関数とか用意するなら素直にオブジェクト指向言語で書けばいいし、
その方が柔軟なアクセス制御が実現できる。
それに、純粋なデータオブジェクト以外で、オブジェクトの操作手段としてアクセサ関数が出てくる状態は、
オブジェクト指向のプラクティスから言って良い傾向ではない。
そもそも実在しない擬似言語の言語サポートを理解しつつ議論しろ というのが土台無理な話だ。
>>694 横からだがそれは違うような。
いつものの主張では、
「
>>663 のような実装をすればカプセル化も実現出来るんだから良いじゃないか」
ということで、言語はそれを強制しないし、そのための支援もしないはず。
なんかソレっぽいことをこのスレで言ってなかったっけ?
>>695 例の人の言語話は間違いを気遣ったつもりだったが、余計なの出さなきゃよかったな。
>アクセサ関数とか用意するなら素直にオブジェクト指向言語で書けばいいし、
>その方が柔軟なアクセス制御が実現できる。
それはまた別な話だな。それはそれで議論したらいいと思うよ。
>オブジェクト指向のプラクティスから言って良い傾向ではない。
だからOOに限定しない話をしてるのに、「OOのプラクティスから言って…」はないだろ。
>>696 例の人の言語を理解しろとは言ってないしhaskellという明確な実例もだしてるだろ。
>>697 言ってなかったっけって言われても知らないし、例の人をだしたのは悪かったけど
疎結合の話に例の人は関係ないよ。
何にせよ、「関数で書くと密結合になる」なんてことは言って無い、ってことで許してもらえないかね。 そりゃ書き方によるし、オブジェクト指向言語には良い書き方を強制するサポートがあるという話。
まぁ全ては半端な自分言語を持ち出して議論をかき乱した例の人が悪いんで…。 済んだ話を蒸し返すようなことになったのは申し訳なかったです。
非OOPLでOOPできるっていうやつは、 そうまでして結局OOPしたいんじゃねぇかw OOPを否定して非OOPを推奨する奴はおらんのか?
>>701 「OOPしたい」
「非OOPLでもOOPできる」
どこもおかしくない
>>702 だからといって、「非OOPLでOOPすべき」ということにはならない。
>>703 「すべき」とはいってない。
OOPは非OOPLでもできる
といってるだけ
仕事で使う言語を自分で選べるってのは少数派でしょ。どちらかというと
でもOOPするならOOPL使うべきだろ。 言語が先に決められているなら 言語にあったやり方をすべき。
では、CとC++を選んで仕事ができるとする。 どっちを選ぶ?
せっかくだから、俺はこのJavaを選ぶぜ!
自分専用のツールをちゃちゃっと用意したいと思ったら、 RubyかJavaになるわなぁ。テキスト処理ならRubyで、 GUIを伴ったり、メディア操作しようと思ったらJavaだな。
総論賛成、各論反対 これに尽きる
OOP不要論者って一人も居ないのか?
OOPが不要だと思う人はわざわざこのスレにはこないだろ
いつものはOOP不要論者だろ。
×不要 ○必要だが十分でない
不十分ということは、各個人でそれを補うための自由が必要。 「総論」は自由を制限しないから賛成できる。
不用意にいろいろなサービスや機能を言語に追加するのは、あまり賛成できないな。 確かに良くはあると思うが、入門者に壁を与える言語は行く末は…
>>715 入門者本人がいないところで本人が理解できない話をしている時点で既に壁は存在する
誰かの陰謀で壁が与えられたのではない
>>710 規模によるから。
小さければ本当は不要。
正確には、現在も小さくて、将来も小さいと確信できる時、かな。 まぁ、大きくなってきたら作り直すという手もあるけど。
一端OOPに慣れ浸しむと、小さいのでもOOPだがな。
>>716 からと言って無視して好きにしていいと言う話ではないだろ。
ファイルハンドルやウィンドウハンドルみたいに ハンドル(シリアルナンバー?)でデータを管理するのはオブジェクト指向? ある意味カプセル化だよねあれ。
あまり関係ないような。。
ハンドるって言うのは数値でしょ、数値よりは名前がいい
数値じゃないでしょ
まさか変数名だから数値じゃないとでも?
>>720 オブジェクトのインスタンスとしてハンドルを取り回してるならOO。
データへの参照としてハンドルを取り回してるなら非OO。
そこだけ切り出されても何とも言えんし、わりとその辺の境目は曖昧で、
結局コード書いた本人がオブジェクトとして意識していたかどうかの問題。
コードの見た目がどうだからOOPというわけじゃない。
ほほほ、やつぱり哲学的な話に 我オブジェクオと思う、故にこれはオブジェクト
Cも本によっては、ポインタじゃない、型の変数をオブジェクトと呼んでるね。
それは単にそう呼んでるというだけで、 C言語で副作用のあるものを「関数」と呼んでるのと同じ。
pascal始めた時、procedureとfunctionの使い分けにイラッとしたなぁ。
>>727 Cの規格でオブジェクトと書かれてる物があるんで、それで正しい。
Cの用語であって、オブジェクト指向でいうオブジェクトとはベツモノ。
>>726 違う方法で作っても似たような物が出来上がることがあって、
出来上がった物からどの方法で作ったのか断定するのは難しい、
という話だよ。
>>720 windowsのファイルハンドルのことはよく知らないけど、unixの
ファイルディスクリプタはカプセル化だけじゃなくて多態もして
いるので、正にオブジェクト指向だよね。
ファイル、パイプ、FIFO、ソケット、デバイス等、色んなものを
ディスクリプタを用いたインターフェース(read, write, close)で
操作できるようになってる。
むしろ抽象化の失敗例じゃないか かゆいところに手が届かない かゆいうま
WindowsのハンドルはCのライブラリではどうしても必要なものだから、あちこちで出てくる。 常にハンドルが見えているのでそれを意識してプログラムしなきゃならない。 OOPなら隠蔽してもっとシンプルなソースにできると思う。
OOPに反対する人はいないし OOPなら、という理由だけで賛成する人もいない
> OOPに反対する人はいないし 前スレ? 前々スレ? には居たようなw
OOPでガンが治ったとか言うなら反対するが、 漠然と道徳的な話をするだけなら何の問題もない
最近GoF本買ったんだけどただ読んでるだけだとまったく頭にはいらないな 実務でよく使うパターン教えてくれ。それから覚えるから
残念ながら、その手順で学ぶのは無理だw 今までそうやって挫折したやつ山ほど見てる。 ある奴などは、無理矢理萌えサンプルを用意し、 結局続かなくて頓挫した。 複雑な案件→設計試行錯誤→糞の山みたいな設計を量産 →何が不味かったか考え始める →デザパタ本を開いてみる の順じゃなきゃ無駄。諦めな。 けどまぁ、あえて言うなら デコレータ、ビルダ、オブザーバがいつも便利。
メソッドって目的によって分類できると思うんだけど そこらへん説明したサイトないですか?
デコレータ、ビルダ、オブザーバね ありがとう、そのへんからよんでみるわ
ファクトリ系も規模が大きくなってくると使う場面が出てくるので覚えておくとよし。
デザパタなんか覚えるだけ無駄じゃん?本質を忘れてる気がするよ
無理やりパターンに押し込めるような使い方をしなければ十分有用
>>740 >萌えサンプル
デザインパターンまで萌えに侵食されてるのか
>>745 >萌えサンプル
心意気は大いに評価したいんだけど、
いかんせん無理矢理すぎたw
やっぱ萌えもいいだろうけど、
最大のモチベーションは糞の山だよな。
自分が苦しみもがいた日々。
初期設計の悪さに足を引っ張られ、
誤魔化し誤魔化しやりくりする日々。
wikipediaで動的束縛を検索すると動的型付けに飛ばされんだけど 型付けと束縛って意味同じなの?
>>748 違う。
でもOOPには直接関係ないんじゃないかな。
>>749 >OOPには直接関係ないんじゃないかな。
そうなの?
OOPの関連用語とかでよく気がするんだけど
束縛とは名前とそれに対応する何かとの対応のこと
752 :
デフォルトの名無しさん :2010/12/07(火) 21:32:27
動的束縛という一般論の1つに動的型付けがあるってこと?
動的型付けというのは、式の型とか変数の型を、コンパイル時に静的に確定せず、 型チェックが必要な所では実行時に計算結果などの実際の値でチェックするような やりかたのことで、 動的束縛というのは、名前に対して呼び出される手続きないし関数の対応が、 静的に決定される型ではなくて、実行時の型で決定されるということで、 例えば Java みたいに、型付けは静的、束縛は動的、という言語もあるので、その リダイレクトはいまいち宜しくない。 # Java のオーバーロードの解決は静的だけど
>動的束縛というのは、名前に対して呼び出される手続きないし関数の対応が、 >静的に決定される型ではなくて、実行時の型で決定される ここでいう型ってのは何の型?変数じゃないんだよね?
オブジェクトの型
メソッドは型の構成要素である と仮定すれば、メソッドの束縛は型付けと関係がある。
動的に扱うメリットってあるの? 静的にできることは静的にやったほうがいいよね?
画像を見るのにjpgとgifとで全然違うプログラムを起動しなきゃならないのが便利だと思う?
つまんね
総称型とか依存型とかきりがないから ある程度で妥協してその先は動的にやるしかない
コンパイル時にチェックしないなんてあほか
JavaでObject型使ったりキャストしないで済むプログラムだけ書いてろ。
オートアンボクシング付く前のJavaで良くキャストしたなあ、懐かしいw
(静的型付けなら)変数の型はコンパイル時にチェックするよ。 動的なのは変数にアタッチされてるオブジェクトの方
インタフェース型の変数に実装型の値をアタッチする。 無名関数または共用体として使うが、そのどちらなのか明示しない。 暗黙にデザインパターンを意識させることでニュアンスを伝える。 そもそもインタフェースと実装の違いもあいまいだが、 動的言語のあいまいさに比べたら大したことはない。
>>766 動的束縛のメリット=無名関数+共用体
デザインパターンのメリット=構文で明示されない文脈を読めるようになる
クラスの中にクラスを書くことって意味があったりするの?
そのクラスの中でしか使わないことが明らかであるか、そのことを明示したいとき。
>>757 動的束縛は
変数の型じゃなくインスタンスの型をみて呼び出すメソッドを動的に選択する
ってやつでしょ
これがなきゃOOPの便利さ半減だよ
変数に型がない言語なら、変数をみてもメソッドの定義はない 変数に型があっても、abstractならメソッドは未定義 仮に動的束縛がないとすると半減どころではすまない
俺も動的束縛ってのがイマイチ分かってない 継承、カプセル化、多態性はなんとなく分かる(つもりかもしれんが) 動的束縛って殆どのOO言語には備わっているもんなの?
C++でvirtualのついたメソッドは動的、それ以外は静的
ある種・・・あれだな。 こう言う話になる。 オブジェクト指向で、型やオブジェクトをレシーバとして解釈するのは正しいのかどうか。 レシーバはレシーバで別で有ってもいいんじゃないかって。 receiver.method( object1, object2 ); ただしこの場合、オブジェクト指向というより、レシーバ指向とでも言うべきだが。 レシーバ=オブジェクトだからオブジェクト指向と言うのかもな。 レシーバ=クラスはクラスベース。 レシーバ=オブジェクトはプロトタイプベース。
この、レシーバの機能を何に持たせるのか、もしくは、単独で用意するのか、って話題は、 かなり入念に慎重に検討すべき話題だと思うよ。 その言語の性質そのものを決定付けてしまうからな。
>>774 C/C++にはどうせ関数ポインタやvoidポインタがあるから
>>775 よく分からん。もうちょい詳しく。
methodなるメッセージを受けたreceiverは、それでどうすんの?
receiverがブジェクトでないなら、構造化設計の思想と変わらなく見える。
レシーバへのメッセージングと単なる関数呼び出しとを
何かでもって明確に区別するの?
プログラムの構成要素とは全てレシーバであって、
そいつをオブジェクトと呼ぶ、という思想が
まさにメッセージングのOOだと思うんだけど、
コイツとは関係ない話?
>>775 その場合、多態はどういうことになるの?
何か素直に解釈すると、レシーバクラスのメソッドが呼ばれて
各オブジェクトのための処理が呼ばれなされなさそうな感じがするんだが。
「レシーバ=手続き」と「レシーバ=データ」の宗教論争を終わらせるために 「手続き≠レシーバ≠データ」ということにしたいんだろう
781 :
デフォルトの名無しさん :2010/12/09(木) 15:04:27
レシーバという概念自体がよくわからんのだけど これは何を指してんの?引数?
先生じゃない俺からすると 引数ではないとだけ言っておこう
ぶっちゃけレシーバが何者だろうとどうでもいい。
おまえらろくにプログラム書いてないだろ
わりとどうでも良いけど、OOPでレシーバと言えば 要求を受け取るオブジェクトのこと。 要求の送信は、大体はオブジェクトのメソッドの呼び出し。 (違うのもあるかも知れんが知らん)
メッセージパッシングってC++やJavaのOOPではあまり意識されないよね シングルスレッドが前提ってのもあるかもしれないけど。
TemplateMethodの意識が強い。 メッセージというより答案用紙の空欄を埋める感じ。
790 :
781 :2010/12/10(金) 19:58:18
C++の人も「C++はSmalltalkの影響は受けてない」っていってたし メッセージパッシングはOO初学者を混乱させてるだけという印象だな
そのC++も混乱の元(ry
C++が混乱しているのは、機能が有りすぎるからだけだ。 1つの事の記述に、言語的に複数の書き方が出来るのが問題。
C++が多くの初学者のやる気を砕いてきたのは認める それでも選択肢は多いほうが良いと思うけどな
StroustrupはC++の仕様をわざとわかりにくく設計したと言ってた。
馬鹿には使えないようにか
その文章ってマジもんなんかね。 だとしたら許せないよな。 だまされるほうが悪いっちゃ悪いんだが。 まったく外人さんの嫌がらせは本気すぎて背筋が凍りつく。 日本は平和だからなー。
↑ ネタ文章に本気になるおまえのようなバカが生きてられるんだから、 確かに平和だわなw
やっぱネタなの? でもネタに見えないところがまた怖いんだが。
ネタだよ
前に日本語訳をどっかで見たんだけど見つからないから英語で
>Did you really give an interview to IEEE?
>in which you confessed that C++ was deliberately created as an awful language for writing unmaintainable code to >increase programmers' salaries?
Bjarne Stroustrup's FAQ
http://www2.research.att.com/~bs/bs_faq.html#IEEE
ん?よくみたら
>>797 に同じリンク張ってあったわ
あの記事はたぶんネタだと思うが、それなりに真実を言い当てているところがあるから一慨に否定もできない。 Stroustrupは元々抽象的な概念を表現できる言語を作りたいと思っていたらしい。 だからC++を使いこなすにはまず抽象的に考えて枠組みを作り、実装はそれに沿って作り込むべきと考えている。 ところが、Cやアセンブラなど低レベルのところからやってきた人は、最初に抽象的に考えると、 そこからどうCPUの命令に落ちるのかイメージしにくい。素直にCPU命令を並べたほうが慣れてるし シンプルでわかりやすいと思ってしまう。CPUは全てが具体的で、抽象的なものはないからね。
でもそうするなら、もうちょっと標準ライブラリを練り込んで スクリプト言語と張り合えるぐらいの抽象度が欲しかったなあ 幅も深さもやや残念な感じ あれじゃどうやってもベターCとしてしか使われなかったと思うわ
Haskellあたりに比べりゃたいした抽象度じゃないんだが
歴史的役割は大きかったと思うけどねぇ<C++
C++はマルチパラダイム 抽象に特化するわけがない
>>805 スクリプト言語って?当時はAWKとか?
>>808 そうやって欲張った結果、非常に使いにくく、わかりにくい言語になってしまったんではないかと。
そお?単にC++人口がでかいから頂点が高く底辺も大きいてだけじゃ。 C++で挫折した人間がSchemeやHaskellを使えるとは思えない。
話は聞かせてもらったぞ! C++で挫折した人類は滅亡する!
コンピュータプログラミング言語がこんなに複雑である必要があるわけないだろ。 何かがおかしいのは間違いない。 きっと先入観が邪魔してるんだ。
> C++で挫折した人間がSchemeやHaskellを使えるとは思えない。 そお? あの結構な量の変態構文覚えるより簡単なんじゃ?
言語の文法は「身につける」ではなくて「覚える」ものと考えるプログラマは存在して欲しくない。
これは恥ずかしい… 大辞林 第二版 (三省堂) おぼえる 【覚える】 (2)技術を身につける。習得する。
体得と丸暗記の違いの話をしてるんじゃないの。
誰が丸暗記の話をしてるんだ?
>>813 言語が単純だと作成するプログラムが複雑になる件について
多分おちこぼれがなんか言ってるんだよ。
>>819 lispあたりはおもいっきり単純だけど、なにか?
C++0xで、関数っぽい仕組みが一体どれだけあることか。 しかもしれぞれ型が違う。その意味で抽象度が落ちてる。 機械語からアセンブリ、Cと、どんどん抽象度を高めていったはずなのに、 何でこうなったんだろうな。
需要と供給です ※だたし非英語圏は除く
型て。テンプレートは型どころじゃないと思うんだが。ほんとにC++やってんの?
>>823 確かに
・関数とメソッドは違う
・コンストラクタとメソッドは違う
こういう思考は抽象度を落としているな
827 :
デフォルトの名無しさん :2010/12/13(月) 16:51:18
>>823 その「関数っぽい仕組み」の内容は?
それがOOPにどう影響を与えるの?
あと型云々の所は何を指してるの?
質問ばっかりで悪いけどよろしく
アクセサって必要?
必要だ/必要でない と聞かれたら必要だ!
>>829 アクセス制御や内部データの隠蔽、抽象化をしたいなら必要
>>829 別に必要無い
ただし馬鹿が弄るかもしれないような現場では仕方なく使ってるだけだろ
>>832 こういうバカが、身の程を知らずにデスマを確定させる。
966 名前:デフォルトの名無しさん[sage] 投稿日:2010/12/14(火) 14:31:28
getterってカプセル化的によくないの?
967 名前:デフォルトの名無しさん[sage] 投稿日:2010/12/14(火) 14:33:37
使い方により
968 名前:デフォルトの名無しさん[sage] 投稿日:2010/12/14(火) 14:36:38
>>967 本来そのクラスが処理するのがカプセル化だよね
969 名前:デフォルトの名無しさん[sage] 投稿日:2010/12/14(火) 14:37:44
10年以上前にこんなやり取りあったよね
970 名前:デフォルトの名無しさん[sage] 投稿日:2010/12/14(火) 14:38:51
まだオブジェクト指向が浸透してないってことよ
971 名前:デフォルトの名無しさん[sage] 投稿日:2010/12/14(火) 14:45:25
プロパティなんて普通に使われてるだろ。
今時OOP原理主義なんてはやんねーよ。
フィールドを直接晒すべきではないので、その場合は必ずアクセサでラップするべき。 しかし、アクセサを使っても、オブジェクトの内部実装に依存したインタフェースを 外部に晒していることには変わりはない。 したがって、より抽象度の高いメソッドを用意するのがより望ましい。 その意味ではアクセサは推奨されない。
なんかを返すメソッドって使う側がそのなんかと依存する事になるのでどうしたらいいんだろう
cmで入力したいのにアクセサがインチしか対応してなかったら不便だもんね。 内部的には尺でも良いんだけど。
「そのなんか」に依存するのは、それ自体は別に悪いことではない。
二つのアホがある。 1.唯の構造体的なもので、内部で何の整合性も取る必要ないのに、いちいちsetter/getterつける奴。 2.そのクラスの内部実装依存のオブジェクトを返す奴。 どっちもアホだ。何も分かっちゃいねぇ。 と思ういつもの人でした。 でも結構見かけるでしょ。困るよね。 この手のスパゲッティーは本当に手におえないよ。
フィールドを使うのは、getは引数無し・setは引数1個と決め打ちするようなもの。 メソッドは引数を自由に決められる。 もちろん自由があっても活用する機会がなければ効果はない。 これは抽象化全般に言える。 効果が出る保証はないが費用は確実に前払いさせられる。
単体テストすることを前提にするならアクセサで異常値全部はじけるから 開発効率は上がるんじゃね
それほど言語の種類は知らんけど、結構文法によると思う。 Rubyの文法やC#のプロパティは好きだな。 public int Property {get;private set;} とか、まぁ無くても良いんだろうけど、よく使う。 この構文が追加されて大分楽になった。 とりあえずフィールドアクセスとアクセサの呼び出し構文が違う言語は あとでの変更がメンドイし、辛いわ。
あくまで自分で書くクラスの話だが… getterは割と使うけど、getterが扱うのはそのオブジェクト自身の属性ではないことが多いかな。 どっちかっつーと、所持(has a)してるオブジェクトの属性であることのが多い。 setterに至っては自分で書くことはほとんど無いなあ、最近。 本当に、値を代入するっていう感じがしっくり来る場合と 既に構造体的な扱いでコードを書いちゃって、それを弄る場合だけだな。 それにしたって、getterと同じく内部構造との乖離はするんだけど。
>>843 なんだかな…
自分語りになっちゃってるあたり、どこか抜けてるし内容的にもおかしいぞ
プログラマとしての自負だけは強そうだけど
なんか
>>815 と同じ匂いを感じる
隠蔽したフィールドのスコープ平気で広げまくる人間と一緒にやってるのでもう諦めた。好きにしてくれ。
>>843 has aも晒す必要がないなら晒さない方がいいと思うけど。
>>839 >1.唯の構造体的なもので、内部で何の整合性も取る必要ないのに、いちいちsetter/getterつける奴。
内部の構造が変更になったときのためにsetter/getterつけるんだよ
内部構造が変更になろうとインターフェイスが変わらない限り他に影響が及ばないというのがOOPのはずだが。
構造体という一つの単位ができあがる程度の情報量があるのに 何のラッピングも無く直に触ろうってのが問題なんじゃね。 内部とはいったってその構造体の値にアクセスする箇所が何箇所もあるわけでしょ。 アクセス方法の整合性をその箇所ごとに毎回人手でチェックしないといけなくなるよ。
Composite パターン使うんならsetが欲しいよね。 いろんなレベルから、自由自在にsetかます。
>>849 整合性は型でチェックすると息巻いてる連中に聞かせてやりたい
型がいかに頼りにされてないか、これでよく分かる
まあ、構造体にgetsetは要らんと思うが。 がしかし、構造体その物が滅多にないからな。 あっても、ほんの一握りの小さなデータのみ、例えばVECTORとか
>>848 統一形式アクセスの原則を守ってる言語は別だけど
フィールドを直接触さわるのとメソッド呼び出しで記法が変わる場合(C++とか)は
顧客側でコード書き換えが発生するから、それの防止
>>851 よこからすまんが
>>851 は
アクセス方法の整合性の話をしてるんであって型の話じゃないでしょ
>>853 内部の話をしてるんであって顧客側の話じゃないでしょ
>>852 そうかな。
構造体は結構使うぞ。
いつもの人は普通の思考回路だから、
管理関係の無いクラス同士のコミュニケートのさいに、メソッドにオブジェクトを渡したりはしない。
依存関係が強くなるだけだからな。
必ず基本型か、もしくはそれに準じるstringなどの基本的なクラスに分解してから渡す。
ただ、そうすると引数が多くなるから、それらの引数を構造体に纏めたりもする。
と言うことで、構造体は結構使うな。
機能を持った賢いクラスと、
それらのクラス同士でコミュニケートをする際の、データを受け渡しするためのみに使われる構造体と、
そういうわけ方。何でもクラスだけでやろうとはしないのさ。
だから、Win32なんて物凄い引数のAPIとかゴロゴロあるけど、 あれはあれで賢いと思う。 今のMSよりも昔のMSの方が優秀だったと思うね。 今はなんか受け狙いというか短絡的というか。 釣りしてるように見える。ほら便利でしょう!!って。
>>856 う〜〜ん、私の場合、その様な連絡用のデータもクラスにしてるな。
その場合はどちらでもいいと思うけど。
本体のオブジェクトをむやみに渡したりはしない。
同じだと思うけど?
C++の場合だけどな。 C++の構造体はフリーすぎるから。
ここまで来ると、単に好みの問題かもしれん。
>>855 アクセサやインターフェースの話をしてるんだから
顧客も当然含まれるよ
構造体使うんならクラス使うのもそんなに変わらんと思うけど
なんか論点がズレてるな。
>>839 の「構造体的なもの」はPoEAAでいう「バリューオブジェクト」のことで、その実装方法が
クラスか構造体かどうかは(アクセサに関しては)関係の無い話。
問題は「内部で整合性を取る必要がない場合であってもアクセサを作成するべきかどうか」だろ。
もっとも、最近の言語では何らかの仕組みが用意されていることが多いから、もう終わった話題
だとは思うが。
>>861 制約付けたい時とかのためにメソッドでラップしておく、とか?
まぁ、最近の言語は統一形式アクセスをサポートしてたりするし、
AOPコンテナを使うという手も無いわけではない、か。
>>862 ん?何か誤解してるかな、「何らかの仕組み」と言ったのは
>>842 のこと。
なぜAOPコンテナ?
まとめ Q.内部で整合性を取る必要がない場合であってもアクセサを作成するべきか A.統一形式アクセスがサポートされているか? されている→必要なし されていない→必要
>>864 >>Q.内部で整合性を取る必要がない場合であってもアクセサを作成するべきか
すまん、意味がわからん
整合性を取る??どういうことでしょうか?
A.統一形式アクセスがサポートされているか?
統一形式???
>>865 >整合性
簡単に言うと
2つのフィールドの値の合計が100じゃなければだめとか
相反するフラグが同時にTrueになっちゃだめとか
こんなの、適当な例で申し訳ない
>統一形式アクセス
あるモジュールによって提供されるサービスはすべて統一された表記によって
利用できなければならない。その表記はサービスが記憶領域によって実装され
るか計算によって実装されるかにかかわらず一定でなければならない。
--「オブジェクト指向入門」
>>865 >整合性
フィールドにint型の変数があったとして、
その変数はint型のとりうる範囲なら何でもいいなんて場合は極まれ。
正の数でなければならないとか、n〜mの範囲でなければならないとか条件を絞れるはず。
アクセサをかませば異常値ははじけるし、毎回ifで確認する手間がはぶける。
>統一形式
そのオブジェクトの利用者はアクセス対象が変数かメソッドかを意識しなくても良い様にする仕組み。
少なくともC++とJavaには無い。
まあ、なんだかんだ言ってもローカル変数にはプリミティブな型に直アクセスするんですけどね^^
それで何の問題もないけど? まさかローカルなプリミティブ変数にまで、アクセッサーをw まあ、変数総てがクラスという言語もあるからw
もういっそのこと動的型付けでも何の問題もないけどな
いや、動的型付けはいや!
アクセサをかませば異常値ははじける 動的な意味で
>>873 異常値をはじくのは呼び出し側の仕事のような気がする
DbC的な意味で
>>874 やっぱバグは残るんで、契約破りで例外ぐらい飛んでくれないと困る
フェイルセーフ的な意味で
まぁそれをアクセサがやるかアサート的な物がやるかは
どちらでも良いかな。
何が何をどう持つかというデータ構造が重要なのかね
>>867 上の例、アクセサでのチェックがなくても一応は型だけで弾けるよ。
あくまで一応は、だけどね。推奨はしない。
でも場合によっては一考の余地はある。
正の数でなければならないなら正の数クラスで受け取るようにする。
数値型もオーバーロードで受け付けるが、正の数クラスにラップして渡すだけ。
n〜mも、ほとんどの場合はn〜mに制限する理由があるはず。
それがトランプのカードに書かれた数値であるため1〜13であるなら
その数値はただの数値でなく、カードのランクだから1〜13なのだ。
だから「カードのランク」クラスにラップしてやる。
まあ、結局コンストラクタで値チェックすることになるんだけどさ。
>>875 リリースするときは例外捕まえてこけないようにするけど
開発中は派手にクラッシュしてくれたほうがいいな
デバッグ的な意味で
型推論 ダックタイピング 遅延束縛 動的束縛 解説みるとどれも似たようなこと書いてるんだが どう違うのか教えてくれ
型推論:静的に解決できるのがウリ ダックタイピング :型を介さないポリモ 遅延束縛 :? 動的束縛 :実行時に型などの情報を使ってメソッドをオーバーロード 反論は受け付ける。むしろ、誰か正しく突っ込んでくれ。
881 :
880 :2010/12/17(金) 20:31:20
し、しまった。またやってしまった。 ×オーバーロード ○オーバーライド
遅延束縛はVBやってたころに見た記憶があるけど 内容は覚えてないな
型推論って変数の型を推論するの?それともオブジェクト?
>>883 変数の型とオブジェクトの型は必ず一致するのが普通
OOPが特殊なだけ
>884 >変数の型とオブジェクトの型は必ず一致するのが普通 とか言っちゃうの恥ずかしくない?
なんでいきなり型クラスが出てくるんだw
いつものパターンに引っかかってるだけなのかな俺
オブジェクトもクラスになりえるとかいうレベルの話と
型クラスは大分レイヤが違う話
>>886 が思う型クラスを持つOOP言語の例を教えてくれ
>>887 型クラスは型変数の制約。
型変数は推論できてない型をあらわす。
推論できてなくても、変数と値の型は同じだという前提は崩さないと思う。
> 変数と値の型は同じだという前提 lisp 辺りだと 変数に束縛される object は型を持つけど、変数は型を持たないんだが… # 論点がちゃってたらごめん
> 変数は型を持たない 持たないものは比較できないから、同じかどうかは論点にならない
どうやら支離滅裂らしいです
>>891 問題はそこじゃなくて、型推論の話で型の弱い言語の話が混ざってるところだろ
いわゆる型推論って言った時はHMとその派生をさしてると思うけど
これはかなり強い型システムが前提
なのでlispが例に出てくるのは変だし
その辺で混乱してそうな人に型クラスを持ち出すのも変
(型クラスを持つOOP言語って何よ)
そんで、型推論のあるシステムでは
>>884 は普通で
変数と値の型が違えばコンパイルエラー
(変数の型が命題、値が証明というカリーハワード対応関係というものが成り立つ)
>>883 とか890はおそらく、動的なOOP言語を思い浮かべて混乱してると予想する
変数にクラスオブジェクトを入れてその変数経由でオブジェクトを生成して、みたいな
>>893 俺の予想ではこうなった。
変数に型がなければ混乱しない。
変数に型があっても、オブジェクトの型と同じなら混乱しない。
変数に型があって、変数の型とオブジェクトの型とが異なると混乱する。
883は混乱している。
ゆえに、883は変数に型がある言語を思い浮かべている。
895 :
883 :2010/12/18(土) 18:55:21
>>893-894 ぱっと思いついた疑問だったので細かいとこまで考えてなかったw
型推論は
静的型付け言語の概念で変数の型を推論してる
であってる?
変数の型が束縛する値に合わせて静的に決定されるのが型推論 束縛する値が変数の型に合わせてキャストされるのは弱い型付け
オブジェクト指向とFSMの関係について
899 :
デフォルトの名無しさん :2010/12/29(水) 21:51:30
スパゲッティモンスターがオブジェクト指向と関連があるとはしらなかった
オブジェクト=ヌードル触手
C++のテンプレートはOOP 的にはどうなの?邪道?
902 :
デフォルトの名無しさん :2010/12/30(木) 16:34:04
総称性は欲しいので有り
>>901 もちろん不要。テンプレートで頑張りすぎちゃって、
virtual付けたときに不安になっちゃう子を沢山見た。
目先の速度に縛られてるうちはOOPのメリット享受までは遠い。
今時ジェネリックプログラミングができないとかありえないわー
〜ないとありえないって言ってるやつのほとんどが そいつの技量がありえない
テンプレートで静的に解決! あんなこともこんなことも! boostのアレ使ってコレ使って。 凄くシンプルなはずのことを、 糞みたいに複雑に記述してるソースを見たことある。 お前等に見せてやりたかったよ。
>>906 論点がずれてるよ。
>>901 は「OOP的にどうなの?」って聞いてんだから
C++でOOPするならテンプレートはいる
総称性が使えないと不便
>>905 C言語でOOP、とか職人芸を「技量」と勘違いしてる老害乙
>>908 そういえば昔は年賀状の季節になると
テレビで郵便局のおっさんが出て来て
無造作にポンポン放り投げて仕分ける
名人芸を見せるのが流行ってたな
C++やPerlでオブジェクト指向なんて
その当時のアナクロさを思い出させるな
「どんなことでも熟練すればうまくできる」と言いたいのでは?
無造作とかアナクロとか否定的なイメージを感じる
わりと素朴な疑問なんだけど、一般的に、OOP的には 以下のような例はどのような方針でモデル化しますか? 1. 入力 I0 ... In が(タイプは違う)あって、 2. これを処理する一次遅れ系の関数 Fn(In) -> Xn (処理内容は異なる)が必要 3. Xn をまとめて受け取ってさらに自分自身の出力からのフィードバック f を処理する機能 G(X0, ..., Xn, f) からなるシステム
じゃあまずOOPでなくて良いから 知ってる言語で書いてみて
>>914 Gというクラスを作り、インスタンスを作るときにパラメータX0, ..., Xnを与えて起動。
フィードバックfはクラス内で処理するように作る(動作中は内部で処理されるので表から見えない)。
最終結果が出たら終了。
電気回路か何か? 外部から必要な情報と出力だけを管理すればいいと思う A a = new A(I0,I1,I2,...); print(a.feedback()); //内部でxnを生成しfを計算 1クロックごとに処理をしたいとかいう要求があるとエスパーすれば Pulseをメソッドとして持たせて、その戻り値を結果の型を表すクラスの階層にする 3がフリップフロップぽくて嫌な感じだけど詳細は聞いてないし
> 電気回路か何か? そだよ. In は ADC の出力で, Fn 自体も In のソース種別によって パラメータだけじゃなく方式まで変化する. Fn をなんとかしたいわけなんだけど、うまい方法を思いつかない (何がつながるかは, システム設定時に決定可能) 関数を返すことが可能な言語だと Fn を合成する関数をつくれば いいんだけど、指定言語が java なのでどうしたもんかと…
>>919 今までだと、動的にその関数を作ってるんです
動的に、って、ソースコードを動的に生成してコンパイルして、動的リンクで呼んでるの?
普通、実行時に動的にコードを生成するんなら、機械語を直に吐くだろ。 なんでソースコードからいちいち生成しなきゃならんのだよ。
BCEL使えば?
>>921 ,922
言葉足らずで、すまん
最初の実装が、 cで関数を作る各パーツをさらにい関数として
{関数, 引数リスト}のリストを返すようになっていた
前任者が、lispで書き直した
作年末、あるクライアントから「Javaで作り替えられないか?」ってな
相談がきた。
ってのが現状
引数リストを一つのクラスに閉じ込めるかList<BaseArguments>みたいなのにして 同じインタフェースにしたら{関数,引数リスト}のリストをJavaでも動的に扱えると思う 関数のインタフェースは Result f(ArgumentList<BaseArguments>)みたいにして統一すればいい java版parsecだってあるしね ところでJavaVMを使うLisp実装とかなかったっけ、Closure? それで実装してクラスファイルだけ呼び出すとかそういう解決もあるんじゃないの lispからの移植ならなおさら
>>925 > ところでJavaVMを使うLisp実装とかなかったっけ、Closure?
あぁ、その手があるか。 ちょっとabcl調べてみる。
closureは癖がありすぎて短期にポートできそうもない
>>926 話はそう簡単じゃなくて、lispで書き直されたときに自由度が滅茶苦茶上がってる
つか、lispって処理系にコンパイラとほとんど反則なマクロ抱え込んでるから
何でもありの世界なのよ
こういったことを通常のOOPLで考える場合の参考になった。
ありがとう、みんな。
日本語事態怪しくて、かなり頭がくらくらしてくるのは俺だけではないはず。
唯俺が思うに、ソースコードを見ると、誰もが「普通にやれやボケッ」って言いたくなる状態なんじゃないかと。 入力データにタイプ値持たせてスイッチするだけの方がマシなんじゃないのか。 保守の意味でも。
まぁ質問者は納得したみたいだからあれだけど
>>928 の日本語と漢字の能力でこれを言われたくはないなw
何の話をしてるかもわかってなかったのは俺だけではないはず。
Javaで、動的に関数を生成して実行させる方法を知りたかったらしい
Javaにあるみたいな、アトミックに操作できるオブジェクトって作れる?
934 :
デフォルトの名無しさん :2011/01/05(水) 03:15:20
アトミックな操作を実現する機能があれば作れる
なければ作ればいいじゃまいか
オブジェクトのコピー作ってそっちで一回処理してみて 成功したらオリジナルに反映してコピー破棄。 失敗したらオリジナルそのままでコピー破棄。 こんなかんじけ? オブジェクトの中で参照持ってたりするとディープコピーするのめんどくさそう
もしかして:トランザクション
>>937 上でいってる「アトミックな操作」のアトミックって
ACIDのAとは別物なの?
いろいろ考えてみたんだけどSimulaのコンセプトやCでの問題点を考えると オブジェクト指向にたどり着かざるを得ないよね。 問題はいまのOOPの理解がいまいちピンボケしてるんじゃないかってことだと思う。
WebProgの方にも書いたけど、qconにEric Evance来るよ。
関数型言語:数学 オブジェクト指向:物理学(科学)
ばかじゃね? オブジェクト指向のどこに物理学的な要素があるんだよ
あほはおまえ
で?
なんかさ、みんなが試行錯誤してて方向性がバラバラな気がする。 結局、今は手間がかかってもOOP以外の言語で組んどいたほうが迷わなくていい分、楽なんじゃないかと思うね。
それ、OOP以外の部分を別の何かに変えても同じこと言えるだろ
読みづらい
お、何、その人すごいね。 やたら「日本では」「日本だけでは」を強調するのが鼻にかかるけど。 外国の一般的企業の実践例、風潮を知った上で言っているのなら、 それなりの信憑性あるソースなり、体験談を語って欲しいところ。 EAAを真面目に考えようとしている人は凄い共感もてるわ。
>>950 その記事読んだ、大笑いした後に、マジか!! と考えてしまった。
COBOLは強い影響力があるんだな〜
片手間にやってる試験なのに、真面目にになる方がアホだよ。 大人だったら流せよな。愚民代表がそんなに楽しいのかね。よーわからん。
>>954 問題提起なんだから。大人だったら分かるよな。
2chで「試験問題が糞過ぎる件wwww」ってスレ立てるのとは違うんだよ。
>>952 「SI業界」という言い方だと全世界的にそうなのか、という話になるから、
筆者が実体験としても分かる範囲である「日本の」と限定してるだけだろ。
余計なこと書いて悪かった。 単純に日本は、日本ではって言葉が多すぎるのが鼻についただけだ。
実際ググって出てくる英語の掲示板とか見ても レベルは日本と似たり寄ったりでがっかりすることが多い あきらめたら終わり 満足してしまっても終わり
>>948 組むだけなら、それが正解。
しかし保守を考えたらOCPが適応しやすいOOになる。
あとは規模でも違ってくる。
小規模や社内向けアプリなら、大半のアプリはOO以外でも大丈夫。
まっ、最近はここの住人みたいに技術が無い人間が多いから
OO以外が無難。
「保守」というと、ソフトを書くという本題と関係ない、みたいに思う奴が多そうだが、 つまり、要求の変化に対応するための改良ということであって、開発とは不可分。 書き捨てでいいならそれでもいいんだが、そんなのちょっとしたスクリプトくらいのもんだな。
>>960 OO の場合
要求の変化 -> 処理の変化 -> ラッパライブラリの差し換え
なら対応できるけど,
要求の変化 -> 処理の変化 -> 末端ライブラリの根本的見直し -> 全滅
じゃ、ねえの?
>>960 ここいうスレを大規模開発のスキルのある人が牛耳る。
しかも、ソフト開発というのはこういうものだという決めつけ
を付けて。だけどまてよ、OOを採用するにしても、
個人レベルもあれば、小企業の社内向けのものもある。
こういうものは、共同開発自体が必要無いものが多い。
保守というが、一度納入されたアプリの変更はありえない、
というものが大半。これではOOの利点の多くが要件に
ないということになる。こういうケースでもOOPは使われて
いるのであって、ある程度はそのことも念頭に入れた議論
が必要ではないか。
>>962 おまえはもう少し要点をまとめる書き方を勉強しろ。
それで全滅しない言語教えてくれ
965 :
959 :2011/01/29(土) 19:02:25
>>960 その通りだな。
>ソフトを書くという本題と関係ない、みたいに思う奴が多そうだが、
俺が思うには多分理解出来ないだろう、本を読んでもこればかりは
経験を積まないと技術者として物にならない。
みんな書籍からの知識をひけらかしたいだけだろうな。
>>961 >要求の変化 -> 処理の変化 -> 末端ライブラリの根本的見直し -> 全滅
>じゃ、ねえの?
960じゃないが、それは保守じゃなくリプレースな。
>>962 >ある程度はそのことも念頭に入れた議論
>が必要ではないか。
そうだな、だがみんな経験が無いから議論出来ないんだよ。
しかし、OOを理解してない奴は保守以外にOOを何に使っているんだ?
あとは共通部品やライブラリーぐらいか?
それだと開発の一部だけOOを適用すれば済む話だしな。
まっ本人がOOと思っているだけでOOじゃ無いかもしれんがw
そもそも多態がない言語なんて、開発自体が辛いと思うようになった
>>965 そうですね。
本人がOOと思ってるだけでOOではないのかもしれません
968 :
959 :2011/01/29(土) 22:06:05
>>967 >本人がOOと思ってるだけでOOではないのかもしれません
まっ簡単に見分けることは出来るがな。
実行時のオブジェクト数が1000以下なら、まずOOじゃない。
OOが出来ない奴はオブジェクトを関数みたいな作りにするからな。
>>962 > 個人レベルもあれば、小企業の社内向けのものもある。
> こういうものは、共同開発自体が必要無いものが多い。
開発という行為は、三日前の自分と現在の自分との共同開発だと考えることもできる。
個人レベルでも、少人数開発でも、OOのメリットはあると思うよ。
> 一度納入されたアプリの変更はありえない
「アジャイル」という開発手法があってだな。
なんだかんだいって、みんな最後はC言語に戻ってくるのさ。
Cだとやっぱり機能が足りない。 C++は無駄な拡張しすぎ。 難しいね。
C++はPerl6みたいなもんだわ 付け焼刃のOOPもどきじゃ駄目だよ
どこと付け焼刃といってるのか C++はCにSimulaの機能を追加しようとした正統な言語だよ。 その後のマルチパラダイム路線がきついが。
そこでObjecti...おや、誰か来たようだ
>>968 わかる、オブジェクト指向が出来ない人間は
1つのクラスに一つのインスタンスしか作らないからな。
会社に大勢いるよ。
答えがないからみんな俺のがオブジェクト指向、あいつは馬鹿って感じ。
OOが上手く実装さらているかは別にしても
オブジェクトが少ないんだから
プログラムが”オブジェクト”を”指向”して作られていないのは確かだな。
>>977 お前のつくっているプログラムはOOPで作っている構造化プログラムだからw
C++「Javaがやられたようだな…」 Smalltalk「ククク…奴はOOPL四天王の中でも最弱…」 ObjectCOBOL「構造化ごときに負けるとはOOPLの面汚しよ…」
構造化もOOPの一部分なのになに言ってるんだ・・・
982 :
デフォルトの名無しさん :2011/01/30(日) 13:10:11
∩_ 〈〈〈 ヽ ____ 〈⊃ } /⌒ ⌒\ | | /( ●) (●)\ ! ! / :::::⌒(__人__)⌒:::::\| l | |r┬-| | / <こいつ最高にアホだお \ ` ー'´ // / __ / (___) /
OO, OO って, 言ってるやつらに鍵って, 「 不必要な状態変数を持ち込みたがる」 のはなぜですか?
ちょっとどのレベルの話しているか分からん。 字義通り取れば、不必要なものを持ち込むのは単なる設計・モデリングミスだろう。 イミュータブルで副作用のないコーディングを目指すべきだというのならば、 理想としては同意する。ただし、業務アプリにおいてそれを実現する方法を俺は知らない。 だから、ステートパターンなんかでワークアラウンドな対応を取る。
>>984 おまえさんみたいのは全然安心
でも, 現場は, 不必要な状態変数を持ち込みたがるやつが多すぎ
で, 結局, class/object に閉じ込められたグローバル変数のてんこ盛り
なんのためのOO ?
質問。 図書館やレンタル店どっちでも良いが 未返却一覧を画面に表示する場合のオブジェクトの種類はどれだけ作成するか。 1.画面オブジェクトのみ。 2.画面オブジェクト+顧客情報オブジェクトX未返却者数分。 3.画面オブジェクト+顧客情報オブジェクトX未返却者数分+商品X未返却商品数分。
>>986 そんなもんbackendが何かにっよって変わるだろ?
>未返却一覧を画面に表示する これはOO的ではなく、手順的(構造化的)
>>986 それ自体がドメインとなる要素なんであれば、
未返却一覧Repositoryを作る方法もあるって、ファウラー先生がRTしてた。
List<未返却> 未返却 = 未返却一覧Repository.getAll();でおしまい。
種類なのか、前のオブジェクト数1000云々に対抗してるのか不明だけど、
これを実装するとしたら
画面、画面コントローラー、Repository(Service Class)、dao、Domain Object(Entity)が一般的じゃね。
>List<未返却> 未返却 = 未返却一覧Repository.getAll();でおしまい。 ごめん、間違い。 List<貸出商品> 未返却 = 未返却一覧Repository.getAll();でおしまい。
>>987 >そんなもんbackendが何かにっよって変わるだろ?
簡単に書きすぎたか?RDBよりデータ取得して画面に出力ようなイメージだったが。
>>988 >これはOO的ではなく、手順的(構造化的)
手続き型と言いたいのか?それなら
1.RDBよりデータを取得して
2.画面一覧にデータ設定して
3.・・・
見たいのが手続きと言うだが、
>未返却一覧を画面に表示する
は4GL的に宣言として書いていると思うが。
>>989 >未返却一覧Repositoryを作る方法もあるって、ファウラー先生がRTしてた。
なるほど、マーチンはそんなことを言っているのか。
>種類なのか、前のオブジェクト数1000云々に対抗してるのか不明だけど、
オブジェクト数の話で、話を振ってみた。
>画面、画面コントローラー、Repository(Service Class)、dao、Domain Object(Entity)が一般的じゃね。
なるほど、しかしそれはクラスの数では?
OOPで作と2か3になると思うが、OOPが出来ない奴は1で作る方が多い。
普通にRDBからデータを取得してO/Rマッピングしないでそのまま表示する。
実際職場でも、こんな感じで作ってある場合が多い、OOPじゃないが別に
そこまで凝る必要もないような気もするし。
話は変わるけどマーチンのアナリシスパターンは何回読んでも理解出来ない...
RDBとOOPの相性の悪さは半端ないぜ
OOPでなんでstatic変数があるのか理解できない
Singletonのためw static変数が無いと結構不便かも。
無いと不便だと思うけど、 無いなら無いで、なんとかなるのかも。
Scalaとか、static無くなして代わりにSingleton用の記法にしちゃったしな。
上位からオブジェクト渡せばstaticいらないのに
正しくは「渡しまくれば」だな。
>>992 Java とか C++ って、
class ParsistentClass extends ParsistentMetaClass {
// define class members
}
とか、かいておいて、あとはライブラリがよきに計らってくれるような仕組みってないの?
おしまい
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。