オブジェクト指向システムの設計 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/
2017/07/18(火) 22:44:02.28ID:tId1dkJr
>>623
ウェイターをモデル化したのが食券販売機だね。
どう違うか教えて。
625
垢版 |
2017/07/18(火) 22:44:30.71ID:zovgvuTt
>>619
うん、そのフラグ知ってるのは、OrderのCancelを呼ぶということを知ってるのに等しいんだけど?
だから、Cancelと言うメソッドは無いし、実質QueueOrderのOperationがそう。
最低限のAPIじゃん。exec。

キャンセルの責務はcancelに持ってるかもしれんが、その修正の影響範囲はcancelを呼ぶもの全部に波及するぞ。
バケツリレーの良いところは、明らかに守備範囲外、が明確で、かつ、その場合の処理方法が「バケツごと捨てる」の一択しかない所。
捨てられたなら、捨てた時点より以前がおかしい。単純明快。
デジャーナルして、もっかいジャーナルから流すのも簡単。
626
垢版 |
2017/07/18(火) 22:47:30.09ID:zovgvuTt
>>622
責務は、それぞれの責任範囲で行うこと。
それ自体は否定してない。
>>421でも言ってる。

ビジネスロジックは、データの持ち物じゃない。
逆。ビジネスロジックがステートを持つなら百歩譲って理解できるが、データがロジック持つのは責務で言えば越権行為じゃないの?
2017/07/18(火) 22:52:05.35ID:mSXXv0D2
>>623
そうだね
よく読んでね
628
垢版 |
2017/07/18(火) 22:52:47.34ID:zovgvuTt
注文管理システムであれば、ウエイターをモデル化すると実は、ウエイターは2つの職責を果たしてる事に気づくと思う。
(両方できる奴も居るが)伝票に追記したり抹消線引いたりする奴と、料理の配膳や片付けする奴。
伝票があるから、注文を伝えた事が正しかったか証明できて、料理が正しいか、配膳されたか証明できて、そして会計できる。

伝票はひとりでに動いてない。ウエイターが書いてる。
食券の自販機なんかもっとわかりやすいな。金券かつカンバンそのもの。
629
垢版 |
2017/07/18(火) 22:55:50.55ID:zovgvuTt
食券やら映画のチケットはもっと俺が言ってるのに近いか。
存在する=金払った証明として有効
もぎれる=使用することができる

料理が出てきて食券渡して、もぎられると、もうもぎれないので、食券としては無効。
ただ、半券として金払った証明としてはまだ有効。
2017/07/18(火) 23:01:32.66ID:LmMkrF0z
>>629
それでいて所持する役、もぎる役がそれぞれ別にいるってことか
2017/07/18(火) 23:01:37.95ID:oy6gK2Tn
>>624
レストランの物理的な構造に囚われてウェイターという物をモデル化しようとする人が居るってこと
注文クラスと聞いて紙の注文書を馬鹿正直にモデル化しようとする人も同じタイプだね
レストランシミュレーターウェイターモデルならそれでいいかもしれないが注文管理システムでは不適切だろ

ついでに言うとウェイターをモデル化したものが食券販売機という例は適切じゃない
ウェイターも食券販売機も同じインターフェースの実装でしかないよ
632
垢版 |
2017/07/18(火) 23:05:36.86ID:zovgvuTt
>>630
もぎる奴が居るから、存在するし、
使うやつが居るから、存在する。
その数は一対一でもない。媒介物。

もぎりのバイトは、ひたすらチケットもぎるだけで良い。
職務は「もぎれるかどうか判断して、もぎれなければ追い返す」
滅茶苦茶シンプルじゃん。
後工程で、映画の半券持ってたら一軒だけ飲食店で割引なんてのが突然増えても、
飲食店は、半券持ってるか、ハンコ押してないか見て、押して無かったらハンコ押して割り引くだけ。
633
垢版 |
2017/07/18(火) 23:10:05.32ID:zovgvuTt
>>631
飲食店の注文管理システムってのがえらく玉虫色してるな。
レストランシミュレーターウエイターシステム以外を指して言ったなら、かなり恣意的な運用な気がする。

あと、リアルウエイターは2つ以上のインターフェイスを実装することもあるとまで言ってるんだけど、割とスルーなのな。
2017/07/18(火) 23:11:35.47ID:cq/Z8Yw/
おっさんたちがんばりすぎじゃねぇの?
635
垢版 |
2017/07/18(火) 23:13:48.33ID:zovgvuTt
>>634
なんせ、コード掲載必須をルールにしようと言ってる人が、ご高説しかくれないもんだからねえ。
2017/07/18(火) 23:16:56.79ID:j0qpHmEl
なんか喩え話で論点がズレてきてるし
同じことの繰り返しになるから
最後にまとめると

オブジェクト指向では
データと処理を一体化(カプセル化)する

それはネットの解説サイトでも入門書でも
だいたいそう書いてある

一体化してカプセル化することで
外側の利用者は簡潔なAPIだけ
知っていればいいから使いやすくなる
責務が限定されてるから保守もしやすくなる

