オブジェクト指向システムの設計 172 [無断転載禁止]©2ch.net

■ このスレッドは過去ログ倉庫に格納されています
1uy ◆e6.oHu1j.o
垢版 |
2016/07/09(土) 00:35:13.95ID:Mn3UGZ+O
前スレ
オブジェクト指向システムの設計 171 [無断転載禁止]©2ch.net
http://echo.2ch.net/test/read.cgi/tech/1465636703/
2016/07/12(火) 00:42:17.97ID:M/oXbOZH
>>27
いやいや
だって例外を1番上で捕まえると
死ぬ箇所によって死に方が千差万別よ

それって折角閉じたクラスや関数であっても大ジャンプしてケツも拭かずに飛び出して来るからね

だから例外を一括で処理するとデリケートな処理してっとこだとまじーんじゃねーかな?ってのは思うわ
2016/07/12(火) 00:45:40.75ID:StomlD/Y
Cって例外ないじゃん
C++は既にJavaに似た例外あるじゃん

C言語スタイルってなんじゃん?
2016/07/12(火) 00:48:43.19ID:M/oXbOZH
>>31
だから例外ないからその場で処理するしかないだろ
2016/07/12(火) 00:49:55.80ID:StomlD/Y
>>32
アナルほど凍死罵
2016/07/12(火) 01:02:14.20ID:4M8hLvVe
>>30
> だって例外を1番上で捕まえると
> 死ぬ箇所によって死に方が千差万別よ

頭が硬すぎ。困るときだけ対処しろよ。

困らないときがほとんどなんだから
困るときだけ対処すればよい。
2016/07/12(火) 01:03:49.06ID:4M8hLvVe
C言語よりもあとにできた言語では
ほぼ全て例外機構があって、例外を使うのが推奨されている。
(例外を使うなって意見聞いたことあるか?)

という現実を見れば議論するべき内容じゃない。
例外が良い。の一択
2016/07/12(火) 01:09:39.99ID:umCvEWis
>>35
釣りか?
むしろ使うなという方が大勢だと思うが。
http://www.textdrop.net/google-styleguide-ja/cppguide.xml#%E4%BE%8B%E5%A4%96
2016/07/12(火) 01:11:50.86ID:Vf+ZIi05
C言語の例外処理はシグナルを使う方法だろ
2016/07/12(火) 01:17:32.84ID:rBak2gB5
>>36
Googleは例外が使われていない大量のレガシーコードを抱えている
そのレガシーコードと例外を扱う今風のコードを混ぜることにコストがかかるから例外を使わないというルールになっている
新規にコードを書くなら例外でエラーするのが一般的

>>Googleの既存コードに例外に対する耐性がないことを考慮すると、Googleのプロジェクトで例外を使うのは、新規プロジェクトで例外を使うのと比べて、ややコストが大きいと言えます。
>>例外の変換プロセスには時間がかかり、問題になりやすいものです。また私たちはエラーコードやアサーションといった例外の代替手段が大きな障害になるとは考えていません。
2016/07/12(火) 01:36:55.20ID:4M8hLvVe
>>36
Googleは特殊な事例があるからってだけだなw

もうネタ切れ? つまり例外を使うべきだよね。
(もう何度もやって答え出てること繰り返すのは面倒だ)
2016/07/12(火) 01:37:15.67ID:M/oXbOZH
>>34
会社でどっちに倒すか?
ってなったら俺ならその場で対処だな

ロールバックの付いてないDBみたいな処理のが世の中多いと思う

例えば0割とかモノによってはその場で対処必須なものもやっぱあるわけで

どっちかに方針を統一しろって話になったら例外大ジャンプは取り返しがつかない事態を内包すると思う

まあ、概ね大丈夫ってのはわかるけどね
2016/07/12(火) 01:38:38.08ID:M/oXbOZH
文中の例えばは間違い
2016/07/12(火) 01:38:41.27ID:4M8hLvVe
>>40
> 例外大ジャンプは取り返しが
だからさ、例外小ジャンプすればいいだけだろ

なんで使い分けられない?
2016/07/12(火) 01:45:58.42ID:4M8hLvVe
プログラミングやってて時たまいるんだが、
視野が狭いっていうか、何かをやれって言ったら、
それだけしかやらないやつな。

自分で適切なコードが何かがわからない。
マニュアル通りにしかコードをかけない。

そんなやつがいるんだよね。

例えば例外はちゃんとキャッチしろって言ったら、
はいはいわかりましたよって、すべての関数にtry-catchを入れる。
んで、え?あんたがキャッチしろっていったんでしょ?
だから全部入れてやったんですが?って言うようなやつ。
2016/07/12(火) 01:48:36.07ID:umCvEWis
>>38
そこは俺も読んでるよ。
しかし俺は逆に「例外を使え」ってのを聞いたことないんだが、
日曜コードではなくて、マジの商用コードでそういう方針の所ってあるか?
2016/07/12(火) 01:55:35.82ID:4M8hLvVe
> しかし俺は逆に「例外を使え」ってのを聞いたことないんだが、

