- オブジェクト指向システムの設計 172 [無断転載禁止]©2ch.net
74 :デフォルトの名無しさん[sage]:2016/07/13(水) 00:49:32.32 ID:uq0wU9fp - >>65
おー書いたか、ご苦労さん。 俺が想定したものとは異なるが、それ以上に情報を含んでいたので、 レビューの様子もよく伝わったぜ。 まあ感想は他の連中と同じだな。 君は難しいコードを書いている。だから駄目なんだよ。 張り切って色々やろうとしているけど、それが駄目なんだ。 手を抜くことには努力を惜しまないってのが優れたプログラマだろ。 少なくともそのレビューと上司はまともだから、言うことを聞いた方がいい。 その上司のコードが何故いいか?それは簡単だから。 構造が単純だから、ぱっと見たらちゃんと動くことが分かる。 それに対して、君のコードはちゃんと動くかはよくよく見ないと分からない。 上司のコードは「自分で処理出来る例外はcatch、それ以外は放置」というポリシーだから、 基本的に下から上がってきた例外は「予想外」として落としている。 つまり例外ツリーは単純なツリー構造で、 このポリシーさえ守れば今後とも簡単に処理を追加出来る。 そして処理も基本的に上から下に処理されるだけだ。単純明快でいい。 対して君のコードは、そうじゃない。 よくよく読まないと果たしてちゃんと動くかどうかも分からない。 そして追加するにしても君が作ったクラスを全部知ってからでないと追加出来ない。 つまり、やることが増えすぎているし、密結合になっている。 対して減らせたのはせいぜいDirectry/Fileの例外の被り部分だけだろ。 それは明らかに設計コストを増してしまっている。
|
- オブジェクト指向システムの設計 172 [無断転載禁止]©2ch.net
75 :デフォルトの名無しさん[sage]:2016/07/13(水) 00:50:08.11 ID:uq0wU9fp - 多分勘違いしているのだと思うし、実際そういう奴も多い気もするが、
ベタに書くのが悪いとか、同じようなコードが2箇所に出現するのが悪いとか、 そういう単純な問題ではないんだ。 分かりやすく言えば、 「そのコードを初めて渡されて、ああこのコードはちゃんと動くだろうねと分かるまでに、何秒かかるか」 について最適化しろということなんだよ。 当たり前だが全く同じ内容がダブってたら読むのに2倍かかるから、 それはループなり多態なりして一つに減らせってことになる。 だけど無理に多態したりして「コードを追う手間」が増えるようでは駄目なんだ。 その上司のコードはさらっと読んだだけで動くのが分かる。 でも君のコードはあちこち追い回さないと動くかどうかも分からない。 もちろん君が書いたコードだから、君のコードを君が読むのには苦労しないだろう。 だからもし君に同様の同僚がいて、同様に駄目出しをくらっているのなら、 その時の両方のコードを君が初見で読みこんで、 その構造と動くかどうかを把握するまで何秒かかるかを比較してみればいい。
|
- オブジェクト指向システムの設計 172 [無断転載禁止]©2ch.net
80 :デフォルトの名無しさん[sage]:2016/07/13(水) 02:08:26.36 ID:uq0wU9fp - >>70,72
情報ありがとう。 > 契約プログラミング 考え方はよしとして、大して採用されてないのは効果がいまいちだったのかな? > noexcept お?これはなかなか良い感じ。 ついでにそこから辿れる以下も読んだが、こちらも例外を有効活用しようとしている。 (より正確に言えば、例外を有効活用する時のライブラリの作りについてだが) http://boostjp.github.io/archive/boost_docs/document/generic_exception_safety.html 例外の文法を使えば、確かに表現力は上がる。それは事実だが、ここに書いてあるように、 当然STLや自前クラスがどの例外保証を持っているかすべて把握してないと駄目だし、 完全活用するとなるとなかなか難しい気がするね。 (プログラミング時に把握しなければいけない項目が増える) > HaskellのEitherモナド Haskellの知識はないのでとりあえず日本語部分だけ読んでみたが、 この読み方では有効かどうかは判定不可能だorz > C++やC#でそれっぽいコード このURLをくれればすごく助かります。
|
- オブジェクト指向システムの設計 172 [無断転載禁止]©2ch.net
92 :デフォルトの名無しさん[sage]:2016/07/13(水) 22:44:01.74 ID:uq0wU9fp - >>84
例外をエラー通知として使う分にはその辺は知らなくていいんだよ。 ただ、例外で復旧させようとするのなら、その辺を全て把握する必要がある。 そして彼等はそれにも耐えられるようにSTLを整備しようとしている。 それは無駄なコストを発生するから、それについて彼等も議論しているわけだ。 ただ、今見た限りはまだ環境が追いついていないね。(ドキュメントが出来ていない) 偶々このページを見ていただけだから、unordered_map自体に意味はないけど、 http://en.cppreference.com/w/cpp/container/unordered_map 個々のメソッドには例外発生時の動作が書いてあるけど、本体のページに纏まっていない。 だからunordered_mapを使ったらどの例外安全になるのかを確認する為には、 全部のメソッドを確認するしかない。 大半の奴は確認もせずに「例外を使った方が安全です」と信じているだけだろう。 例外を活用しようとなると、既に書いたように、大ジャンプを避けられない。 その場でいちいち判定するだけなら、余計に汚らしくなるだけだ。 ただしこれについては速度面ではtry/catchの方が上だと指摘されているし、 表面上のコード量では確かにそうだ。 とはいえ、x86に於いては分岐予測+投機実行なので、 ほぼ常に通らないパスのif-elseifについては、 気になるのなら1段目で切ってしまえば速度低下はしない。(if (result>0))
|
- オブジェクト指向システムの設計 172 [無断転載禁止]©2ch.net
93 :デフォルトの名無しさん[sage]:2016/07/13(水) 22:44:36.15 ID:uq0wU9fp - > 必要があれば戻り値のエラー通知を部分的に使うのはかまわないと思うよ
個人的にはTryParseをよく使っている。それで十分だから。 必要性はない。try/catchでも書ける。 戻り値判定の場合は、その場での処理が強要される。 結果、65の上司型のコードしか書けない。 実際にあのコードを戻り値判定に変換するのも簡単だ。 この使い方をする場合は好みの問題でしかない。 一方、例外を用いれば、65がやろうとした「積極的にthrowして統合的に扱う」ことも出来る。 戻り値判定でこれをするのは大変なことになるので、これをしてこそ活用だと言える。 とはいえ、これがろくな事になる気配が全く感じられない。 ちなみに、言語的な例外復旧能力に必ずしも頼る必要はない。 上位レベルでの復旧も実は簡単だからだ。 例えばTryParse、ファイルから読むのならソースは保持する必要がない。 Seek出来ないネットワークストリーム等なら、MemoryStreamに一旦受ければいい。 JSONみたいに階層ありオブジェクトを丸々生成するのなら、成功した後に差し替えればいい。 これらの場合は、ロールバックを上位で行うことはほぼ自然に出来てしまうので、 結果的にSTLが実装した例外機構の為に無駄に税金を払う事にしかならない。 この点を修正しようというnoexceptはC++っぽくていいが、 なるほどこんな事をやっているうちは生Cを駆逐することは出来ないだろう。
|
- オブジェクト指向システムの設計 172 [無断転載禁止]©2ch.net
94 :デフォルトの名無しさん[sage]:2016/07/13(水) 22:45:05.83 ID:uq0wU9fp - 生Cはある意味世界がno-fail保証されている。
そして失敗した場合は上記のように自前で戻すか、諦めるしかない。単純な話だ。 ロールバックする気なら、この点については例外で処理した方がコード的には楽だ。 しかし実行効率ではどうやっても生Cの方が上になる。何もしてないコードだからだ。 生Cは世界が単純に出来ている。あまり気にしたことはないが、これは大きな利点だね。 言語がシンプルな結果、シンプルな記述を強要され、結果的に65のようなコードを記述出来ない。 65みたいな「考えすぎておかしくなっている奴」には生Cギプスが効くかもしれない。 > .NetだとSystem.Diagnostics.Contracts 以下を見る限り、型についてのTDDみたいな感じだな。 静的チェックが出来るのはいいね。ただ、流行るかと言われれば微妙かな。 https://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970 > C++ Either 以下でいいか? http://faithandbrave.hateblo.jp/entry/2014/05/30/153325 つまりは例外を呼ばずに値として埋め込みたいだけか。 関数型で組んだ場合には個々の要素で例外呼ばれても困るから、そりゃこうなるだろう。 そういった意味ではC++の例外機構は「手続き型」にしか対応してないね。 そこですぐ呼ばれる前提だ。 他の関数型言語の例外機構ってどうなっているんだ?知ってたらよろしく。 Haskellがこの手で値埋め込み、後でユーザ側で確認するというのは分かった。 なおJavaScriptは0割は無限大になるというお気楽仕様だ。 当初は驚いたが、正直これで問題ないよなとも思う。
|