データと処理がバラバラになってるのは
自己流だから他人に押しつけられても困る
2017/07/18(火) 23:23:00.65ID:nMbDVkey
>>632
もぎれてるか否か、ハンコの有無、といった状態をもとに各加盟店が判断をすると必ず間違いが起こる
後々ハンコ二つまで割り引くと仕様が変更になったとする
仕様変更に気が付かずハンコが1つ押してあるから割引なしと判断する加盟店が必ず現れる
2017/07/18(火) 23:39:41.42ID:tId1dkJr
>>633
??
インスタンスを2つ作ればいいだけの話では?
2017/07/19(水) 00:12:50.17ID:747RlNYZ
エレクトリカルエバンズのドメインドライブ開発を学びましょう。
640
垢版 |
2017/07/19(水) 01:04:48.44ID:Hpw0ftXx
>>637
ハンコ2つは筋が悪い。
一つだから押せば良いのであって、累積できるものはたとえ同じものでも、累積できるものであればもぎるごとく消費するか、予め2つ、ハンコ打つ欄を作るべき。
仕様変更に気が付かず、をなくすためのもぎりやハンコなんだから、先回りしろよ。
>>638
そういう問題じゃなくて、インターフェイスとするのはもっともだ、って話。
2017/07/19(水) 05:39:36.24ID:Fs5NzL6m
>>640
いちいち返しがズレてるなぁ
2017/07/19(水) 07:10:10.15ID:ax2Hweij
>>636
デザパタとか知らなさそうなガキが言いそうな台詞w
2017/07/19(水) 07:44:25.87ID:8lSN/EDp
>>642
それはデザパタを深く理解してない意見だ
デザパタは基本的にカプセル化に沿ってるぞ
2017/07/19(水) 10:25:55.52ID:ZGccHuTU
>>593
> 違う、逆に実際のキャンセル処理はCancelerしか知らない
> Cancelerのcancellなどのメソッドにキャンセル処理を書く
実際の実装では、キャンセル処理には注文のデータそのものが必要なので、「注文の中身を知らない
Cenceler」だとキャンセル処理はできない
なので、CencelerにはOrder自身を渡す必要があり、その結果相互参照するという結合になる

> 肥大化していくから委譲する
肥大化してから考えればいいこと

それとも、最初から「注文実行クラス」「注文内容変更クラス」「注文キャンセル実行クラス」に分割しとくのか?
2017/07/19(水) 10:30:14.53ID:ZGccHuTU
>>596
そのコードだと、C(注文する)・R(注文を取得する)・U(注文を変更する)・D(注文をキャンセルする)の
D以外の目的でOrderクラスを使いたいときでも、常にクライアントはCancelerをインスタンス化する必要がある

さらに言うと、OrderがCencelerに依存しているということをクライアントが知っておく必要があり、
仮にCancelerのコンストラクタ引数に変更があると、Orderクラスのクライアントコード全部を修正する必要がある
2017/07/19(水) 10:56:06.72ID:ZGccHuTU
>>626
> ビジネスロジックは、データの持ち物じゃない。
> 逆。ビジネスロジックがステートを持つなら百歩譲って理解できるが、データがロジック持つのは責務で言えば越権行為じゃないの?
実は、DDD(ドメイン駆動設計)ではそういう考え方に近い
だからといって、一般の「データ+処理+ルール=オブジェクト」が間違いというわけではない
647
垢版 |
2017/07/19(水) 11:13:09.73ID:lwS1UjSf
>>646
うん。そこは納得してる。
「処理」と「ルール」ってのはオブジェクトの責務上持ってて然るべきだけど、それはオブジェクトのインスタンス一つが自分でできる範囲って思ってる。
これ、実務以外では確かSOLIDとか言って定義した人の本で見た気がする。
ググった感じこんなのかな。
https://code.tutsplus.com/ja/tutorials/solid-part-1-the-single-responsibility-principle--net-36074
2017/07/19(水) 12:01:33.11ID:y+cwN28R
こいつらjavaのコード書きながら、
javaeeとか知らなそうなやつらばっかだな。
649
垢版 |
2017/07/19(水) 13:05:49.85ID:lwS1UjSf
>>648
POJOとか、いやEntityであるべきだ、DTOだ、ってJavaだとホントいつやったかわからん議論だな、確かに。
2017/07/19(水) 21:19:18.85ID:747RlNYZ
ジャヴァエエとかいうのなくても困らんし
バカなの茶?
2017/07/19(水) 21:20:38.96ID:8lSN/EDp
>>644
>相互参照するという結合になる
相互参照は不可避でもない

たとえば話を単純にして
注文日から何日以内という情報さえあれば
キャンセルできるとする

その場合、注文日オブジェクトを
OrderとCancelerが(コンポジションで)参照する
共通参照はするが相互参照じゃない

>肥大化してから考えればいいこと
SOLIDの話が出てるからついでに触れれば
注文とキャンセルは異なる責務だと
分かっているので最初から分離したい
2017/07/19(水) 21:24:59.31ID:747RlNYZ
結合がダメ言うならオマエ全部int型の足し算にすりゃええんちゃうか?
バカなの茶?茶茶茶おも茶ンの茶?
ドメインドライブ開発も知らん土方がイキっとんじゃないぞ!おう!
2017/07/19(水) 21:31:04.08ID:8lSN/EDp
>>645
>常にクライアントは〜する必要がある
インスタンス生成の処理は
ファクトリに隠蔽すれば
クライアントは依存関係や
コンストラクタについて知らなくてもいい


>>646
>DDD(ドメイン駆動設計)ではそういう考え方に近い
ええ……? 逆でしょ?

DDDではドメインオブジェクトが
ビジネスロジックを持つ

データと処理をカプセル化する
OOの基本はDDDでも変わらない