なんのために言語に例外なんて機能を追加していると思ってるんだ?

言語マニュアルを読めば例外はどういうときに使うもので、
どういう使い方をするか説明してあるだろ。
それにその言語のライブラリは例外使われてるだろ。

ごく普通に使われってるとおりに使えばいいだけ。
2016/07/12(火) 01:58:01.82ID:4M8hLvVe
まああれだ。C言語のしがらみがないライブラリで
例外を使っていないライブラリありますか?
という質問に答えてみればいい。

例外を使うのが自然すぎてわざわざ使えという話じゃないことがわかるはず。
2016/07/12(火) 01:59:34.67ID:rBak2gB5
>>43
エラーと例外の処理 (Modern C++)
https://msdn.microsoft.com/ja-jp/library/hh279678.aspx

>>最新の C++ のほとんどのシナリオでは、論理エラーとランタイム エラーの両方を報告および処理する方法として、例外を使用することが推奨されます。
2016/07/12(火) 02:01:08.65ID:rBak2gB5
ごめん、まちがえた
>>47>>44
2016/07/12(火) 02:01:24.87ID:4M8hLvVe
>>47
レスする相手は俺じゃないだろw

例外の使用が推奨ね。
当たり前だが。
2016/07/12(火) 02:21:04.05ID:umCvEWis
>>47,48
情報ありがとう。頭だけざっくり読んだけど、詳細検討には時間がかかりそうだ。
googleのコーディングガイドでしれっと最後に
> Windowsのコードについては、このルールは例外です(シャレでなく)。
とあるのだが、Windowsで閉じている場合は環境が整備されているから
googleみたいな運用方法でも障害にはならないということなのかな?

大ジャンプが問題になっているけど、
現実的には大ジャンプ無しでの処理を強制するのなら例外を使う意味は無いよね。
例えば>>17なら従来方式、

int result = Director.Create("C:\\testdir");
if (result==1) MessageBox.Show("入出力エラーが発生しました。");
else if (result==2) MessageBox.Show("想定外のエラーが発生しました。");

でもほぼ同じなわけでさ。当然そのMSのサンプルコードもthrowしている。
その点>>15の方がそのMSのサンプルコードには似ている。
とはいえthrowするなってのは環境的な問題もあるとは思うんだが。
2016/07/12(火) 02:28:01.69ID:SKMsT/RZ
>>6
tryで囲む領域が大きくなると、どこでエラーが起きたか、わかりにくい

throwはややこしい。
一々、これは内側、これは外側の関数で処理するとか、変わるのはややこしい

LinuxのようなC言語だと、関数の下の方に、
リソース解放などの共通処理をまとめて、gotoでそこへ飛ばすようにするけど、
まあ、ややこしいプログラミングは避けた方がいい

仕事のプログラムは、個人のプログラムとは、書き方が違ってくる。
初心者・新入社員も入って来るから、自分だけがわかる書き方はダメ
2016/07/12(火) 02:33:58.13ID:4M8hLvVe
>>50
そんな小さい処理で同じとか言われてもな。

resultって数字しか返せないだろ。
例外ならオブジェクトを返すことができる。
エラーとして返せる情報は無限大だ。
見つからないパスがどこか情報だって返せる。

あと自動で上に戻る機能。
とかさ、例外の機能をお前は理解してるか?
してないだろ。

なんでどの言語にも例外があるのかを考えよう。
必要だったから例外を作ったんだよ。
これぐらいは理解しろ。
理解したら、なぜ必要なのかの理由を調べろ。
2016/07/12(火) 02:36:15.80ID:4M8hLvVe
> throwはややこしい。
> 一々、これは内側、これは外側の関数で処理するとか、変わるのはややこしい

うん。馬鹿だからだと思うよw

処理する必要があるときだけ処理する。
それだけのこと。

っていうかさ、さっき俺が言ったことじゃん。
自分で何が適切かを考えられない。

マニュアルを用意してほしい、そのとおりにやりたい
自分で何も考えたくない。
やれって言われたからやりましたー。
だから俺の責任じゃないですー。

自分で考えることを何もしようとしない。
2016/07/12(火) 03:23:53.60ID:umCvEWis
>>47,48
だいぶ読んだ。

どっちがいいかは結構微妙だと思うんだけどね。
結局の所全体ポリシーとして「例外」を考慮しないといけないし、もちろんRAIIも徹底してないと危険。
だから出来るだけスマポというのはその通りだけど、
言っちゃ悪いけどRAIIとスマポだけで行く気なら最初からGC言語使えばいいだけだし。
むしろGC言語でGCタイミングをユーザが完全に制御可能にして例外使いまくりというのが正解か?

ついでに教えて欲しいんだけど、下記URLにある
https://msdn.microsoft.com/ja-jp/library/hh279653.aspx
no-fail/strong/basic保証ってのは単なる知識として考慮しろって話であって、
コンパイラに型として指示してコンパイラ側で全部整合性をチェックしてくれるようなことはないんだよね?

