- PR -

プログラムの書き方でご指導お願いします。

投稿者投稿内容
がるがる
ぬし
会議室デビュー日: 2002/04/12
投稿数: 873
投稿日時: 2005-11-09 12:45
がるです。
…コメントを返すかどうか悩んだのですが。

引用:

引用:
個人的には「戻り値で判断」をあまりしていない、のかもしれないです。


という記述があったので、正常系状態遷移に積極的に例外を利用しているような印象を受けました。


その記述の直前のコードをご覧ください。
そのコードを読んでなお「正常系状態遷移に積極的に例外を利用しているような印象を受け」
るようであれば、何も言うべきものはありません。

引用:

何度も体験しているのだとしたら、それは設計ミス・設計能力の問題かもしれませんね。


そうだろうと思います。もっとも改修において「前任者」とお話をさせて
いただける場を設けていただけない場合も多々ありますのでなんとも…
ではあるのですが。
或いは「設計ミスだ」と騒ぐのはよいのですが。それが事態の解決には
まったくつながらないです。
で。折角なのでそのようなミスは積極的に自らの経験として
糧にさせていただいているってのが現状です。

引用:

ふつー、成否や有無などの二値表現に boolean を使います。それが仕様変更に耐えられないというのは、根幹を揺るがすほど大きなシステム変更ではないでしょうか。


1。「ふつー」。便利な言葉ですね。私は「危険な言葉」だと
認識しておりますが。
現実、成否判定で「一部成功」とかいう微妙な判断が出てくる
ケースは決して少ないものではありません。
(そういえば「据え置き」とかってステータスもあったなぁ、と。)
2。「根幹を揺るがすほど大きなシステム変更」であることに
特に異論はありません。
ただ「大きな変更」は「大きな金額」につながるだけで、
作業しなきゃいけないことに変わりはないです。

引用:

初期設計時に二値だからといって適当に boolean を使ったりはしていないですよね? たとえば性別属性を「男(true)」「女(false)」と boolean で設計するのは間違い。顧客は「子供」は別に集計したいなどと平気で言い出しますからね。


む、これは新しい知識。「性別属性」をbooleanで、っていう
考え方をする可能性があるですね。
今のところこのタイプに当たったことはないけど…気をつけねば。
# というか性別が二値であるって認識すらなかった(苦笑
# 大抵の場合、最低でも男女+不明で、そもそも二値にならなかったりするので。

引用:

引用:
ただ、現実には「ありえないと叫びたいほどの仕様変更」があるのも事実なので。


ならば「ありえない」と言いましょう。


ありえないと言える未記入さんの環境を心よりうらやましく思います。
# いやまぁ対クライアント交渉術としては当然のごとく
# 「これは……………少々工数がかさみますねぇ」とかいう
# 無言の圧力込みの発言をするものですが。

ただ。ありえないと叫ぶことと
引用:

十分な説明を行ってシステム変更費用を取れるように努力しましょう。


との間に大きな乖離を感じるのは気のせいでしょうか?
それとも「ありえない」と叫びつつあきらめて仕様変更の作業をするという
ことでしょうか?
それならば、作業的にはやはり「あらかじめ可能性を考慮しておく」
ほうが有利です。
# 手の内をクライアントに見せるような愚は犯しませんが。

引用:

戻り値の範囲というのは、なるべく狭いほうがシステムが平易になります。汎用性のヒトコトで広げるべきものじゃない。


それがユーザのシステム要件に対して叶うものであるのなら。

引用:

割り切った設計も顧客のメリットになります。過剰な設計で顧客は喜んだりしませんよ?


以前から多々感じていたのですが。恐らくは未記入さんと私の
環境は随分と開きがあるようなので。

私の周囲の環境の場合、場合によっては「金にはある程度糸目を
つけない」からという条件で「かなりヘビーな仕様(変更)」を「通常
ありえないような速度で」要求されることがあります。

出来ない、という一言で片付けるのは簡単です。
ありえない、と騒ぐのは簡単です。
仕事を失うだけですが。

目の前には「事実」と「要求」があります。
無論営業的観点も必要ですが、金額で折り合いが付けば
「やらなければならない」事も多々あります。
# ええ修羅場ですよ。修羅場ですともさ(血涙

