- PR -

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

投稿者投稿内容
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-11-10 15:42
コード:
if (cobj.is_true()) {
  // 承認OK
} else if  (cobj.is_true() = false ) {
  // 承認NG
} else {
  // 通常ありえない
}



コード:
bool bflg_is_true = cobj.is_true()
if (true == bflg_is_true) {
  // 承認OK
} else if (false == bflg_is_true) {
  // 承認NG
} else {
  // 通常ありえない
}



おまえら・・・。本当にバカだな。「通常ありえない」って何ですか。最後の else 節には絶対に到達できないですよ。物理的に。どんなに論理設計を間違ったとしても。(is_true() が副作用を持っていて呼び出しのたびに返す値が変わるということであれば前者のコードはかろうじて最後の else 節に落ちる可能性があるけど、がるがるの変数に状態を格納するコードでは絶対に最後の else 節に到達できない。)

到達できない else 節をオマケのようにくっ付けて、三値以上に拡張された場合を考慮しているかのように見せかけているけど・・・。その else 節に到達することは絶対にないんですよ。つまり、if() { ... } else { ... } という二値しか考慮していない分岐と完全に等価なんです。これのどこが拡張性を考慮していると言えるの?

本当に拡張を考慮しているのなら、はじめから is_false() を使っているはず。この指摘に対する説明・釈明はまだですか? がるがるさんは、私が質問・確認をしていないというけれど、私の指摘している問題について、がるがるさんは何も回答していないじゃないですか? がるがるさんが回答しない状況下で何を一方的に確認しろなどと偉そうなことを言っているのでしょうか。

念押し。ここは Java の会議室ですから bool は boolean と読み替えました。そしてこの型は true/false いずれかの値しか格納できない変数です。がるがるさんの場合は、C 言語のつもりで書いてました、とか言い訳しそうですから、さらにクギをさしておきますけど・・・typedef bool int など bool 型を作成しておいて、実際は int 型なので 2 や 3 も格納できるから bool 型に第3の値も格納できる、有効活用しようなんてコードだとしたら、ぶっとばしますよ。
小僧
大ベテラン
会議室デビュー日: 2005/06/24
投稿数: 122
投稿日時: 2005-11-10 16:50
こんにちは。

※ 相変わらず前提の確認なのですが。。。
皆様が前提としているソースはこれで宜しいでしょうか?

コード:
  // チェック
  cobj.check();

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



そして、 ( 私の前提条件として ) is_true のメソッド戻り値の値の意味は
・true ・・・ 認証 OK
・false ・・・ 認証 OK 以外
となります。

んで、この時に
・「臨時認証」というステータスを追加したい
という仕様変更が発生しました、と。

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

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


と提案しました。
つまり、
・is_true が false で
・かつ is_wait ( これが臨時承認の結果判定、戻り値は is_true と同様 ) が false
の場合、「承認 NG」とする、とコードで対応してはどうでしょうか?という内容です。

で、未記入さんが提示された私のソースは
・「is_true の戻り値 ( 承認 OK の戻り値 ) が false の場合に
承認 NG という事を保証する、という意味のソースであれば」
という意味で提示しました。
ので、私が本来提示したかったソースではありません。

まとめると
・is_true は変更しない
・臨時承認用メソッド ( is_wait ) を新に作成する
・当該メソッドをコールしている箇所全ては修正必要 ( これはどのパターンでも発生すると思いますけど )
・基本的にコールしている方で吸収
という事を最初から言い続けたつもりです。

「通常ありえない」って何ですか。
ありえないので記述しなくて良かったのですが、コピー元 ( どれだか忘れましたが ) に
書いてあったのと、例としているのであった方が分かりやすいかな、と思い
記述しました。
返って理解しにくいソースで申し訳ありませんでした。

拡張された場合を考慮して云々、というのは必要でしょうが、
関わるプロジェクトの全てに新規参加出来るわけではなかったり、
修正だってプロジェクトの文化や工数などの兼ね合いも出てくるのが現実だと思います。
( それを言ったら「Case By Case」で終るんですけど )
そういった事を考えた所、私のような対応でもいいのでは無いでしょうか?という意味で
投稿したのですが、どうでしょうか?

本当に拡張を考慮しているのなら
それなら、私は最初から boolean ではなく ( 多分 ) int で
・0・・・承認 OK
・1・・・承認 NG
としておきます。
んで、コードは
コード:
  // チェック
  cobj.check();

  // 判断
  if (cobj.is_true() == 0) {
    // 承認OK
  } else if ( cobj.is_true() == 1) {
    // 承認NG
  } else {
    // is_true にミスが無ければここにはこない
  }