あとついでに言うとDDDやるなら
(ドメイン層では)POJOね
2017/07/19(水) 21:33:44.53ID:747RlNYZ
ダメだね君たち〜
才能ないね^^
2017/07/19(水) 21:47:48.41ID:747RlNYZ
設計の答え、教えたろか?
2017/07/19(水) 21:48:22.18ID:ytbmAMvR
>>649
ここは初心者が活発に意見交換して知識を共有するためのスレッドだよ
まともな人はこんなところに来ない
657
垢版 |
2017/07/19(水) 22:54:49.71ID:PC/qPmp3
>>656
そうなの?
キャットドアとかいう欠陥問題を揉んでるスレかと。

なんともならないとなったら壊れる奴居るとこもどっかのスレと同じだなぁ。
658
垢版 |
2017/07/19(水) 22:59:30.27ID:PC/qPmp3
>>651
注文日オブジェクトって何者なの?
正規化しすぎたRDBみたいな話じゃん。
そんな意味のあるようで無いデータ、共通参照したら死人が増えるだけでは?
「何日以内」って誰が持ってる設定値で、誰がそれ使って処理するの?注文日オブジェクト?
密すぎると思う。分離できてそうで、全くどれも単独で存在できないじゃん。
659
垢版 |
2017/07/19(水) 23:03:03.88ID:PC/qPmp3
>>653
ドメインモデルなら、EntityとValueとServicesに分けたら、Orderはどこに行くの?
2017/07/19(水) 23:18:58.09ID:lxe5FWzj
>>655
よろしく
2017/07/19(水) 23:23:06.03ID:HXXCFkzn
話は変わるが、お前らこういうコード書いたらダメだからな

if (order.cancelable()) {
 order.cancel()
}

例外はなんにでもあるからそのことについてコメントはしないが、
この場合キャンセル可能と判明した直後にキャンセル不可能になる可能性がある。

if (order.cancelable()) {
 sleep 1日
 order.cancel()
}

とやれば理由がわかるだろう。

これが正しい書き方だからな

try {
 order.cancel()
} catch(e) {
 キャンセルできない場合の処理
}
2017/07/19(水) 23:33:07.83ID:8lSN/EDp
>>658
>「何日以内」って誰が持ってる設定値で、
>誰がそれ使って処理するの?
たとえば注文日オブジェクトが
期限日を判定するメソッドの形で持つ
キャンセルがそれを参照する

もっとていねいにやるなら
注文日オブジェクトの値から
期限日オブジェクトを生成して
キャンセルは期限日オブジェクトだけ参照するとか

どれくらいの粒度でやるかは
実際の処理がどれくらい複雑かによる


>密すぎると思う
それはたんにひとつのクラスで
何でもやることを密だと思ってない感想

>共通参照したら死人が増える
逆、逆

構造化だと修正に弱いから
仕様変更に対応できなくてデスマになる
2017/07/19(水) 23:36:30.58ID:8lSN/EDp
>>659
OrderはEntity
注文日とかはValue

>>661
もちろん実務では例外処理が重要になるが
サンプルコードとしては複雑になるので省略してる
2017/07/19(水) 23:40:49.25ID:747RlNYZ
わかってないなあ
2017/07/20(木) 00:13:09.93ID:zy040NCi
>>664
回答まだ?
666
垢版 |
2017/07/20(木) 08:44:25.42ID:bw5c+A+a
>>662
期限を判定するメソッドには注文日オブジェクトが必要、
期限日は別にオブジェクトとして期限日オブジェクトが必要。
それCOBOLなんかでよくあるメタテーブルとかわらんくない?

一つのクラスでやらんよ。ジョブランナーはひとつだが、例で挙げたOperaionごとに、は別クラスというか、タスクとしてアクター最初から作る。
どのOperationだとどのアクターか、ってのはジョブランナーしか本来は知ることができないものでしょ。

毎年会計周りは変わるシステムだったけどデスマ起こったことほとんどないよ。
会計屋は、会計する以外のタスク持ってないんだから。

>>663
注文がEntityなのがわからん。何故?
注文日をValueにしたからでは?
2017/07/20(木) 10:39:07.21ID:3fjdXCU7
>>653
> ファクトリに隠蔽すれば
わざわざ結合度が高いクラス同士に分割して、簡単にインスタンス化できなくなり、
なのでファクトリメソッドを用意する?
>>577のように実装すればシンプルなのに、そうやることでなにかメリットがあるのか?

> データと処理をカプセル化する
> OOの基本はDDDでも変わらない
Entity, ValueObuect, Serviceの話だよ

>>662
> たとえば注文日オブジェクトが
> 期限日を判定するメソッドの形で持つ
> キャンセルがそれを参照する
まぁ俺なら文字列比較で一行で終わらせるだろうが、無駄に複雑にして何がうれしいんだか
668
垢版 |
2017/07/20(木) 12:03:30.26ID:bw5c+A+a
>>667
>>577はシンプルそうに見えて闇が深くないか?
例外をThrowするなら、外のCatchは本来は型指定でCatchしてるはずじゃん?
例外の種類増えないって保証も無いし、事実上はCancelを変えると、一旦全体の動作が保証できない状態に陥るかと。
そこからテストするんだろうけど、まず全体のテスト定義書き換える事になるから、全体のテスト定義の定義にあたる要件定義からテスト起こし直しでは?
自動テストかけられる方向で修正したくない?
2017/07/20(木) 13:34:14.05ID:3fjdXCU7
>>668
> 例外の種類増えないって保証も無いし
例外クラスは基底クラスでcatchできるということは理解してるか?