どこまで処理するかにもよるけど、原因が分かってそれを通知出来ればいいだけなら、
むしろ「例外機構」の設計が必要になる分、無駄なような気も。
なんつーか、将棋ソフトの駒クラスの例外を設計しようぜ!みたいな。

例えば、
> 発生することのないエラーをチェックするには、アサートを使用します。
> 発生する可能性があるエラー (たとえば、パブリック関数のパラメーターにおける入力検証のエラーなど)
> をチェックするには、例外を使用します。(>>47内URL)
つまり、将棋で言うと「二歩」「打ち歩詰め」は例外として処理しろってんだろ?
なんだかウザイだけの気が。(まあそれ以前に駒クラスが不要だが)

元々は正常処理と異常処理のコードを「見やすさ」の為に分離したいというところから来ているはずなのだけど、
その「見やすさ」を得る為に他も色々注意して設計しろというのは無駄/本末転倒だと思うね。
ただそのコストが環境整備によって極限まで低下したのであれば、それもありかとも思うけど。
それがWindowsの世界なのかなとはgoogleの付け足しから感じた。
2016/07/12(火) 04:39:01.98ID:Vf+ZIi05
Googleのスタイルガイドを読む限り、Windowsのコードの場合は独自性ガ強くて
どうにもならんところが多いからコーディング規則を逸脱しても仕方がないって感じだな
2016/07/12(火) 06:14:29.07ID:4M8hLvVe
>>54
あんたが例外を使ったことがないから
例外がすごく使いやすいってことを知らないだけ。
何かと理由をつけて使いづらいってことにしたがってるだけだな。

戻り値だと注意が必要な場面がたくさんあるが、
例外だとさほど注意しなくても正しく動くアプリが作れる。
なにせ例外処理する必要が有るところだけ書けばいいからね。
すべて正しく書かないといけないC言語方式は大変。
2016/07/12(火) 06:16:12.63ID:4M8hLvVe
例えばC言語方式だと、
printfの戻り値までチェックしないといけない。

ちなみにprintfが失敗する例として書き込み不可能な
デバイスに標準出力をリダイレクトする等がある。

例外だとチェックしなくても書き込みができなかったときに
エラーで中断してくれる。
2016/07/12(火) 08:53:57.34ID:3JVrmQRs
例外を「例外」だと思わないマが多すぎる
とくにJavaから来た人
2016/07/12(火) 10:05:30.22ID:KWfKXhYB
ところでOOPと関係ある?
60デフォルトの名無しさん
垢版 |
2016/07/12(火) 10:09:09.18ID:3O9ex62E
例外よりeitherの方が使いやすいよ
型安全だし
2016/07/12(火) 10:09:59.26ID:ddtK31Ex
ここはOOだけやってんだろ?Pはスレ違いだしな。
62デフォルトの名無しさん
垢版 |
2016/07/12(火) 10:10:01.65ID:3O9ex62E
例外よりeitherの方が使いやすいよ
型安全だし
2016/07/12(火) 11:43:29.90ID:K7Zjf19C
>>17はずれてるだろ

例外処理のメソッドを作った理由は「分割しなきゃならんほど複雑な処理している」からじゃなくて
「あちこちで発生する例外」を共通に処理するためだろ
だから当然再利用もしている
「catchすんのかthrowするのか」ってのも意味不明
64デフォルトの名無しさん
垢版 |
2016/07/12(火) 20:39:39.22ID:cQbnp1H7
>>63
意図を汲んでくれてありがとう
65デフォルトの名無しさん
垢版 |
2016/07/12(火) 21:54:41.73ID:cQbnp1H7
>>26
規約も規則もないみたいで好きに作っていいっていわれたからこう作った。
https://ideone.com/g1uE5d
ちなみにローカル環境でしか動かさないツールだから例外処理はログ出力ぐらいでしか
使わない。
ツールが落ちないようになってるならthrowしちゃいけない理由も特にない。
そうしたらなんでこういう風に作るの?はぁ、ちゃんと見ておけばよかっ、た。
って言われて、レビューとヒアリング聞いてみたの結果これが最適解だった。
コメントは言われたこと少し載せてみた感じ。
https://ideone.com/lbl7VW
これで伝わる?
多少おかしなとこあったとしてもそんなに意味わかんないことしたのかな。
ややこしい?
ファイル作るのにファイル名抜けてたりなんだりしてるけど黙殺してくださいごめん。
2016/07/12(火) 22:51:05.48ID:StomlD/Y
う〜ん、PG歴2年目くらい?
コードをたくさん書きたいお年頃的な
なんつーかクドい

下のコードで必要十分に見えるよ

>予期せぬ値って何?想定があるの?必要?(笑)
同じ感想でワロタ
2016/07/12(火) 22:57:14.06ID:aSzJV8SF
普通に書け
普通に
オリジナリティなんていらねえんだよゴミが
2016/07/12(火) 23:25:13.63ID:umCvEWis
>>55
最後の「ルールの例外」からするとそんな感じだな。
夜はそこまで読んでなかったわ。