事実は小説より奇なり。
クライアントの業務業種によっては、私の予想範囲など
あざ笑うかのごとき奇天烈な要求も存在します。
# おかげで大抵のことでは驚かなくなりましたが(笑

無駄な実装はしません。工数かさみますし。
でも変更があったときに「変更が容易である」ような
設計は常に意識しています。
だからこその、例えばステータス取得を別メソッドにする
だのそういう手法が生まれてくるわけです。

このラインについて環境が違う以上議論するつもりも
なのですが。
一応私の状況をコメントさせていただきました。

元の発言からかなりそれてしまったことをお詫びいたします
> スレ主 & みなさま
まいるどきゃっと
大ベテラン
会議室デビュー日: 2004/08/12
投稿数: 135
お住まい・勤務地: 群馬
投稿日時: 2005-11-09 12:59
>未記入さん

おっしゃっていることだけ見たら、おおむね同意なんですが、なんか違和感が……
なんか、がるがるさんの発言を読んで、そこからいろいろ想像をふくらませすぎて、書いてもないことにつっこみを入れまくっているように見えます。

もうちょっと落ち着いてみてはどうでしょう?
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-11-09 13:55
引用:
その記述の直前のコードをご覧ください。


if(cobj.is_true()) { ... } else { ... } のことですか? この if 文を見る限り、boolean の戻り値を使うのと本質的に何も変っていないと思います。この if 文の書き方自体明らかに、二値表現(真偽)しか意識していないですよね。

ここで、第3の値が必要になったらどうするんですか? 第3の値が必要になった時点で例外によるフロー制御をするのだろうと思ったのですが・・・。

それと、is_ture() が常に正しい値を返すことを保証できますか?

コード:
try {
  cobj.check();
} catch(Exception e) {}

if (cobj.is_true()) {
    // 承認OK
} else {
    // 承認NG
}


例外を握りつぶされた場合にも is_true() は信頼できる実装になっているでしょうか。is_true() で正しい値を返せるフェーズまで進んでいない場合、is_true() が例外を投げないといけないことになりませんか? 結局 cobj.check() の戻り値判定と例外を使う場合と何が違うのかまったく読み取れません。

引用:
ありえないと言える未記入さんの環境を心よりうらやましく思います。
# いやまぁ対クライアント交渉術としては当然のごとく
# 「これは……………少々工数がかさみますねぇ」とかいう
# 無言の圧力込みの発言をするものですが。


「少々工数がかさみますねぇ」それが「ありえない」の結果なのでは? 私だって文字通り「ありえない!」などと顧客の前で叫んだりするわけじゃないですよ。ただ、システム設計として想定外なので費用がかかる、という事実を相手に伝える必要がある、そのような変更要求が発生してから、はじめて変更内容を検討するというスタンスにもメリットがあるということです。

あなたの「二値では足りない可能性を考慮しておく」というスタンスからは「少々工数がかさみますねぇ」という発言は想像できませんでした。てっきり「想定の範囲内です!」と答えると思ったのですが。

引用:
それとも「ありえない」と叫びつつあきらめて仕様変更の作業をするということでしょうか?


「叫ぶ」とか「あきらめる」とか意味がわかりませんけど、システム設計段階で想定されていない変更であれば、きっちりと費用を頂いた上で変更作業をします。もちろん、常識的範囲内の要件であれば、システム設計漏れとして無償で追加作業をさせていただく場合もあります。ただ、boolean の成否判定が通用しなくなるような大規模改修では、そういった可能性は低いでしょう。

引用:
このラインについて環境が違う以上議論するつもりもなのですが。


環境やスタンスの違いではなく、単純にあなたの提示したコードのメリットが分からないのです。どのあたりが、二値表現の拡張を想定している汎用性の高いコードなのですか?

引用:
おっしゃっていることだけ見たら、おおむね同意なんですが、


そうですか。それであれば「おっしゃっていること」だけ見て同意していてください。私が申し上げていないことまで無理に想像して第六感で感じ取っていただく必要はありません。
がるがる
ぬし
会議室デビュー日: 2002/04/12
投稿数: 873
投稿日時: 2005-11-09 14:22
がるです。
んっと、後々に見る方にも或いはメリットがあるかと
思ったので、部分的に。

まず
引用:

コード:
try {
  cobj.check();
} catch(Exception e) {}