> 事実上はCancelを変えると、一旦全体の動作が保証できない状態に陥るかと。
Order自身は、正しくキャンセルできたかできなかったかのどちらかでしかないから、
全体の動作は変わらないと思うが

> そこからテストするんだろうけど、まず全体のテスト定義書き換える事になるから、全体のテスト定義の定義にあたる要件定義からテスト起こし直しでは?
> 自動テストかけられる方向で修正したくない?
ちょっと意味がわからない
670
垢版 |
2017/07/20(木) 18:21:23.58ID:bw5c+A+a
>>669
基底クラスでキャッチとか常識的に考えて、まともなシステムではありえないだろ。
>>559でいったような、否定文での条件定義と同じく、そのときに定義されていたもの、でしかない。

Orderが正しくキャンセルされたか、って、キャンセルすることができるか以上に正しくが未定義すぎる。

自動テストのくだり。
今までのロジックに一切手を加えていなくて、かつ、お互いが疎であれば、今回分の増分のテスト作って実施しつつ、過去のテストをそのまま実行すりゃ良いじゃん。
呼び出す、みたいな形だと、呼び出してる側のテストまで作り直しじゃん。

全段落含めて言うけど、実務でやらんの?
2017/07/20(木) 18:30:59.84ID:3fjdXCU7
>>670
> 基底クラスでキャッチとか常識的に考えて、まともなシステムではありえないだろ。
いやちょっと根本認識が違いすぎて、何をいいたいのかよくわからん
君のソースには、catch () {}が10個くらい並んでるのか?

> Orderが正しくキャンセルされたか、って、キャンセルすることができるか以上に正しくが未定義すぎる。
キャンセルが完了するかしないかの二択でしょ(それ以外に致命的な以上による例外を含めれば三択だが)
キャンセルできないパターンが多少増えても、全体で見れば変わってないでしょ

> 自動テストのくだり。
> 今までのロジックに一切手を加えていなくて、かつ、お互いが疎であれば、今回分の増分のテスト作って実施しつつ、過去のテストをそのまま実行すりゃ良いじゃん。
> 呼び出す、みたいな形だと、呼び出してる側のテストまで作り直しじゃん。
まじで何を言っているのかわからんのですが
コードで説明して
2017/07/20(木) 18:45:26.11ID:3fjdXCU7
つか、依存しているオブジェクトの変更が、依存する側に影響しないようにするのが基本で、
例えばSOLIDの原則とかがあるんだろ

なんでCancelを変更したら、全体に影響するんだよ
そりゃ設計が悪いとしか言えんわ
2017/07/20(木) 18:52:06.11ID:3fjdXCU7
例外もそう

勝手に既存の例外クラスツリー/群と全く関係ない例外クラスなんか作るなよ
Validatiorライブラリ作ってるんなら、
class ValidatorException extends RuntimeException {}
を継承したOutOfBoundsValidatiorExceptionを追加しろ

で、Validatorライブラリのクライアントは、基本的にはValidatorExceptionかRuntimeExceptionをcatchしろ
674
垢版 |
2017/07/20(木) 19:25:21.13ID:bw5c+A+a
>>671
え?どー言うこと?Exceptionなんかでトラップしたら静的解析にすら怒られるだろ。
FileNotFoundExceptionなのか、とかトラップして、定義外はアプリケーションレベルのハンドラまで飛んでプロセス殺すよ。

それでも既に3択じゃん。
キャンセルには、キャンセル後に承認が必要になった、なんてときには、キャンセル呼んでる所全部直してくの?
キャンセル出来た訳ではなくなるよ。キャンセル処理は完了したんだろうけど。

そもそも正常系を例外で処理すんな。


テストの事。
....cancel()が、メソッドで、かつ、例外を吐くならば、
呼び出し元のtry-catchやってる、例えばCartやらUserやら、そのクラスも必ず再試験でしょ。
CardやらUserを再試験するならば、システム全体の結合試験もやり直しだわな。
かつ、その試験仕様は、要件が変わったんだから、試験仕様やソース以外からつくる他ないだろ。
サブシステムやデータクラスの問題が、システムの問題になる。

例外吐くんだから。例外って端的に言えば大域ジャンプだぞ。

>>673
アホか。
2017/07/20(木) 19:37:01.08ID:XDbsbGlQ
例外は極力クラス内で殺したい
モノによったらゼロは難しいかもしれんけど外に迷惑かけたらやばい

プログラムの例外を逃がすだけでリアルの俺が殺される
2017/07/20(木) 20:48:26.88ID:buuqmr6G
>>667
同じことの繰り返しになるから
ひとつだけ言うと

>Entity, ValueObuect, Serviceの話だよ
Value Object はメソッドを持つよ
データと処理をカプセル化する

Services は処理専門だけど
Entity と Value Object だけで扱いづらいものだけ
Services を例外的に適用するのであって

Value Object をメソッドを持たない
たんなるデータの入れ物にして
Services から処理するのは
手続き的なアンチパターンで
DDDのやり方ではない
2017/07/20(木) 22:30:58.38ID:mEIqzc+z
インスタンス生成の処理は
ファクトリに隠蔽すれば
クライアントは依存関係や
コンストラクタについて知らなくてもいい