>>60,62
大事なことなので?
ってのはさておき、それについても布教用のドキュメントはあるのか?(例>>47)
ググッてもいまいち出てこないんだが。

>>47,48
こんな記述を見つけた。これって何言語か知らないか?
> 言語によっては基本保証やno-fail保証を静的に解析可能なものがあります。
> いくつかの言語ではno-fail保証をそのまま言語レベルでサポートしています。
> コードを静的に解析することでno-fail保証を約束するものもあります。
> また、基本保証を強制している言語や機構があります。
http://qiita.com/Kokudori/items/987073d59529b6c9a37c
2016/07/12(火) 23:28:42.89ID:VAaNpcds
>>66
初心者であるとかお年頃であるとか
そーいうのじゃない可能性もあるな

文章にしたって簡潔に書けない人おるやろ
あの手の人は死んでも直らない
2016/07/13(水) 00:20:45.58ID:7t1kL6eB
>>68
Eiffelみたいな契約プログラミングによる保証か、
https://ja.wikipedia.org/wiki/契約プログラミング
もしくは、
C++11のnoexceptのような仕組みかな
http://cpprefjp.github.io/lang/cpp11/noexcept.html
2016/07/13(水) 00:26:34.83ID:C7S+nyqs
noexceptでヌルポったらどうなるん?
2016/07/13(水) 00:44:09.12ID:yKl3ljrD
>>68
>>60のはHaskellのEitherモナドのことを言っていると思われ
http://itpro.nikkeibp.co.jp/article/COLUMN/20090210/324443/
一応、C++やC#でそれっぽいコードを書いている人はいるみたいだが……

>>71
例外が投げられたら、std::terminate()が呼ばれて終了
73デフォルトの名無しさん
垢版 |
2016/07/13(水) 00:48:21.46ID:wcqcmuYS
>>66
共通の例外処理を繰り返したくないと書かれてるじゃん
読解力がない上に自分の意見を押し付けるってさあ…
2016/07/13(水) 00:49:32.32ID:uq0wU9fp
>>65
おー書いたか、ご苦労さん。
俺が想定したものとは異なるが、それ以上に情報を含んでいたので、
レビューの様子もよく伝わったぜ。

まあ感想は他の連中と同じだな。
君は難しいコードを書いている。だから駄目なんだよ。
張り切って色々やろうとしているけど、それが駄目なんだ。
手を抜くことには努力を惜しまないってのが優れたプログラマだろ。
少なくともそのレビューと上司はまともだから、言うことを聞いた方がいい。

その上司のコードが何故いいか?それは簡単だから。
構造が単純だから、ぱっと見たらちゃんと動くことが分かる。
それに対して、君のコードはちゃんと動くかはよくよく見ないと分からない。

上司のコードは「自分で処理出来る例外はcatch、それ以外は放置」というポリシーだから、
基本的に下から上がってきた例外は「予想外」として落としている。
つまり例外ツリーは単純なツリー構造で、
このポリシーさえ守れば今後とも簡単に処理を追加出来る。
そして処理も基本的に上から下に処理されるだけだ。単純明快でいい。

対して君のコードは、そうじゃない。
よくよく読まないと果たしてちゃんと動くかどうかも分からない。
そして追加するにしても君が作ったクラスを全部知ってからでないと追加出来ない。
つまり、やることが増えすぎているし、密結合になっている。
対して減らせたのはせいぜいDirectry/Fileの例外の被り部分だけだろ。
それは明らかに設計コストを増してしまっている。
2016/07/13(水) 00:50:08.11ID:uq0wU9fp
多分勘違いしているのだと思うし、実際そういう奴も多い気もするが、
ベタに書くのが悪いとか、同じようなコードが2箇所に出現するのが悪いとか、
そういう単純な問題ではないんだ。
分かりやすく言えば、
「そのコードを初めて渡されて、ああこのコードはちゃんと動くだろうねと分かるまでに、何秒かかるか」
について最適化しろということなんだよ。
当たり前だが全く同じ内容がダブってたら読むのに2倍かかるから、
それはループなり多態なりして一つに減らせってことになる。
だけど無理に多態したりして「コードを追う手間」が増えるようでは駄目なんだ。

その上司のコードはさらっと読んだだけで動くのが分かる。
でも君のコードはあちこち追い回さないと動くかどうかも分からない。

もちろん君が書いたコードだから、君のコードを君が読むのには苦労しないだろう。
だからもし君に同様の同僚がいて、同様に駄目出しをくらっているのなら、
その時の両方のコードを君が初見で読みこんで、
その構造と動くかどうかを把握するまで何秒かかるかを比較してみればいい。
2016/07/13(水) 00:53:31.98ID:2JhFq5Nw
>>65
まずMain関数はこれだけだ。
これ以外不要。