if (cobj.is_true()) {
    // 承認OK
} else {
    // 承認NG
}


例外を握りつぶされた場合にも is_true() は信頼できる実装になっているでしょうか。


握りつぶすのはいかがなものかと。
もちろん「そんなことをしでかすようなPGに渡す可能性のあるクラス」
なら考慮して実装しますが :-P
# その辺は費用対効果のトレードオフですね。

で。考慮した実装の場合
引用:

is_true() で正しい値を返せるフェーズまで進んでいない場合、is_true() が例外を投げないといけないことになりませんか?


については「ならないようにする」です。
まぁis**なので、returnはbooleanイメージなのですが。
私がよくやる実装は
・常にfalseを返す
です。
そうすると、問題のあるコードを書いたPGが大抵
「がるさん、あなたの作ったクラス、is系のメソッドが全部常に
 falseしか返してくれないんです」
とかいうので大体想像が付きます :-P

引用:

環境やスタンスの違いではなく、単純にあなたの提示したコードのメリットが分からないのです。どのあたりが、二値表現の拡張を想定している汎用性の高いコードなのですか?


では改修パターンを。
ステータスに「ちょっとまて(wait)」が混入したとします。

コード:
  // インスタンス生成
  credit_auth cobj = new credit_auth;

  // 適当なパラメタの設定
  cobj.set(ほげほげ);

  // チェック
  // XXX 異常が発生したらthrow
  cobj.check();

  // 判断
  if (cobj.is_true()) {
    // 承認OK
  } else
  if (cobj.is_wait()) {
    // ちょっとまて
  } else {
    // 承認NG
  }

  以下、処理は続くよどこまでも


こんな感じです。無論クラスメソッドがひとつ追加はされて
ますが、工数的には小さいものでしょう。
これですと、diffかけても「3行追加されただけ」なのがすぐに
わかるので、ソースバージョン管理とかやっていても結構
楽です。
# 修正行数多いとやっぱり不安になるんですよねぇ。
# 過去の経験と照らし合わせると特に(苦笑

ついでに「あぶなそうなPGに渡す場合用サンプル」は
コード:
  // インスタンス生成
  credit_auth cobj = new credit_auth;

  // 適当なパラメタの設定
  cobj.set(ほげほげ);

  // チェック
  // XXX 異常が発生したらthrow
  cobj.check();

  // 判断
  if (cobj.is_true()) {
    // 承認OK
  } else
  if (cobj.is_wait()) {
    // ちょっとまて
  } else
  if (cobj.is_false()) {
    // 承認NG
  } else {
    // ありえないしここに入るのは
  }

  以下、処理は続くよどこまでも


というコードにしておきます。
「ありえない場所」に入るのは、クラスの実装にミスがない
限りにおいて「例外を握りつぶしているケース」くらい
なので。
PGが「ifでここにばっかり入ってきて困る」とか騒ぐと
やはり「例外握りつぶしている」いい証拠になるです :-P

さて。同様のことを「return がboolean値の場合」に
置き換えて想定してみてください。
もちろん「違わないジャン」という感想もアリだとは
思います。
ただ、私は「メソッドの戻り値が変わる」よりは「メソッド
がひとつ増える」ほうが、システム全体への影響が少ない
だろうと感じているだけなので。

以下、余談ですが。
引用:

てっきり「想定の範囲内です!」と答えると思ったのですが。