( 懲りずに else を書きましたが )
となります。

書いててなんとなく気がついたのですが、どうも前提条件が違うようなので
( 未記入さんは「最初の設計から〜」という状況を想定しているようですが、
私は「プロジェクトに途中参加して、このソースを見せられて「仕様変更発生したので対応宜しく」と
言われた状態を想定しています )
今後続けても平行線かな、と思います。

と、いう事で一応これでやめたいと思います。
長文、失礼しました。
ここまで読んでいただいて多謝、多謝。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-11-10 17:17
引用:

・is_true が false で
・かつ is_wait ( これが臨時承認の結果判定、戻り値は is_true と同様 ) が false の場合、「承認 NG」とする、とコードで対応してはどうでしょうか?という内容です。



「臨時承認」追加後は (省略) is_wait() が false の場合「承認 NG」とするって本当ですか? 確定仕様ということでよろしいんですか? 私には、とても信用できないんですけど。たとえば、さらに「代理承認」が追加されたらどうなるんですか? is_fuga() で判定、is_wait() が false を返しても「承認 NG」とは限らない、と仕様を変更するのではありませんか?

もし「臨時承認」追加時に、is_true() == false && is_wait() == false の場合「承認 NG」とする、という考え方をする人であれば、初期設計でも is_true() == false の場合「承認 NG」とするように思えます。この一貫性のなさについて何らかの説明ができますか?

引用:

ありえないので記述しなくて良かったのですが、コピー元 ( どれだか忘れましたが ) に
書いてあった


本当ですか? 私はそのような物理的に不到達になるコードを見た覚えがありません。重要なことですので、忘れたなどといわずに思い出して提示していただけませんか?

if(is_true()) {
  ...
} else if(is_false()) {
  ...
} else {
  ...
}

このコードと混同しているなんてことはないですよね?

引用:
拡張された場合を考慮して云々、というのは必要でしょうが、関わるプロジェクトの全てに新規参加出来るわけではなかったり、修正だってプロジェクトの文化や工数などの兼ね合いも出てくるのが現実だと思います。


私は、がるがるさんが拡張を考慮してコードを書いていると言うので、どんなものかと聞いてみたのです。出てきたコードを見る限りは拡張に強いわけでもないし、建て増しによる弊害しかないように思えました。さらに二値が三値に拡張されているようにすら見えません。その点を指摘しただけです。

私自身のスタンスとしては、はじめから拡張を考慮するのが必ずしも良いとは言えない、と述べていますし。

引用:

本当に拡張を考慮しているのなら
それなら、私は最初から boolean ではなく ( 多分 ) int で


みっつ以上の値になることが十分に想定されるのであれば、これは、良い方法のひとつだと私も思います。ただ、がるがるさんは boolean を使っていながら拡張を考慮していると言っています。また、私は 成否・有無の二値が拡張されることなど、よほどのことがない限り考えられない(事前に考慮するようなことじゃない)、と述べています。

引用:

( 懲りずに else を書きましたが )


意味が分かりませんが、今回提示されたコードでは最後の else 節に到達する可能性が十分にありますよ。前回のコードとは明らかに質が違うので「懲りずに」というのは不適当だと思います。
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2005-11-10 17:40
intなら、クラスに定数作りたいですね〜というのは関係ないとして。

true/falseで返すものを拡張するとしたら、通常のOKでも臨時でもtrueを返すようにして、別途OKの種類を示すフィールドとそのgetterを作る、というのも…。
修正範囲外で使われる場合に、今までNGだったものがOKにならないように、しないといけませんけどね。
がるがる
ぬし
会議室デビュー日: 2002/04/12
投稿数: 873
投稿日時: 2005-11-10 17:41
がるです。
少し補足というかなんというか。

引用:

小僧さんの書き込み (2005-11-10 16:50) より:
本当に拡張を考慮しているのなら
それなら、私は最初から boolean ではなく ( 多分 ) int で
・0・・・承認 OK
・1・・・承認 NG
としておきます。


ん〜。大本の、私のイメージしていたクラス(の一部)を
書いてみます。

# ちとしばらく頭がC++なので一部Javaっぽくない表記ですが ^^;
コード:
typedef enum status { _HOGE, _FOO, _UNKNOWN };
class XXX {
protected status status_;

//
public void XXX { this->set_status(_UNKNOWN); }

//
public status get_status(void) { return this->status_; }

//
public void set_status(status s) { this->status_ = s; }
public void set_status_hoge(void) { this->set_status(_HOGE); }
public void set_status_foo(void) { this->set_status(_FOO); }

//
public bool is_hoge(void) { return this->_is(_HOGE); }
public bool is_foo(void) { return this->_is(_FOO); }

//
public bool _is(status s)
{
  if (this->get_status() == s) {
    return true;
  }
  return false;
}

// 結果をset_statusで設定する
public void check(void) {}
}