public class Test {
 public static void Main() {
  try {
    CreateTempFile("targetPath");
    MaggageBox.Show("一時ファイルが作成されました");
  } catch(XXXException e) {
    MaggageBox.Show(e.Message);
  }
 }
}
2016/07/13(水) 00:59:57.51ID:2JhFq5Nw
CreateTempFileの中身はこうだな

void CreateTempFile(string path) {
 String directory_path = ディレクトリのパス(path);
 Directory.CreateDirectory(directory_path);
 File.Create(path);
}

ディレクトリやファイル作成時にExistsなんてやる必要ない。
Existsのチェックした後に、他プロセスから作成されることもある。
「チェック→実行」のパターンはロック機能がない限りたいていアンチパターン。
2016/07/13(水) 01:03:40.12ID:2JhFq5Nw
結局のところこの程度であればMainに全部入れてもよい良い

public class Test {
 public static void Main() {
  try {
    String path = "targetPath";
    String directory_path = ディレクトリのパス(path);
    Directory.CreateDirectory(directory_path);
    File.Create(path);
    MaggageBox.Show("一時ファイルが作成されました");
  } catch(XXXException e) {
    MaggageBox.Show(e.Message);
  }
 }
}

このコードを出発点としてだ。
メッセージを変えたいのであれば、
メッセージだけを変えるように工夫すればいい。

Mainに全部入れても良いと言ったが、CreateTempFile()という1関数で実行したいならそれもあり
その場合、CreateTempFile()でメッセージを変えたい例外だけトラップして
メッセージを置き換えて投げ直すだけで、Main関数は>>76のようにシンプルのままでいられる。
79デフォルトの名無しさん
垢版 |
2016/07/13(水) 01:19:00.17ID:OE4fGXcq
なにこのキモいスレw
2016/07/13(水) 02:08:26.36ID:uq0wU9fp
>>70,72
情報ありがとう。

> 契約プログラミング
考え方はよしとして、大して採用されてないのは効果がいまいちだったのかな?

> noexcept
お?これはなかなか良い感じ。

ついでにそこから辿れる以下も読んだが、こちらも例外を有効活用しようとしている。
(より正確に言えば、例外を有効活用する時のライブラリの作りについてだが)
http://boostjp.github.io/archive/boost_docs/document/generic_exception_safety.html
例外の文法を使えば、確かに表現力は上がる。それは事実だが、ここに書いてあるように、
当然STLや自前クラスがどの例外保証を持っているかすべて把握してないと駄目だし、
完全活用するとなるとなかなか難しい気がするね。
(プログラミング時に把握しなければいけない項目が増える)

> HaskellのEitherモナド
Haskellの知識はないのでとりあえず日本語部分だけ読んでみたが、
この読み方では有効かどうかは判定不可能だorz
> C++やC#でそれっぽいコード
このURLをくれればすごく助かります。
2016/07/13(水) 02:16:26.70ID:2JhFq5Nw
> 当然STLや自前クラスがどの例外保証を持っているかすべて把握してないと駄目だし、

例外保証ってなんや?

その例外保証があるかどうかわからんものが
戻り値でエラーを返したら、それを保証してくれると
思う根拠は何や?

気をつけることがあるとしたら、それは戻り値でも同じだし
正常処理とエラーを、一つの戻り値(変数)に入れる分
複雑度は上がるんだぞ。
2016/07/13(水) 03:23:41.31ID:vjGvgzcz
>>65
ディレクトリを作れない時に、throwして外のスコープに飛ばすのは、ややこしい。
そこでエラー処理できる

外のスコープから見ても、内側からも、throwしてくると考えると、
考える組み合わせ数が増える。
組み合わせ爆発を避けるため、早期に枝切りすべき

また、内外のスコープで、情報を共有するため、
Commonというグローバル変数もどきを、作らざるを得ないから、
内外の関数が、密結合を起こしてしまっている

修正・保守していくうちに、こういうのがいずれ、スパゲティ・泥団子へと成長していき、
誰の手にも負えないようになっていく
2016/07/13(水) 06:01:23.07ID:QAw5IbxT
>>65
的確な指摘じゃない?
どうみても下の方が出来がいい
2016/07/13(水) 06:22:04.43ID:7t1kL6eB
>>80
>契約プログラミング
C++だとBoost.Contract
.NetだとSystem.Diagnostics.Contracts
があるね
使ったことないけど

>例外保証
なんか、まじめに考え過ぎな気がする
どのクラスがどの例外保証を持っているかなんて、気にして書いている人なんていないんじゃないか
(と、言うとちゃんとやってる人に怒られそうだが)

例外安全、例外耐性を考慮して、きれいにやるなら把握しているに超したことはないけれど
基本的には「いちいち戻り値でエラー判定するのが面倒。戻り値だとエラー判定忘れることがある(アプリがエラー状態のまま動き続けてしまう)。例外をつかえばそれらを簡単に回避できる」くらいの感覚で使われてるんじゃないかな

例えばオブジェクト指向でクラス設計するときはSOLID原則を意識することはあれ、
そこまで厳密に遵守して書かないし、他人の書いたクラスがSOLID原則に則ってるかなんて気にしないでしょ?