これ意味わからん
コード書いてみてよ
2017/07/20(木) 23:38:17.62ID:1m8bkM5u
よくわからんが、order.cancel(); が出来るってことは
orderオブジェクトはそのメンバにシステムへのリンクを持ってるってことか?
class order
{
  system s;
  void cancel()
  {
    s.cancel( this );
  }
};
↑これなんかすごく筋悪くね?
system.cancel(order);
で良くね?
cancelの処理がオーダーだけで完結するとは思えんし
俺の中でorderがレシーバーとなってcancel処理っていう発想がない

で、order.is_cancelable(); も何か変で、キャンセルできるかどうかは
orderクラスだけで決まることではないし、キャンセルできるかどうかのフラグを
orderに持たせていちいち更新するのも変な話だな
そもそも、orderが何でそんなこと知ってるんだ

ただ、キャンセル中かどうかなどのステート値はorderに持たせて良いと思うけど
他に置き場ないし
2017/07/20(木) 23:39:43.75ID:1m8bkM5u
主従関係が逆転した考え方は嫌いだな
プログラムは明確にトップダウンなほうが読みやすい
手続き型プログラムにはデータ構造と制御構造の二要素しかないんだから
それぞれ組み立てたうえで、それらをどのように割り振るかってことだけ
考えとけば変なことになりようがないと思うんだけど

あと「誰が処理するべきか」って発想がダサくて、そりゃ誰かと問われれば
処理するのは何時でもコンピュータだわな
そうじゃなくて、本来は 「どこへ書くべきか」 だろ?
発想の転換というか、本来のあるべき考え方を取り戻すというか
現実を正しくとらえないとな
2017/07/20(木) 23:45:13.58ID:mEIqzc+z
俺が全てを知ってるんだから
俺オブジェを作ろう
ore.god
2017/07/20(木) 23:47:19.71ID:1m8bkM5u
どこへ書いておけば後々楽かなぁ〜ってことだけ考えとけばよく
誰が処理するか、とかワケワカランことは考えなくてよし
これで大体迷子になっている人が多い印象、2chみてる限りはね
2017/07/20(木) 23:47:26.83ID:Y8mmcpEl
>>680
そのオブジェは邪魔なのでお片付けしちゃいましょーね〜
2017/07/20(木) 23:48:59.86ID:mEIqzc+z
>>681
そうやって君はコントローラーやセービスにたくさん手続き書くんだろう?
それじゃオブジェ志向にはなれないだよ
2017/07/20(木) 23:58:42.38ID:Y8mmcpEl
すべてを知ってるのにファクトリ隠蔽をご存じないのはおもしろいですね
カプセル化としても大切なポイントなのに
2017/07/20(木) 23:59:13.34ID:1m8bkM5u
別にそういうわけでもないけど

でもよ、書かなきゃならないコードの総量は決まっているわけよ
必要な機能を削るわけにはいかないからな
とにかく、それは、決まってるから、初めから

それを分割してどこへ書くかってだけの話で
無理に小さなオブジェクトへ不必要にコードを押し込んでも意味無いっつーか
自然な形で実装できればそれでよし
自然が一番
2017/07/21(金) 00:07:01.17ID:joLx1qFD
あぁ、「小さなオブジェクト」ってのは変な表現だな
「末端のオブジェクト」でおねがい
2017/07/21(金) 00:26:40.80ID:61IBLwjA
自然な手続き型至上主義の老害ガイジいるかぎり
日本の未来は明るいな
2017/07/21(金) 00:27:36.02ID:61IBLwjA
> でもよ、書かなきゃならないコードの総量は決まっているわけよ
> 必要な機能を削るわけにはいかないからな
> とにかく、それは、決まってるから、初めから

これ読んだだけで程度がしれるからすごい
2017/07/21(金) 00:32:01.04ID:joLx1qFD
あと、SSE用、AVX用、AVX2用、AVX512用、と
プログラムのメイン部を4つも用意するのはマジ勘弁なんで
その辺も含めてコンパイラのループのSIMD展開に頑張ってもらうしかないと思う
2017/07/21(金) 00:41:30.63ID:joLx1qFD
そういった煽りには何かこう、イラッとすら来ないんだよ
何言っても無駄なのは知ってるし
囚われてる的な何か
自分で気づくまではどうにもならない類

迷路を自分で作って自分で解くのには飽きた
ただそれだけ
2017/07/21(金) 06:50:23.04ID:61IBLwjA
糞設計糞コード糞重複

でもよ、書かなきゃならないコードの総量は決まっているわけよ
必要な機能を削るわけにはいかないからな
とにかく、それは、決まってるから、初めから

ガイジか?
2017/07/21(金) 08:41:20.87ID:aAG5dXP6
コード総量がどーのって方は固定値取得とかエラー処理、ログ出力のような汎用的な処理も毎回コピペしてるんだろうか
そして毎回同じテストをしているのだろうか
2017/07/21(金) 09:45:18.16ID:KtdPIrW5
>>691
クソコードクソ重複が
お前にとっては「書かなきゃならないコード」
ってことかい?w
2017/07/21(金) 10:35:11.71ID:kcrlXzzc
俺も最後にするわ