いやぁそんなもったいない(笑
お金を巻き上げ…もとい、頂戴できる大切なチャンスじゃないですか(笑
フリーでやってるとそのあたりはまぁ「シビア」になります。
# いや本当は会社員でもシビアになるべきなんでしょうが。

実際には想定の範囲内なんですがね、大抵の場合。
# 戻り値が二値から三値以上になるってのも含め。
# 本気で想定外の仕変は…受けるけど、寿命が削れる思いがします :-P
小僧
大ベテラン
会議室デビュー日: 2005/06/24
投稿数: 122
投稿日時: 2005-11-09 14:44
こんにちは。

つまらない横槍で申し訳ないのですが、いつも疑問に思っていたので
質問させてください。

ここで話題になっているコードは「Java」だと思うのですが、
これが VB とか C の場合ってどうなるのかなぁ、と思い。
VB とかだと ( クラス使っていないと ) 戻り値ステータスを増やすだけなので、
結局それをコールしている箇所全部を見直ししないといけないのかなぁ、と。

気が向きましたらお返事下さいませ。
宜しくお願いいたします。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-11-09 14:57
引用:

小僧さんの書き込み (2005-11-09 14:44) より:

これが VB とか C の場合ってどうなるのかなぁ、と思い。
VB とかだと ( クラス使っていないと )


この時点で、前提条件がフェアじゃないので比較対象から外れませんか?
では、逆に「C#, Java とかだと (クラス使っていないと)」の状態で実装してみてください。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
がるがる
ぬし
会議室デビュー日: 2002/04/12
投稿数: 873
投稿日時: 2005-11-09 14:59
がるでふ。
ちとVBは不得手なのでCの場合の話なのですが。

…こういう類の修正で何度も地獄をみました(血涙
なので、例外処理とかオブジェクト指向とかってモノを
見た瞬間、それこそ「神様が与えてくれた福音」くらいに
感じたモノです(笑

ただ、その後C言語で
・1ファイル1クラス
チックな書き方を覚えてしまってからは随分と楽に
なりましたが。
# 「C言語でオブジェクトライク」な書き方してました(笑

ただ、やはり例外処理&クラスってのは仕様変更に
対して便利であるということは、例外処理がなかったり
クラス実装が困難な言語ってのは比較した場合において
「面倒である」んだろうなぁ、と。

かくして、私が知っている狭い範囲では
引用:

小僧さんの書き込み (2005-11-09 14:44) より:
VB とかだと ( クラス使っていないと ) 戻り値ステータスを増やすだけなので、
結局それをコールしている箇所全部を見直ししないといけないのかなぁ、と。


いう風になるのではないかと思います。

C言語の方には
・ファイル的にstaticとか使いまくってオブジェクト的実装頑張れ
といいますが。
VBの熟練者の皆様、なにかよい知恵などありますでしょうか?
# ちょいと興味あったり。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-11-09 15:01
まったく何が違うのか理解できません。

引用:
私がよくやる実装は・常にfalseを返すです。


これは、もっとも汚い実装のひとつではないでしょうか。認証の例に当てはめた場合、正しいユーザー名・パスワードを入力した場合にも is_true() が例外を投げずに false を返す可能性があるということですね。

引用:
ステータスに「ちょっとまて(wait)」が混入したとします。


コード:
if (cobj.is_true()) {
 // 承認OK
} else
 if (cobj.is_wait()) {
  // ちょっとまて
 } else {
  // 承認NG
 }
}


このコードおかしくないですか? is_wait() は is_ture() が false を返したときだけチェックされています。つまり「ちょっとまて」とは「承認されてない」に分類されていて「承認されていない」理由が「否認」なのか「未決」なのか詳細理由をチェックしているだけですね。

これを第3の値とは、お粗末じゃないですか? 上位分類が「承認されているか否か」という二値表現である点は変更されていませんよね。これなら

if(check()) {
  //承認OK
} else {
  //承認NG
  switch(reason()) { //承認されなかった理由の確認(Optional)
    ちょっとまて:
    default:
  }
}

と書くのと同じでしょう。成否の二値表現が三値以上に拡張された例としては説得力があるとは言えません。

コード:
if (cobj.is_true()) {
    // 承認OK
  } else if (cobj.is_wait()) {
    // ちょっとまて
  } else if (cobj.is_false()) {
    // 承認NG
  } else {
    // ありえないしここに入るのは
  }


引用:

PGが「ifでここにばっかり入ってきて困る」とか騒ぐとやはり「例外握りつぶしている」いい証拠になるです :-P


え? 私にはとても信じられない実装なのですが・・・。例外を握りつぶすと

  cobj.is_true() == cobj.is_false()

これが成りなってしまう可能性があるということですか? 明らかに内部状態の不整合のアラワレだと思います。無理に例外を投げずに false にしてしまう、なんてことをするから、こういった論理破綻した等式が成り立ってしまうのでは?

あなたのいう第3の値が、第1、第2 の値と同等のものではなく、いずれかの子(詳細ステータス)ということであれば、大した変更じゃないですね。その程度なら、設計段階で想定していなくても比較的容易に拡張可能な変更だと思います。

私の想像していた第3の値とは、かけ離れていましたね。

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