それに今時の言語なら標準ライブラリが例外を投げるから、それらを使うなら自分のコードでも例外を使うことで
「このコードでは、エラーは常に例外で通知する」という一貫性が生まれる

プログラミングにおいて一貫性は重要だ
先日のGoogleのスタイルだと「例外を使わない」という点で一貫性がある

もちろん、現実世界ではそんなにすべてうまくいかないから
必要があれば戻り値のエラー通知を部分的に使うのはかまわないと思うよ
.Netにも例外を投げるInt32.Perseと投げないInt32.TryPersreの2種類があるし

>Either
"C++ Either"や"C# Either"でググれば「書いてみた」系のブログが引っかかる
2016/07/13(水) 07:23:43.92ID:L2fL/y00
おはようございます!
ご回答ありがとうごさいました。
そうかー難しいのか。
難しいということはたまに言われますが、なにが難しいのかわからなくていつも悩んでいるので、自分は設計には向いていないのかもしれません。
下流で頑張ります。
皆さんも今日一日頑張ってください!
それでは!
2016/07/13(水) 09:37:32.17ID:2JhFq5Nw
>>84
> .Netにも例外を投げるInt32.Perseと投げないInt32.TryPersreの2種類があるし

名前が重要なんだよ。(ちなみにParseな)

例外を使ったときのメリットは、関数の名前通りの戻り値にできるってこと。

Parseはパースするんだよ。だから戻り値はパースした結果であり
エラーを戻すことはない。パースできなければ例外。

TryParseはパースすることをトライするんだよ。だから戻り値はトライした結果。
もしトライすることすらできなければ、それは当然例外。

その2つは、例外を投げるかどうかの違いじゃなくてやる処理の違い。
そしてどちらもやるべきことができなければ、例外を返す。
87デフォルトの名無しさん
垢版 |
2016/07/13(水) 19:05:13.08ID:OE4fGXcq
そんなに力説するほどの事か?w
2016/07/13(水) 21:38:19.72ID:2JhFq5Nw
>>87
これは力説するほどのことだよ。
なぜなら可読性の話だから。

英語わからんとか、ソースコードを命令の並びだとかしか
認識してないレベルの人にはわからないだろうけど、
ソースコードは読むもの。

読みやすさを大きく左右する要素の一つが、
適切な名前をつけているかどうかだから。

たまに適当な関数名つけてる人がいるけど、ほんとやめてほしい。
適当な単語を並べただけじゃソースコード読めないから。
名前から意味がわからないから、中の処理を読んで解析しないといけなくなる。
89デフォルトの名無しさん
垢版 |
2016/07/13(水) 21:54:55.05ID:OE4fGXcq
それなら問うが
Parseが返すパーズした結果とは何ぞや?
TryParseが返すトライした結果とは何ぞや?
俺には名前だけではさっぱり分からんのだが
これがお前の望む適切な名前とはとても思えんのだがw
2016/07/13(水) 22:01:55.88ID:lnUCd6s/
>>89
友情努力勝利に決まってるだろ
2016/07/13(水) 22:31:57.93ID:oLxbX2RO
正直TryParseで変換できちゃうのはちょっと気持ち悪い
2016/07/13(水) 22:44:01.74ID: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))
2016/07/13(水) 22:44:36.15ID:uq0wU9fp
> 必要があれば戻り値のエラー通知を部分的に使うのはかまわないと思うよ
個人的にはTryParseをよく使っている。それで十分だから。
必要性はない。try/catchでも書ける。

戻り値判定の場合は、その場での処理が強要される。
結果、65の上司型のコードしか書けない。
実際にあのコードを戻り値判定に変換するのも簡単だ。
この使い方をする場合は好みの問題でしかない。

一方、例外を用いれば、65がやろうとした「積極的にthrowして統合的に扱う」ことも出来る。
戻り値判定でこれをするのは大変なことになるので、これをしてこそ活用だと言える。
とはいえ、これがろくな事になる気配が全く感じられない。

ちなみに、言語的な例外復旧能力に必ずしも頼る必要はない。
上位レベルでの復旧も実は簡単だからだ。
例えばTryParse、ファイルから読むのならソースは保持する必要がない。
Seek出来ないネットワークストリーム等なら、MemoryStreamに一旦受ければいい。
JSONみたいに階層ありオブジェクトを丸々生成するのなら、成功した後に差し替えればいい。
これらの場合は、ロールバックを上位で行うことはほぼ自然に出来てしまうので、
結果的にSTLが実装した例外機構の為に無駄に税金を払う事にしかならない。
この点を修正しようというnoexceptはC++っぽくていいが、
なるほどこんな事をやっているうちは生Cを駆逐することは出来ないだろう。
2016/07/13(水) 22:45:05.83ID: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割は無限大になるというお気楽仕様だ。
当初は驚いたが、正直これで問題ないよなとも思う。
2016/07/13(水) 22:58:10.35ID:2JhFq5Nw
>>89
> Parseが返すパーズした結果とは何ぞや?