>>676
> DDDのやり方ではない
ルールをどこに実装するかの話で、あ氏はデータがルールを持つのに納得できないというので、
DDDではServiceにルールを実装することもあり、DDDの話を持ち出したまで
2017/07/21(金) 10:43:54.11ID:kcrlXzzc
>>674
> そもそも正常系を例外で処理すんな。
ケースバイケースだしポリシーの話でもあるね
>>577でも「例えば例外をthrow」って書いてるだろ?

俺がそれに関して今君と話したいのはここね
>>670
> 基底クラスでキャッチとか常識的に考えて、まともなシステムではありえないだろ。

> テストの事。
> ....cancel()が、メソッドで、かつ、例外を吐くならば、
> 呼び出し元のtry-catchやってる、例えばCartやらUserやら、そのクラスも必ず再試験でしょ。
まぁ別に再試験してもいいが、しなくてもいい
なぜなら、
class Exception;
class ServiceException extends Exception;
class OrderServiceException extends ServiceException;
class OrderCancelNotAllowedException extends OrderServiceException;
という例外クラス群だったとき、CartやUserは、ServiceExceptionやOrderServiceExceptionなんかで
catchすべきだから

> CardやらUserを再試験するならば、システム全体の結合試験もやり直しだわな。
OrderCancelNotAllowedExceptionを作成する前後で、全体として何かがかわったわけではない
まぁ、やり直してもいいけど

> >>673
> アホか。
何がアホなのか全くわからない
君と会話する意義がゼロに近づいてるぞ
2017/07/21(金) 13:01:16.21ID:+UMDimrc
話がかみ合っていない

おそらく基底クラスの認識がズレてる
697
垢版 |
2017/07/21(金) 13:09:10.34ID:4ZsLxlrH
>>695
例外をスローってのは、もうどうしようもない場合だろ。

ServiceExceptionに新しい小クラス作ったなら、それは元のServiceExceptionではないんだから、テスト範囲膨大になんじゃん?って話。

前提として変わってるよ。....NotAllowed....で拾ってたなら、具体的にはNotAllowedのうちのあれとこれとそれを拾ってた訳なんだから。
大きくCatchして、その中で各サブクラスごとの処理してた時に、新しいサブクラスのハンドリングはすべきか否か、ってのが、仕様として考え直しだろって話。

APIとしてシンプルが売りって、それ呼ぶときだけで、ハンドリングは全然シンプルじゃないじゃん。
698
垢版 |
2017/07/21(金) 13:14:58.39ID:4ZsLxlrH
見た目上疎なのと、実際に疎なのは全然違うし、
大雑把にしか取らなくて良いのと、大雑把にしか取れないのは全然違う。
未来の定義を含んでるから大きく取る他無い、って設計として柔軟なんじゃなくて、設計としてあやふやなんじゃん。

ある意味、そいつが責務として無責任な返事をしてて、その後始末を使う側に押し付けてるように見える。
2017/07/21(金) 14:11:25.03ID:joLx1qFD
そもそもの質問の題意からかなり外れてしまっているように思えるんだが
こういう風にかくも脱線するのがOOPなのかしらね

平たく言えば、もともとは
メソッドが正しくないタイミングで呼ばれたら、どう対処すべき?
って質問だったろう
で、明確な答えなんかないだろう
例えば、a=10; b+=a; って書くべきところを順番を間違えて b+=a; a=10; って書いたら
正しくないタイミングで処理したといえるわけだけど、コンパイルエラーも実行エラーも出ないし
それが我々の日常で、ただのバグであって、手続き型言語というのは何時でも順番が大事で
正しいタイミングで処理が走るように気を付けて書くものだったろう
一方で、順番を間違えたためにバグってヌルポやdiv0が発生することもある
ただしこれはどうしても続行が不可能だから例外を飛ばしているわけであって・・・
あとほか、初期化前の変数を参照しようとして怒られるとか、もあるが

基本的には手続き型言語は処理の順番の権化なので
処理する順番を間違えたとか、変なタイミングでメソッドを呼んだとか
それはプログラマのポカ、バグ、なんだから、テストで炙り出すしかないだろう
こんなことを全部が全部丁寧に例外なんかで対応していたら
手続き型言語はすべての個所で順番が重要なわけだから、全てでチェックが必要になる
順番やタイミングを誤って良い場所など、無いと思ったほうが良い
2017/07/21(金) 14:17:09.63ID:joLx1qFD
しかし、丁寧に作るなら
明らかにおかしなタイミングやおかしな順番で呼ばれたら例外を投げるのは有り
ただしそれはプログラマがミスをしたことを早期に伝えるためであって
そこで条件分岐などして通常フローに組み込んだらまたおかしなことになる
まぁほどほどに

っていう程度の話なのに、それが何故
何処でキャンセル出来るかどうか判断するか、とか
キャンセル処理は何処でするか、とか
認可がどうのこうの、ジョブがどうのこうの
とかって話に派生するのが謎だわ

ある意味では面白い問いかけでは有ったと思うよ
手続き型言語で「手続き」を間違えた場合、どう対処するか?っていう
そのままバグるのか、例外投げるのか、エラーコード返すのか、何もしないのか
好きなのを選べ
2017/07/21(金) 14:35:53.73ID:joLx1qFD
俺が思うに
「呼び出し元のプログラムがバグってて誤ったタイミングや順番でメソッドが呼ばれた場合
 どう対処すべきか」