つまり、is系はそれぞれbooleanですが、内部的には
ステータスはintとかでもつです(実際は上述のようにint
よりもenumのほうが好きですが−その言語に存在してれば−)。
なので、拡張性がないわけではないつもりなのですが。

一応、上述に拡張をかましてみます。
ステータスBARです。
クラスは継承可能ですが、enum宣言は書き換えざるを得ないですね。
# C++でenumの継承とかあると楽なのに(笑

コード:
typedef enum status { _HOGE, _FOO, _BAR, _UNKNOWN };
class XXX_2 : public XXX {

public void set_status_bar(void) { this->set_status(_BAR); }
public bool is_bar(void) { return this->_is(_BAR); }
}


いやまぁ「継承するのか元クラス書き換えるのか」は状況次第
だと思われるのですが。
今回は楽しようとしてます(笑
# あんまり長文にしても、って頭も少しありますし。

というわけで。当初からこのイメージでずっと話をしている
のですが、このやり方なら拡張性も普通に確保できるのでは
ないかと思うんですがどうでしょう?

ちなみにget_statusは一応publicしてますが、本音からいうと
protectedにしたいところです。
ステータスの生の値をとってあまつさえSwitchで、ってやり方
をソースのあちこちに散らかされると本気でメンテナンスが
大変になるので。

そのあたり、クラスの作りもそうですけど全体のつくりとか
設計とかってのも重要ですよね。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-11-10 18:51
いい加減にしてくれよ・・・。C++ で書き換えれば、ごまかせるとでも思ったんですか?

コード:
typedef enum status { _HOGE, _FOO, _UNKNOWN };


・・・これ二値じゃなくて三値でしょ。明らかに。成否・有無などの真偽値ではなく、初期想定ステータスが 2つなら、私も上記のように _UNKNOWN という予防線を張ることがあると思います。

ただし、その場合は実際の利用ケースが以下のようになります。

コード:
if(is_hoge()) {
    ...
} else if(is_foo()) {
    ...
} else {
    ...// unknown
}


何度も言ってますけど、がるがるさんの提示したコードは、この形になっていませんでしたよね? if() { ... } else { ... } と書いてたんですから。これでは、_FOO と _UNKNOWN が同じフローに流れてしまうんです。それで、本当に拡張を考慮していたと言えますか? 「_UNKNOWN になるケースなんて今のところ分からないから、_HOGE じゃなかったら _FOO でいいや」と考えたとしか思えないコードなんです。提示されたコードは。

もう何度も同じことを申し上げて・・・。疲れてしまいました。ホントは分かっていて認めたくないから逃げ切ろうとしているんでしょう?

それから。某所で、がるがるさんがオブジェクト指向言語を(とくにポリモフィズムについて)理解できていないということが発覚していますが、得意げに C++ のこと語っていて大丈夫ですか? ぼろを出すんじゃないかと私とても心配です。深い話ができずに、キーワードをチラ見せするだけのがるがるさんなら大丈夫かも知れませんが。老婆心でした。
ブンデス
常連さん
会議室デビュー日: 2005/10/14
投稿数: 22
投稿日時: 2005-11-10 19:19
がるがるよ、
いい加減に自分の負けを認めろよ。

お前の理論はすでに破綻してるだろーが。
それを他の言語にすりかえたりして
逃げ切ろうとしてるが、本当に見てられないぞ。

ちなみに、お前はオーバーロードとオーバーライドの
区別が出来ていないみたいだな。
仕事中にこんなくだらない書込みするより、
他にやるべきことがあるんじゃないか?

以上、老婆心より俺からのアドバイスだ。
はらだいち
会議室デビュー日: 2005/08/30
投稿数: 11
投稿日時: 2005-11-10 19:43
引用:

ブンデスさんの書き込み (2005-11-10 19:19) より:
がるがるよ、
いい加減に自分の負けを認めろよ。

お前の理論はすでに破綻してるだろーが。
それを他の言語にすりかえたりして
逃げ切ろうとしてるが、本当に見てられないぞ。

ちなみに、お前はオーバーロードとオーバーライドの
区別が出来ていないみたいだな。
仕事中にこんなくだらない書込みするより、
他にやるべきことがあるんじゃないか?

以上、老婆心より俺からのアドバイスだ。



煽ることしか能のないお前には言われたくないだろ(プ
ところで宿題は終わったのか?(ワラ

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