正しくはInt32.Parseなんだから当然Int32だろw
Int32に変換した結果を戻す
(変換できなければ戻さない)

> 俺には名前だけではさっぱり分からんのだが

あー、うん。クラス名が先に作ってことに
気づかなかったのねw
>>86で引用してる>>84にかいてあんだろ。
気づけよw
2016/07/13(水) 23:09:44.65ID:jyyAd6hv
Int32.Parse だからといって、必ずInt32が返るとは限らないだろ
おまえは、human.age()で必ずhumanが返ると考えるか?
2016/07/13(水) 23:11:23.52ID:2JhFq5Nw
>>94
> なおJavaScriptは0割は無限大になるというお気楽仕様だ。

いや、お前、例外っていったら0除算しか思いつかんのかよw
eval("{") とか実行してみろ。JavaScriptは例外を使う言語だ。

0以外の数値を0で割ったら無限大になるのは数学的に正しい。
JavaScriptが無限大を扱える言語ってだけだ。
もちろん数学的に正しいことをやっているから、 0 / 0 は NaN (非数)になる。
少なくともこの点は、お気楽ではなく高度な言語だと言える。

もっともJavaScriptに例外が搭載されたのはJavaScript 1.4(1999年あたり)からだけどな。
それ以前は(エラーを戻り値で返すのではなく)スクリプトが停止され
window.onerrorイベントが呼ばれたんだっけな?もう忘れたが。
2016/07/13(水) 23:11:30.03ID:jyyAd6hv
いっとくが、human.age()で必ずintが返るとは限らないからな
もしかしたらageオブジェクトが返るかもしれないからな
2016/07/13(水) 23:12:49.31ID:2JhFq5Nw
>>96
> Int32.Parse だからといって、必ずInt32が返るとは限らないだろ
> おまえは、human.age()で必ずhumanが返ると考えるか?

Parseとageで関数名が違ってるじゃんw
名前で返すものが決まるって言ってんだろ。

human.parseだったら、human返すんじゃねーの?
2016/07/13(水) 23:13:53.29ID:jyyAd6hv
>human.parseだったら、human返すんじゃねーの?

そんなの思い込みだろ
ヒューマンパーズオブジェクトが返るかもしれないだろ
2016/07/13(水) 23:18:25.58ID:2JhFq5Nw
>>94
> 他の関数型言語の例外機構ってどうなっているんだ?知ってたらよろしく。

関数型で戻り値でエラー情報なんか返したら
大混乱になるわw

関数呼び出しの中の、関数呼び出しの中の、関数呼び出しの中の、関数呼び出し で
エラー情報が返ってきたら、if式による分岐の嵐でもはや
関数型言語のように見えないだろうね。
2016/07/13(水) 23:22:40.62ID:2JhFq5Nw
>>100
> ヒューマンパーズオブジェクトが返るかもしれないだろ

ほらね? 何が返るか想像できてるじゃんw

Int32.Parseじゃ何を返すかさっぱりわからないって言ってるから
それが間違いだよって話。

なにも100%完全に返り値の情報がわかるなんて言ってないんだよw
2016/07/13(水) 23:36:52.14ID:C7S+nyqs
型を見りゃいいだろ

まさかこのスレに居ながら、屁臭いペチプ〜やゴミのペールやペールの糞からひり出されたルビーや・・・そんな糞まみれのウンコ野郎はおるまいね?
2016/07/14(木) 00:31:59.76ID:4Ps/X1K6
>>102
いやお前それ苦しいだろ

>ほらね? 何が返るか想像できてるじゃんw

想像?
思い込みでしょ
ヒューマンパーズオブジェクトが返るかもしれない、とは書いたが
実際には何が返るかわからないから、そう書いただけであって
どうせ、仕様を調べなきゃならないんだよ
2016/07/14(木) 01:02:32.63ID:9qkjMq+e
>>104
言うと思ったw

でお前これから先仕様なんて調べるの?
調べないよね。もう覚えてしまったから。
あとは文字を見れば思い出すはずだ。

適切な名前があると覚やすいっていうのはこういうこと。
2016/07/14(木) 01:31:15.59ID:rhZMoeJF
>>101
>関数型で戻り値でエラー情報なんか返したら
>エラー情報が返ってきたら、if式による分岐の嵐でもはや