っていう問題と
「仕様上、今現在キャンセルできる状態なのかどうなのか、また、どこで判定するのか」
という別問題を混同して一度に扱おうとするから
話がややこしくこんがらがっているのではないか
2017/07/21(金) 15:22:03.43ID:kcrlXzzc
>>697
> 例外をスローってのは、もうどうしようもない場合だろ。
トランザクションをコミットできないような事象は全て例外でハンドリングするというポリシーもありえる

> ServiceExceptionに新しい小クラス作ったなら、それは元のServiceExceptionではないんだから、テスト範囲膨大になんじゃん?って話。
だから基底クラスでcatchしろって話なんだが
2017/07/21(金) 15:35:40.87ID:kcrlXzzc
>>701
> 「呼び出し元のプログラムがバグってて誤ったタイミングや順番でメソッドが呼ばれた場合
>  どう対処すべきか」
そんなこと話してた奴いたか?
2017/07/21(金) 15:38:37.36ID:kcrlXzzc
>>697
> 前提として変わってるよ。....NotAllowed....で拾ってたなら、具体的にはNotAllowedのうちのあれとこれとそれを拾ってた訳なんだから。
> 大きくCatchして、その中で各サブクラスごとの処理してた時に、新しいサブクラスのハンドリングはすべきか否か、ってのが、仕様として考え直しだろって話。
全く意味がわからん
コードで説明して
2017/07/21(金) 15:52:10.73ID:kcrlXzzc
>>697
> 大きくCatchして、その中で各サブクラスごとの処理してた時に、
ちょっと待てよ、そんなこと誰もしないぞ

つか、君、SOLIDのことはわかってるんだろうな?
まさかとは思うが、ポリモフィズムすら知らないなんてことはないよな?
2017/07/21(金) 16:01:34.64ID:JaMkQK0G
ずいぶん前から何度も訊いてる>>422,434,455,527んだが、なぜ答えてくれなんだ出題者よ
2017/07/21(金) 16:14:55.54ID:h+PJbf5A
手続きおじさんに触れるとめんどくさいよ
2017/07/21(金) 16:41:22.90ID:joLx1qFD
>>703
>>412を100回読めばわかるが
もともとは
「実行できない状況でメソッドが呼ばれたら、どう対処すべき?」
って話だろ
で、実行できない、処理を続行できないので、例外投げてますよ、というだけの

実際彼は
> ただその関数型方式でも結局、状態によって呼んではいけない処理を容易に呼べてしまう所は同じままだと思う
> ビジネスルールが複雑化して状態数が増えるとソースコードがinvalid argument exceptionだらけになってしまう
とも言っているわけで、呼ばれてはいけないタイミングで呼ばれたら、どう対処すべき?って話なんだよ
呼んではいけない状況で呼ぶな、バグるから呼ぶな、は手続き型の基本であるが
まぁ安全のために例外でも飛ばしておこうと

それを>>416
> 値を持ったデータの塊に生やしたメソッドでやるから話がややこしくなるのでは?
と余計なことを言うから話がややこしくなって脱線したわけだが
実際には cancel() がどこに実装されていても関係ないわけよ
本質は、キャンセル出来ない状況で cancel() 呼ばれたらどうすんの?例外飛ばすの?
例外であふれかえるんだけど?
って質問なんだから、どこに実装されていても関係ない
そしてこんなことは手続き型プログラミングではありふれている一般的な話題であって
(手続き型なんだから手続きを守ってもらわないと困る)
ジョブとか認可とか、以降の話は、まるで脱線
2017/07/21(金) 16:45:33.11ID:joLx1qFD
いうなれば
「初期化メソッドが呼び忘れられている状態でオブジェクトの他のメソッドが呼ばれたら
 どう対処すべき?例外飛ばしとくべき?例外であふれかえるんだけど?」
っていう質問と同義なんだよ
2017/07/21(金) 16:54:46.20ID:kcrlXzzc
>>708
> もともとは
> 「実行できない状況でメソッドが呼ばれたら、どう対処すべき?」
> って話だろ
そうだが、バグってそうなったらという話じゃないと思ったが

> って質問なんだから、どこに実装されていても関係ない
そんなことないって延々話が続いてたわけだが
711
垢版 |
2017/07/21(金) 16:57:09.68ID:4ZsLxlrH
脱線も何も一番大事だと思うけど。

まー、理解できないなら仕方ないわ。
DTOオブジェクトにメソッド持たせたりとか、過去やった事として悪手だと言ってるんだが、
多分使いたくて仕方ないんだろ。
2017/07/21(金) 16:58:59.38ID:kcrlXzzc
>>709
> っていう質問と同義なんだよ
俺は全然違うと思うけど、OOに詳しくないと同じに見えるのかもね
2017/07/21(金) 17:02:18.04ID:joLx1qFD
大体からしてキャンセルできない状態であれば
画面上のキャンセルボタンは無効になっているか表示されてないか
ともかくキャンセルのオペレーションは実行できなくなってるはずなんだよ
もし無理やり飛んできても、どこかの段階で弾く
それなのに cancel() が呼ばれるってのは基本的にプログラムがバグってるんだよ
だからキャンセルできない状態なのにcancel()呼ぶな、バグるから呼ぶなって事になるが
それでもプログラマの不注意で呼んでしまうかもしれないので
安全のために例外でも飛ばしておきましょう
そうすれば早期に気づくでしょ、ってこと
だからassert()みたいなものだな
2017/07/21(金) 17:13:00.06ID:joLx1qFD
>>710
>そうだが、バグってそうなったらという話じゃないと思ったが

バグらずにそうなるってどういう状況だよ
実際にcancel()呼んでみて例外が飛んできてから
「あぁ今キャンセルできない状態みたいだからゴメンって画面に表示しとくか」
ってプログラムあり得るか?
キャンセルできる状態かどうかは事前にチェックしてて
それに合った画面表示になってるだろ
それでもcancel()で例外が飛ぶことはあるだろうが
それは本当の実行時エラーだ
少なくともキャンセルできない状況というのが事前に判明しているにもかかわらず
実際にcancel()呼んでみて例外が飛んでくるかどうかで判断とかあり得ないだろ
だからキャンセルできない状態でcancel()が呼ばれるってのは単純にバグってるんだよ
その辺をケアするかどうかの話だろ
2017/07/21(金) 17:15:35.17ID:kcrlXzzc
>>713
> 画面上のキャンセルボタンは無効になっているか表示されてないか
> ともかくキャンセルのオペレーションは実行できなくなってるはずなんだよ
そんなことないから、どこで/誰がキャンセル可能かどうかを判断すべきかって話になってるんだが

・ブラウザで注文一覧を見る
・見ている間に発送処理が完了する
・注文キャンセルを行う
・サーバが注文キャンセルリクエストを受け取る
みたいなときとか

厳密に言えば、
if (isCancelable()) {
  doCancel();
}
がアトミックでなければ、「発送」が途中に滑り込む可能性もある
2017/07/21(金) 17:46:44.99ID:FxlP3XPo
手続きの主張は「例外出させるプログラムを組む人が悪い」なので話は通じないよ

ここはできるだけヒューマンエラーを排除するための考え方を話す場所なのにね
2017/07/21(金) 20:12:55.82ID:joLx1qFD
>>715
それは本当に防ぎようのないことだから例外投げるなりなんなりすればよいが
もともと質問者はそんな質問はしていないだろ?
そんなことをどうにかしてくれって言ってるわけじゃないだろ?

>>412のコードを見てもそうだし
>>417でも
> ただその関数型方式でも結局、状態によって呼んではいけない処理を容易に呼べてしまう所は同じままだと思う
> ビジネスルールが複雑化して状態数が増えるとソースコードがinvalid argument exceptionだらけになってしまう
って言ってるだろ
「呼んではいけない処理を容易に呼べてしまう」
って書いてあるだろ?
これは要するに、「呼んではいけない状態の時に呼んではいけないメソッドを呼べなくする方法はないものかね?」
って質問しているわけだよ
それが出来ればプログラマが呼び出しミスすることを原理上なくすことが出来て
ここが大事だが、「その類のエラー処理を書かないで済むので」
> ビジネスルールが複雑化して状態数が増えるとソースコードがinvalid argument exceptionだらけになってしまう
のを防げるんだけども?っていう質問をしているんだよ
呼んじゃならない状態ってわかりきってる時でも、呼んじゃならないメソッドが呼び出せちゃうから
それに対するエラー処理書かなきゃなんねーメンドクセーなんか良い方法ない?って質問なんだよ
だがそれは手続き型言語に対する挑戦でもあるから程々にって俺は思うが、そのことはまぁどうでもよい

それで>>453なんかは質問者の意図を理解してスレの流れを元に戻そうとしているし
>>706なんかも質問者の意図を理解しつつ、探っているだろ

とろこが若干約二名は全然質問の意図と関係ないことを延々と長時間ものすごいレス数で
いったい何やってんだ?
こんなのがプロジェクトに交じってたら会議がいつまでたっても終わらないし
これがもし顧客の質問だったのなら、もうあいつは連れてくるなってなるだろ
全然違うこと言いだして知識をひけらかしあって何がしたいんだ?
2017/07/21(金) 20:15:16.81ID:AAWIl0Xa
> 何がしたいんだ?

そんなもん自覚できてるわけねえだろw
もししててもさすがに発表できないだろw
2017/07/22(土) 09:54:45.41ID:ymw3r4IA
引っ込みどころを見失った手続きおじさん
2017/07/22(土) 10:39:32.69ID:e/4f5Q/N
>>717
> 全然違うこと言いだして知識をひけらかしあって何がしたいんだ?
知識ひけらかしあってって、すげー低レベルな話しかされてないんだけど。
嫌なら飛ばせよ。
2017/07/22(土) 10:43:27.60ID:e/4f5Q/N
>>717
> それに対するエラー処理書かなきゃなんねーメンドクセーなんか良い方法ない?って質問なんだよ
結論としては、オブジェクトのメソッド内部でチェックをして、例外で(エラーコードでいいけど)
返せってことでしょ。

手続き型だって、正常時が戻り値0、異常時がマイナスの値だったら、
if (hoge() < 0) {
some_error_process();
return;
}
some_process();
と書いて、hoge()のエラーの種類が増えても大丈夫なコードにするだろ?
それと同じだよ。
722
垢版 |
2017/07/22(土) 10:53:36.41ID:qYk/zBjZ
>>716
そんな事言ってないぞ。
正常にキャンセルに失敗したならば、そりゃ例外じゃなくて結果だって。
723
垢版 |
2017/07/22(土) 10:56:40.54ID:qYk/zBjZ
>>719
引っこむ必要もわからん。
とりあえず、手続き型ではないオブジェクト指向であれば、ロジックは例外ありきで作るべきなのかってのは気になる。
例外ではなく、メッセージパッシングに使ってるなら、それは例外の濫用では?と。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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