ifの分岐しないためにfunctorだのアプリカティブだのmonadだのtraverseがあるじゃん?
try1 >=> try2 >=> try3 >=> ... tryN
みたいので「成功するまで処理を続けて失敗したら例外情報をもって途中で抜ける関数」を作れるし
こういう合成力は関数型の強み
107デフォルトの名無しさん
垢版 |
2016/07/14(木) 06:27:39.21ID:cfi8dg7p
自分の思い込みの通りなら良い設計良いコードw
2016/07/14(木) 07:26:28.53ID:xgZTwt3g
正しく意図した通りに騙してくれるなら
明らかに良いコードだろ
頭のてっぺんからケツのシワまで数え上げてようやく読解できるコードが糞じゃなきゃ何なんだ
109デフォルトの名無しさん
垢版 |
2016/07/14(木) 07:44:38.40ID:cfi8dg7p
クソの主観によりクソ認定されたコード達w
本当は良い奴も沢山いただろうに不憫だわーw
2016/07/14(木) 08:31:57.85ID:qme/E7bl
車輪の再発明しか出来ない人がいると聞いて。
2016/07/15(金) 23:14:34.82ID:/IkQTUfk
DAO とかDTO ってのが出てくるアーキテクチャは手続き型であって、オブジェクト指向ではない

ってのが解る人ここにいるか?
2016/07/15(金) 23:20:25.90ID:sS/v2c9e
そんな嘘ついちゃいけないんだお
113デフォルトの名無しさん
垢版 |
2016/07/15(金) 23:39:15.88ID:iR/HdeCl
今の日本人は>>111みたいな馬鹿が普通なんだお
2016/07/21(木) 22:59:46.89ID:6Fy4Bz7m
>>113
やはり解る人はいないか
DAOやDTOってのはデータと処理を分離するから手続き的なんだがなぁ
2016/07/21(木) 23:36:49.83ID:vaQfL518
オブジェクト指向なのはEntityを使ったタイプのO/Rマッパーだね。
Railsとかもそう。DAOやDTOなんてのは出てこないで
データベースがオブジェクトにそのままマッピングされる。
2016/07/22(金) 08:12:39.95ID:OQdSZmk7
抽象化が過ぎて解る人がいないだけ
2016/07/22(金) 18:14:47.22ID:fQzF4pQd
>>111
主張が良くわからない。

http://www.nulab.co.jp/designPatterns/designPatterns3/designPatterns3-4.html
に出てくる例と説明にそって、論を展開してみてくれ。
118デフォルトの名無しさん
垢版 |
2016/07/30(土) 00:56:46.87ID:crIAC8Sk
言いたいのは単純に

DAO/DTO

オブジェクト指向論で定義されたものじゃない。
オブジェクト指向で実装されただけで、これらを使うには手続きが必要だ。

それだけだろ。
2016/07/30(土) 02:56:03.60ID:YgaIk6dE
んなことゆーたら全部手続きですやんける
2016/07/30(土) 02:57:31.49ID:6YLFMraq
>>119
程度の問題
2016/07/30(土) 03:07:28.00ID:crIAC8Sk
単に>>114が知ったかぶりしたいだけだろ。
>>111の段階で明らかだし。
2016/07/30(土) 08:02:13.88ID:gkAo/Cig
>>118
逆だろ
使うのはオブジェクト指向にするためで
その実装の中身は程度の差こそあれ
DBを相手にする以上手続き的にならざるを得ない
123デフォルトの名無しさん
垢版 |
2016/07/30(土) 08:03:21.46ID:cz6waps9
知ったかぶりにすらなってなくて意味のない単語の羅列にすぎん
124デフォルトの名無しさん
垢版 |
2016/08/04(木) 16:27:41.40ID:pdTKskF+
クラスの中に別のクラスをコンポジットしてあり、
そのクラスの中にも別のクラスをコンポジットしてあり…という場合、

最下層のクラスに必要な値を入れるために何度もメソッドを経由するのが大変なのですが
オブジェクト指向ではこれが普通なのでしょうか?

カプセル化せずに
outerClass.middleClass.innerClass.set_value(100);
とした方が楽だと思うのですがまずいでしょうか?
2016/08/04(木) 19:08:09.61ID:w6fnMNqO
別に良いけど
innerClass.set_valueが呼ばれて値が変更されたときに
変更されたことをouterClassやmiddleClassに通知する仕組みが必要になるかもしれないよ
この場合、余計にややこしくなる

そのほかのディメリットはカプセル化しないことで発生するディメリットと同じ
2016/08/04(木) 20:37:30.59ID:jTAWnEUa
>>124
O/Rマッパーを使うからそういう処理は
勝手にやってくれる。
2016/08/04(木) 22:17:26.33ID:9BD7w8j0
>>124
更に言えば
実装方法としても、set_valueは分かり難いし楽でも何でもない
あえてやるなら
outerClass.set_value(key, value)とか?
2016/08/04(木) 22:24:04.58ID:dkWDRS+N
>>127
最低のやり方だな
そのk,vのMap、実行するまで完全なブラックボックスになるじゃん
死んで、どうぞ
2016/08/04(木) 23:34:15.07ID:dkWDRS+N
>>127
くっせ〜なホント
こういうペチプ〜崩れの塵屑見ると延髄チョップからのバックドロップ食らわせてやりたくなるわ
まじな。死ね。
2016/08/04(木) 23:36:44.15ID:dkWDRS+N
なんでもarrayにしときゃいいと思ってるド低脳
チンパンジー以下のサルゥ
ほんとつっかえ・・・
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況