Nm

目次

Blog 利用状況

書庫

日記カテゴリ

ダックテストを考える3 オブジェクトの正当性

もう一度ダックテストでいきます

用語の説明は次のものです
ある鳥が鴨のように見え、鴨のように泳ぎ、鴨のように鳴くならば、それはたぶん鴨である。

 

この例では、鳥を見ている人が、"鴨のように泳ぐことができる"、"鴨のように鳴くことができる"
という少なくとも2つ以上の条件が同時に成立することを定義としていることがわかります

複数の条件が同時に成立するかどうかを判定することは、多分原理的?(もしくは計測的?現実的?)に不可能です。
同時に観測することが不可能である点と、同時に判定することが不可能であるという点において。

これを解決する方法は今のところ一つしか思いつきません
ある条件を確認した後、その結果がある期間において変化しないと決め付けてしまうという方法です。
こうすれば、どれだけ条件がたくさんあっても、ある期間内であれば判定が可能になります

期間は、時間つまりタイムアウト付きとしてもいいし、何かのトリガーで寿命としてもいいですね

 

そういったものを何というかというと ・・ 要は変数/状態です
複数の条件を同時に満たすことが求められる時、変数が必要になります
条件は全て、満たすか満たさないかの2値、つまりbool変数として表すことができます

オブジェクトの条件、ダックテストで使用した
XXができることを条件とする、もしくはXXができないことを条件とする、
といった条件もbool値とその評価の組み合わせとしてとれます

オブジェクトが正しい状態というのがどういう状態かというのを表明できます
オブジェクトは正しい状態と正しくない状態の2値、つまりbool値となれるので、
オブジェクトが他のオブジェクトの条件の一つとなることも可能になります

 

総括すると、ダックテストはある種の状態制御を含む概念である、ということです
オブジェクトの正当性とはつまり状態の値かつ定義です。
正しい状態の値(の範囲)を定義に含むことをサポートしなければいけません

 

 

状態の値を含んだ定義というのは実に普通のことです

ある会社の採用条件として、TOEIC600点以上の人が必要だとしましょう
ダックタイピングでは"TOEICの点を持つかもしれない人"程度の定義でしか表現できません
ダックテストでは"TOEIC600点以上を持つ人"という状態の値を含んだ定義が使えます

状態の値を含んだ定義の例はいくらでもあげることができます
元気な犬/病気の犬 (健康というパラメータの値)
黒色のもの/灰色のもの (明度という状態の値)
きれいな机/汚い机 (整頓度?)

例えばあなたは、"きれいな机"を見つけることができます
"机"をみつけてきれいかどうかを見るのではなく、"きれいな机"を直接見つけられるはずです
それはあなたが、あなたの頭の中で状態の値を含んだ定義を作成できるからです

 

状態の値を定義に含むことを、人間(の認知)はサポートしています
抽象化もサポートしています
ダックテストもサポートしています
実はソフトウエア(=実行ファイル=プログラム)もサポートしています

それらから作られたはずの、今のオブジェクト指向プログラミング(の解説)と今のダックタイピングはサポートしていません
これは問題であり、状態の値を定義に含むことをサポートすべきだと私は考えます

投稿日時 : 2009年1月20日 1:42

コメントを追加

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/20 3:54 ゆーち

ダックタイピングってのとオブジェクトの状態ってのは別次元な気がします。

オブジェクトの状態は bool では表せません。
あるファイルがオープン状態であるのかそうでないのかは、bool で判断できるかもしれませんが、ファイルが書き込み中なのかどうかは、オープン状態かどうかと密接に関わります。(その時点でboolではなくなるという話ね)

「状態の値を定義に含む」というのは、他の利用する側に関係のないクラスローカルな範疇で実装されるのがよりよい形だと思います。

何度も書きますが、抽象化オブジェクトの主体性を、それを扱う側に持たせるべきではありません。
そうすると、メインのロジック(あるふさんの言われる実行ファイル)がすべてのオブジェクトの制御に対して責任を持たなくなってしまい、ある程度以上の規模のソフトウェア開発では泥沼のプロジェクトになってしまいますよ。

抽象化されたクラスは、他のクラスに関係なく独立して、正常に動くことをテストされた上で提供されるべきで、扱う人(あるふさんの言われる実行ファイル)の振る舞いとは関係のない再利用可能なものであることが、より望まれる形だと言われています。

歴史的には短いながらも技術の進歩によって生まれてきたソフトウェア工学の用語を、間違った方向で説明されているからこそ、数多くのひとからの指摘があるのに、それを受け入れようともしないで展開していく姿勢を貫こうとされるのは良いことだとは思えません。

blogは配信を基本とするメディアです。
これから知識を仕入れようとする人にとって間違った情報や混乱する情報の配信は、読む人にとって不利益だと思います。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/20 3:56 ゆーち

自分の間違い修正(^^;
>すべてのオブジェクトの制御に対して責任を持たなくなってしまい、

すべてのオブジェクトの制御に対して責任を持たなければならなくなってしまい、

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/20 11:09 επιστημη

> "鴨のように泳ぐことができる"、"鴨のように鳴くことができる"
> という少なくとも2つ以上の条件が同時に成立することを定義としていることがわかります

...そう?

この二つの条件が"如何なるときも成立する"のを要請しているのであり、
"同時に成立する"より厳しいんじゃないかしら。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/20 14:02 インドリ

あるふさん、何度も注意していますが、自分独自の概念の場合は先に宣言しておくと皆好意的にコメントを書いてくれると思います。
もしくは、自分が足りないと思っている既存技術の部分を説明するとか・・・
ソフトウェア工学の用語を勝手に上書きするのはやっぱり駄目ですよ。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/20 23:24 Jitta

> 必ずしも実際にチェックする"必要は"ありません
最初に書いてよ。。。全部チェックする気でいるんだと思ってたよ。

> チェックすることは可能でなければいけませんが、(あるプロジェクトにおいて)
(あらゆるオブジェクトが)チェックすることが可能で‘なければならない’とは、思いません。
必要があるものについては、必要に応じて付いていればいいと思います。
オブジェクト志向設計では、オブジェクト間のつながりは粗である方がよいとされています。もし、戻り値について判断する責任を持つなら、つながりが密になります。

> >「本当に鴨オブジェクトなの?」とチェックする“必要がある”ということでしょうか?
> 「本当に"正しい"鴨オブジェクトなの?」もしくは、「本当に鴨なの?」ですね
「本当に鴨オブジェクトなの?」と「本当に鴨なの?」は、何が違うのでしょう?

> とりあえず当面は主体をソフトウエア固定としてください。最も簡単なので
> 主体をソフトウエアとした時が理解できないうちに、オブジェクトを主体としたものが理解できるとは思えません
> なぜ開発者ではなくソフトウエアを主体とするのかは、今回のインドリさんへのレスを参照してください

> 開発者の思う"鴨の定義"と、システムの考える"鴨の定義"が違っていた時、システムが信じるのは何でしょうか
> 「プログラムは思った通りには動かない。作った通りに動く。」の格言どおり、システムの考える"鴨の定義"ですね。
> では、問題領域にとって、重要なのは、開発者の思う"鴨の定義"と、システムの考える"鴨の定義"でしょうか。
> 実際に問題領域と通信するのはシステムなので、重要なのはシステムの考える"鴨の定義"です。
> そして、最も重要な存在であるシステムを主体にとれば、開発者は第三者にすぎません。
意味がわかりません。コードを書くときは、開発者が思うように動くことを目的として書きます。ソフトウェアの動作が開発者の思惑と違うなら、それは通常、バグといわれます。バグは修正され、ソフトウェアは開発者が思うとおりに動くように修正されます。そのように修正されるなら、いずれプログラムは思った通りに動くようになるでしょう。「思った通りに動くようになる」ことをもって「ソフトウェアと開発者は同じである」といって差し支えないでしょう。

> ただ、皆さんインスタンスをオブジェクトとして捉えていることがわかりました。
> では、実行ファイルの外にあるもの、つまりこの例では犬やファイルやユーザはどういったものなんでしょうか
> 「私=実行ファイル」から見てクラスのインスタンスと同等のものという意味での"オブジェクト"なんでしょうか
むっはー!ここか。。。(『オブジェクト指向 01 定義』のコメント 2008/12/13 21:00)
すなわち、「オブジェクト志向ナントカ」の定義の根本からずれている、と。

オブジェクト志向ナントカの本は、数冊読みましたが、どれもインスタンスをオブジェクトとしています。「違うものである」と解説しているものがあるなら、それはなんなのか、提示してください。
定義が根本から外れるのであれば、「オブジェクト」「クラス」「インスタンス」の定義を示してください。エントリ『オブジェクト指向02 定義2』では、十分に伝わっていません。『オブジェクト指向理論?03 インスタンスとリソース』の時点でも、まだ誰もあるふさんの定義するオブジェクトに納得していないと思います。私は、納得できていません。(だから『無効をサポートするオブジェクト』で「書き手と読み手が共通の理解を持っていません。」「(「オブジェクト指向」という)用語について、共通の理解をすることを、まず第一としてください。」って、書いたんだけどなぁ。)


> オブジェクト指向プログラミングの適用範囲は以外に狭くて(この例では)実行ファイルの中だけであることと、
> 一般用語のモノとオブジェクト指向用語のオブジェクトは別物であり、混同してはいけないということを示しているだけで、
> 別段変ではない、はずです。
変です。
「プログラミング」の範囲は実行ファイルの中だけですが、分析、設計する段階では、「システムに関わるもの全て」が、オブジェクトとして志向される対象です。その中で、プログラムの中に封じ込める必要があるものだけを選りすぐり、システムとして必要なことだけを十分に表現して行えるように洗練し、プログラムとして表現できるように抽象化し、コードとして表現されます。
オブジェクト志向分析の段階では、「一般用語のモノ」と「オブジェクト志向用語(んなものはないけど)のオブジェクト」は同じです。分析から設計に進む段階で、システムを構成するために不要なこと、例えば「ユーザー」であれば人としては必要な「ものを食べる」とか「考える」とかは不要なわけです、不要なことを切り捨てて、システムが要求する「ユーザー」となるように構成されます。
というステップを考えると、分析や設計をすっ飛ばして、いきなりプログラミングから行おうとしている、と思われます。しかし、オブジェクト志向開発においては、分析こそ、必要不可欠だと思います。

 一番の原因は、現実世界をそのままコンピュータの中に再現しようとしていること、だと思います。なので、「現実をプログラミングしようとすると」、いわんとされていることは頷けることが多々あります。でもそれでは、コンピュータの中に落とし込むときに、不要なこと、実現できないことがたくさんあります。例えば、「ダックテストのためには、一般に言われているダックタイピングだけでは不十分」というところです。誰も、ダックテストを行おうとはしていません。「インターフェイスが一致すればその型であるとみなして良い」ということに名前を与えるために、「ダックテスト」を持ち出し、「ダックタイピング」という名前を与えています。
 『オブジェクト指向理論?03 インスタンスとリソース』のコメント 2008/12/18 23:24 で、あるふさん自身が「この考えなら、現代オブジェクト指向プログラミングでも矛盾しないし、一般的なオブジェクト指向の解説とも矛盾しないし、何より自説とぴったり合います。」と書かれています。自説と一般的な「オブジェクト志向ナントカ」に隔たりがあるとお考えなら、自説に別の名前を与えてください。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/21 0:47 ちゃっぴ

既存の programming 概念というかいろいろ影響を受ける仕様にはそぐわないけど、そうなるように改変すべきだという意見でいいですよね?

いろいろあるけど、それならば言語設計しろとは言いませんけど、説得力のある具体例の提示をしてほしいものです。
とりあえず、この説明では説得力のある具体例にもなっていません。

抽象的な概念がそうだからといって、現実に落とし込むときにそれが丸々当てはまるわけではありません。
現実の問題を扱うためには多くの factor を詳細に吟味し、最適なものを選択する必要がありますから。
とりあえず、ここら辺は理解してください。

> ある条件を確認した後、その結果がある期間において変化しないと決め付けてしまうという方法です。
> こうすれば、どれだけ条件がたくさんあっても、ある期間内であれば判定が可能になります。

ごく限られた範囲では物事を単純化する有効な手法です。
ただし、例外を全く許さない環境では絶対にやってはいけないことです。
Programming においては後者が優先されることが圧倒的に多いです。

基本的に外的要因に影響を受けるものについてはこの概念は絶対に利用してはいけません。

実際に外的要因の影響を受けるものとしては file sytem とか network を介した通信とか、multi thread で扱われるものとか数多く存在しますね。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/22 13:12 インドリ

かなり気まずい雰囲気で、あるふさんが精神的に追い込まれそうなんでフレンドリに書きます。
※みんな手加減してあげて!
あるふさんの記事の書き方が、「オブジェクト設計者が単体テストも記述する契約指向で行こう!」であるならば、こんなにコメントが炎上する事は無いと思うピヨ。
その考えならばD言語で徹底されており、言語設計者がライブラリ実装者にも「契約を書け」と注意を促しているぐらいなんだ。
あくまでも単体テストならばテスト完備はいいんだけど、あるふさんの記述がオブジェクト指向全体にいきわたり、結合テストや総合テストまで考えが広がっているように見えるから、読み手にあまりいい印象を与えないと思うんだ。
ここは一つ勇気を出して仕切りなおして、「自分はこう考えています」とオブジェクト指向とは切り離して書いたらいいと思うピヨ。
このままオブジェクト指向で解説を続けてもいい結果を生まないと思うピヨ。
何故かと言うと、あくまでもオブジェクト指向で行くのならば、みんながコメントで指摘している事は正しいから無理があるよね。
ここは勇気を出して仕切りなおそう♪

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/23 12:15 Jitta

> 「オブジェクト設計者が単体テストも記述する契約指向で行こう!」であるならば、こんなにコメントが炎上する事は無いと思うピヨ。
え?単体テストじゃないですよ?「ダックテスト」って書いてあるじゃないですか。
つまり、実行時に型を特定しようとしているわけで、その型の特定を、メソッドを実行させた結果で行おうとしている。
これって、とてもリスキーですよ。型を特定するためのメソッドの選定と、そのメソッドが何をするか、ってところをキチンと抑えておかないと、例えば「コピーできればファイル」なんてやっちゃうと、コピーしてしまってから「コピーできるからファイルだ。じゃぁ、コピーしよう」なんてことになってしまいます。これは、単体テストなんてモンじゃないです。

つーか、最初に SelfTest とかってあったから、それの延長だと考えていた、とか?だったら私も一緒。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/23 15:11 インドリ

>え?単体テストじゃないですよ?「ダックテスト」って書いてあるじゃないですか。

うん。余りにリスキーなんで、ボクとしては単体テストぐらいにしておいて欲しいなという気持ちをこめて書きました。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/23 15:36 επιστημη

いやだから型の同定でしょ?
単体テストとは異質だって。
言い訳になってねぇ > インドリたん

<ヨタ>
これは消火器だろうか? ってグリップ握ってぶしゅーと泡出て、
確かに消火器だとわかった途端に消火器として使い物にならんくなるですねー。
</ヨタ>

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/23 15:39 επιστημη

ついでにDbCも型の同定とは関係なさげ。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/23 19:25 インドリ

ボクはあるふさんが、SelfTestを言いたくてこんな記事を書いたのかな?と思ったんだ。
だけど、違うかもしれない・・・
うーん、どうしよう。本当に困った。
もし本気ならば茨の道だけど次の点を書こう♪


1、型の同定を判定する環境を別途用意する必要があると思う。そうしないと静的言語はテストできないよね?その点をどうするのか説明しよう。

2、あるふさんが言っている方法は、オブジェクトの再利用性を損なうからそれでも利点がある事を説明するべき。というのも、人間の認知を型に含めるのならば人(プロジェクト)が変ったら再利用できないよね?

3、オブジェクト指向ではカプセル化(区切り)が重要だから、どこで分けるのかを書くべき。今のままだと、状態もオブジェクトだという点が解決できないよね?
例えば・・・

>ダックテストでは"TOEIC600点以上を持つ人"という状態の値を含んだ定義が使えます

TOEICというオブジェクトの定義はどうするの?
600というオブジェクトの定義はどうするの?
以上という演算子メソッドはどうするの?
人オブジェクトはどうするの?

状態の値もオブジェクトだからね。


これら3点を説明すると説得力が増すかもしれない。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/26 2:11 あるふ

>>επιστημηさん
>型の同定
まさにこれ、ここでいいたかったのはこの概念に相当近いです。同定なんて用語があったんですね。
生物の分類学の説明が一番しっくりきます
分類するためには定義、つまり型が必要。型は当然状態の値をとることが可能。視点が違えば同じものをさしても型が違うこと(結果的に専門家の使う型と非専門家の使う型は異なる)

もう少し調べてみます

ヨタにだけ反応
私なら大抵"消火器の形"だけで消火器とみなしますが、
"消火器として使える"ことを消火器の制約とするなんて、επιστημηさんは変わってますね
本当に中身がはいってるかどうかわからないインチキ業者のものとか、捨てる予定の消火器を想定したのでしょうか

後のレスは少々お待ちください

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/26 2:13 あるふ

ここでちょっとアンケートをとりたいです

私の中では、各用語の階層図として大体次のように考えています
(A:抽象化)->(B)->(C:オブジェクト指向/ダックテスト)->(D)->(E:OOP概念/ダックタイピング/OO分析/OO設計)->(F)->(G:OOPを利用した実装)

今このブログでは、A~Cあたりをうろうろしていると私は思っているのですが、
もはや見ている人がどういうものを想定しているのかはちょっとわからなくなりつつあります

この階層図をそのまま使ってもいいし、()の数や中身を変えてもいいので、
どういう構造のどのあたりをこのブログが扱っていると思うのかを教えてもらえないでしょうか

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/26 11:20 ・・・

> 私なら大抵"消火器の形"だけで消火器とみなしますが、
> "消火器として使える"ことを消火器の制約とするなんて、επιστημηさんは変わってますね
> 本当に中身がはいってるかどうかわからないインチキ業者のものとか、捨てる予定の消火器を想定したのでしょうか

あなたの言うダックテストでは実際に「消火器として使えないと」消火器じゃないんでしょ?
えぴさんは当然の反応を返したまでです。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/27 10:21 επιστημη

> "消火器として使える"ことを消火器の制約とするなんて

まったくです。
"ちゃんと消せなきゃ消火器じゃない"
"ちゃんと点かなきゃマッチじゃない"
"ちゃんと飛べなきゃ鴨じゃない"
どれも同じにみえますね。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/27 18:12 Jitta on the way

エピさん、それは、ちょっと違いますわ。
「外観」を返すメソッドと、「火を消す」メソッドがある。エピさんは、「火を消すメソッドを実行し、それが成功なら消火器である」と、消火器を定義した。
あるふさんは、「外観を返すメソッドの戻り値が、既知の消火器と一致すれば消火器である」と、消火器を定義した。
どのメソッドでもって「ソレである」と定義するか、まず決めにゃならんのですわ。



で、普通は、「消火器」とラベルが貼ってあったり、使い方を読んで火を消せると納得すれば、消火器であると定義すると思うんよ。
たとえば、ここにボールがある。これを「消火器です」と説明されても、あるふさんは、消火器であると認めないのね。既知の消火器と一致しないから。他の人も、「火を消すメソッド」の有無が判らないから、認めない。そこで、次の説明がある。「天ぷら油火災の場合、このボールを天ぷら鍋に放り込んで下さい。中に入った消火剤が油を覆うことで新たな燃焼を防ぎ、消火します。」(マヨネーズ放り込めっちゅうのといっしょね)
この説明で、火を消すメソッドの有無が確認できた人は、ボールを消火器であると認識する。でも、あるふさんは、既知の消火器がメンテナンスされるまで、消火器と認めない。どうやってメンテナンスするんかわからんけどね。


こんな感じ。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/27 18:21 επιστημη

> それは、ちょっと違いますわ。

百も承知ですw

> メンテナンスされるまで、消火器と認めない。

となると非破壊検査可能でないかぎり認められんてーことすかね。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/27 19:13 Jitta on the way

そりゃ失礼しました!!

ん、非破壊検査つーか、SelfTest が型判定を兼ねる、みたいな?
class 消火器 {
 //確認用=SelfTest
 bool 消火器のように見える();
 bool 消せる(火);

 //本番用
 object 外観();
 bool 消す(火);
}

消火器によって、対応可能な火災原因や規模が異なりますから、「説明書で対応可能か確認する」みたいな?そんなメソッドを余分に設けるのかなぁ?とか思ったんだけど、どうなんだろう?

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/28 10:28 インドリ

あるふさんのアンケート
正直に言って、あるふさんはオブジェクト指向外を言っていると思っています。
みんなが指摘しているのは、この一連の記事がオブジェクト指向じゃないということだと思います。
もしテスト手法に拘りたいのならば、オブジェクト指向として解説するべきじゃないと思います。
抽象化しているのにもかかわらず、ダックテストでの明示的テストを求めるのはおかしいかと。
これが単体テストならば許容範囲内なのですが、それ以上の範囲事を求めているので、オブジェクト指向の利点を損なうまでになっています。
カプセル化の原則も無視していますし、細かな点で色々オブジェクト指向とは思えない記述が見受けられます。
やはりテスト手法に焦点を当てるのがよろしいかと思います。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/28 12:23 Jitta

> > メンテナンスされるまで、消火器と認めない。
>
> となると非破壊検査可能でないかぎり認められんてーことすかね。

あれ?「既知の消火器リストにボール型の消火器が追加されるまで、消火器と認められない。いつ、誰が、どうやって追加するのか、わからないけどね。」の方が良かったかな?

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/28 13:58 επιστημη

んー...いやね、あるふさんは「オブジェクトの正当性はインスタンスごとの状態が絡む」いうてはるんでしょ。
てことは、消火器リストにボール型油火災専用消火器が載ってるだけではダメで、「今現在ちゃんと消せる消火器」であるかをその消火器自身が保証せにゃならんです。
だもんで僕は"非破壊検査"と称したわけで。

でもねー、この自己テストは実行時に行われるわけよね。
ちゃんと消せる消火器か否かのテストにパスしない限り
消火器じゃないとなると:

目の前で天ぷら鍋が燃えている。とっさに手近にある「たぶん消火器だろうボール」に手を伸ばすが、テストボタンを押して青ランプが点かないとホルダーから抜き取れない。
ボタンを押して3分間の自己テストの後ホルダーから取り出し、その間にめらめらと燃え上がる鍋に向かって祈る思いで投げ込む...

んな悠長なことしてられっか。目の前で燃えてんだぞ。「消火器」って書いてあるからにはなんとかなんだろー、ひっつかんで天ぷら鍋に投げ込む。それで消えなかったら改めて別の手を考えるはず。

(オブジェクトごとの状態が絡むので)やってみなけりゃわからんのは自己テストも同じ(そでないと困る)なら、自己テスト結果を待たずにやってみてその結果を得るのと

「どこがちゃうねん!?」

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/28 14:51 インドリ

ボクずっと疑問だったんだけど、あるふさんの手法は結合テスト的だよね?
※本当は異次元だけど言い難いので結合と表現します。
インスタンスの状態値をチェックする場合、オブジェクト指向である限りは状態値もオブジェクトでなければならない。
だけど、そのオブジェクトも定義された状態値オブジェクトが保障されなければならない。
そんな事を繰り返していれば、循環参照ループ問題が発生すると思うんだ。
脳内プログラミングでコンパイラ作ってみたけど、これかなり致命的な問題だと思うな♪
仮想実行パスを追加すれば実装可能だけど、別にテストプログラム起動するほうがいいと思うんだ。
それに、結合部分を変えるたびにコンパイルしなおす必要があるし、オブジェクトが密結合してれば再利用性が無くなると思う。
あと、あるオブジェクトを修正した場合、使っている全てのオブジェクトでテスト条件をチェックするのは大変だし・・・
プログラムは第三正規化する必要があるよ。
やっぱり、テストファーストで結合テストプログラムを別に書いて、テストプログラムに任せるのが良いとボクは思うな♪
以上の理由でボクは、テスト自己記述オブジェクトを作成したい場合単体テストに止めたほうがいいと思います。

# re: ダックテストを考える3 オブジェクトの正当性 2009/01/29 1:46 あるふ

ちょっと今ゲームで廃人プレイしてるので来週まではまともにレスできません。すみません

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/04 21:32 Jitta

 あ~、そうか。今は「ちゃんと火が消せる消火器」が欲しいので、「ちゃんと火が消せる」ことを確認したら、「使い終わった消火器」になっちゃうよwww、と。
 私は「使用期限内であること」「消火器が対応した火災であること」「封が切れていないこと」を確認すればいいかなぁ?と思ったけど、これだと「おそらく消すことができるであろう消火器」であることはわかるけど、「ちゃんと火が消せる消火器」かどうかは、まだ不明だねぇ。内部の圧力が規定以上であること、消化剤が固まっていないことのチェックなども必要?
 また、火を消すためには「正しい使い方をする」ことも必要だけど、その外的な要因まで消火器がチェックしないと、ここで期待する「ちゃんと火が消せる」には該当しなくなりますねぇ(-_-; 難しいなぁ。。。


> ボクずっと疑問だったんだけど、あるふさんの手法は結合テスト的だよね?
 全然関係ないと思います。
 先の単体テストといい、今度の結合テストといい、「オブジェクトが特定の型に属し、かつ有効なことを、オブジェクト自身が保証しなければならない」ということと、「コードが開発者の意図通りに書かれていることを保証すること」と、どうして同じになるのでしょう?


> 私の中では、各用語の階層図として大体次のように考えています
> (A:抽象化)->(B)->(C:オブジェクト指向/ダックテスト)->(D)->(E:OOP概念/ダックタイピング/OO分析/OO設計)->(F)->(G:OOPを利用した実装)
何における、階層なんだろう?(用語は階層を形成したりしない)
B, D, F には、何が入るんだろう?(ホルダー?)
A と B では、どちらが階層の上なんだろう?
階層の上にあるということは、何を意味するんだろう?

ほら、認識がずれてる。


> 状態の値を定義に含むことを、人間(の認知)はサポートしています
> 抽象化もサポートしています
 状態は、抽象化によって削除します。
 「机」は、「きれいな机」も含む、様々な机を抽象化したものです。このとき「机」には、「作業可能な平面があること」程度しか定義されていないでしょう。四角形なのか円形なのか、三角形なのかも、まだ定義されていません。立って使う机なのか座って使う机なのかも、定義されていません。状態の値の定義は、抽象化はサポートしません。そいつをこそぎ落とすことが、抽象化です。

 この抽象化は、オブジェクトに注目することで、オブジェクトとして抽象化しています。プロセスに注目してプロセスとして抽象化するなら、別の結果が待っています。このことより、先の「(A:抽象化)->(B)->(C:オブジェクト指向)」という“階層”を付けることがおかしいと言えます。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/05 9:36 επιστημη

> ボクずっと疑問だったんだけど、あるふさんの手法は結合テスト的だよね?
> 全然関係ないと思います。

状態が絡むから型を同定するには動かさにゃならん。
さらにちゃんと動くかは外部要因にも絡むから結合動作させにゃならん。
つまり本番(と同等)の環境を用意して実際にスイッチ入れにゃならん。

...ってーことで結合テスト"的"てーことじゃないすかね。
その"目的"じゃなく"手段"に着目すれば結合テストみたいだな、と。

# いつも思うがインドリたんはロジックに"ほころび"が目立つぞ。
# 「補足しないとわかってもらえない」て意味で。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/06 0:55 あるふ


>>ゆーちさん
>ダックタイピングってのとオブジェクトの状態ってのは別次元な気がします。
もちろんダックタイピングと状態は別次元です
私と同じ認識ですね

ダックテストではサポートしていた状態の定義を、なぜダックタイピングでは削ってしまったのでしょうか?

>オブジェクトの状態は bool では表せません。
??よくわかりませんでした。
bool ファイルが書き込み中なのかどうか;として変数として置けますし、複数が必要であれば、
(A && B && C) とか、(A && B || C)のように、複数をまとめて一つのboolとして扱うことが可能ですよね?
これをするためには、正しい状態を知っていることが条件になりますが。


>>その他
私は"ダックテスト"と"ダックタイピング"を別概念としています
"ダックテスト"と"ダックタイピング"は別物であり、違いがあります
その上で、"ダックテスト"の方の考察をしています

ゆーちさんの指摘は、"ダックタイピング"のものであり、
"ダックタイピング"が("ダックテスト"=私の主張)と違うということですよね?

私もそれは正しいと思います
ただ指摘する意味があるとは思えないのですが。



>>επιστημηさん
>>> という少なくとも2つ以上の条件が同時に成立することを定義としていることがわかります
>>この二つの条件が"如何なるときも成立する"のを要請しているのであり、 "同時に成立する"より厳しいんじゃないかしら。
これは確かにミスでした。というか言葉が足りないです

素直に導ける定義は、(鴨である間は)2つ以上の条件が常に成り立っていなければいけない
ということで、επιστημηさんの言うとおりです。
点ではなく期間が条件であるという理由で、この時点で既に変数の必要性が示されているかもしれません


常に成り立っていることを保証するためには、全ての条件を同時に判定することが可能でなければいけません
同時に判定しないと、2つ目の条件を調べている時に1つ目の条件が壊れてしまう可能性があるので、結果が未定義になるからです。


あとは本文と同じです。主旨は変わりません



>>Jittaさん
うーん。ここまで全てずれているとある種壮観ですね
最初から順番にいきましょう。まずはリソースの概念から。
この概念が私の主張の全ての基本になっているので、これだけはなんとしても理解してみてください


設定ファイルを扱うソフトウエアを考えて見ましょう
ソフトウエアは、設定ファイルクラスと設定ファイルクラスのインスタンスをソフトウエアの中に生成します。
それらを使って、ソフトウエアの外に設定ファイルを作成します。

このソフトウエアの外に作られた設定ファイルに注目して下さい。
この設定ファイルは、間違いなく設定ファイルクラスではありません。
この設定ファイルは、間違いなく設定ファイルクラスのインスタンスでもありません。
だから、クラスとしての特性をもてませんし、クラスのインスタンスとしての特性ももてません。
クラスでもクラスのインスタンスでもないので、OOPオブジェクトとしての特性を持ちません


このソフトウエアの外に作られた設定ファイル、つまり実体(wの事をなんと呼びますか?
ちゃっぴさんは外部要因と呼んでいますし、インドリさんは問題領域と呼びました
Jittaさんはなんと呼びますか?

設定ファイルクラスのインスタンスと、
ソフトウエアの外に作られた設定ファイルは、
明らかに全く違うものなので区別ができるような名前をつけてください。


ちなみにこれは、オブジェクト指向プログラミングとはほぼ無関係です
手続き型だろうと命令型だろうとたぶん同じ
ソフトウエアの中にある設定ファイルの概念と、実際の設定ファイルは別物です
そして"ソフトウエア"はその両方を扱わなければいけません




>>ちゃっぴさん
>既存の programming 概念というかいろいろ影響を受ける仕様にはそぐわないけど、そうなるように改変すべきだという意見でいいですよね?
うーーん。まあそのとおりですね。
ただし、言語の拡張をするほどの必要はないですし、実装的にはほぼ変わりません

私が独自拡張しようとしているのは"状態制御"だけですが、これは別の概念として既に存在しています
ですから"状態制御"をサポートしている言語であれば必要な材料は既に揃っています


一般的にはオブジェクト指向プログラミングの概念と状態制御は別々の概念とされていますが
私の主張は、「オブジェクト指向プログラミングの概念が状態制御を含まなければいけない」です

オブジェクト指向プログラミングの実装時に状態制御が必要なことは誰もが認めることです。
実装者という立場から見ると、状態制御が独立していようがOOPに含まれていようがほとんど関係がありません
どちらにせよ状態制御は必要ですし、手法もそれほど変わらないからです

だから私の主張は実装者にとってはほとんど影響がありません
影響があるのはオブジェクト指向プログラミングの概念だけです


>具体例
抽象化でもプログラムでも"白い犬"という"白い"ことと"犬"という条件を両方とも満たす抽象的な定義を簡単に作成/使用できますが、
オブジェクト指向プログラミングの概念では表現できません
これは十分具体的な反例だと思うのですが、違いましたか?

もしかしてオブジェクト指向プログラミングの概念(or ダックタイピング)で"白い犬"を定義できますか?


>外部要因
では、エクスプローラから見たUSBメモリを考えてみましょうか
エクスプローラから見てUSBメモリは、"外部要因"ですね?

このUSBメモリを引っこ抜いてみましょう
今私がやってみたところ、目に見えるくらいのラグがあってからマイコンピュータからドライブの表示が消えました
エクスプローラでは有効なドライブを表示するはずですが、
引っこ抜かれた瞬間USBメモリは"存在していない"はずですよね?
しかし、エクスプローラの中には"存在しています"
この時間差は絶対に0にはできません

USBメモリは、"エクスプローラの認識"では存在していますが、"現実"では存在していません
この時エクスプローラにとって優先されるのは"エクスプローラの認識"です


ここで利用されているのが、USBメモリの生存期間の決め付けです
エクスプローラが、USBメモリの生存期間がある期間において変化しないと勝手に決め付けています
その定義により、当然上記のように現実とずれますが、それは仕様どおりなのでどうでもいいんです

時間差のズレが問題になった場合は、サンプリング周波数をあげるしかありませんが
それをしたところで時間差のずれを0にすることは絶対にできません
単に決め付けた時間が短くなるだけです


まとめるとちゃっぴさんの意見とは逆ですね
外部要因があるからこそ、"ソフトウエアによる条件のスコープの勝手な決めつけ"というテクニックは絶対に必要になります。
このテクニックがなければ外部要因を扱うことはできません



>>・・・さん
>あなたの言うダックテストでは実際に「消火器として使えないと」消火器じゃないんでしょ?
全然違います
ダックテストだから「消火器として使えないと」というのは違います
"見る人"が「消火器として使える」と決めたから「消火器として使えないと」消火器じゃないのです

ダックテストを考える2 で使用した例を使ってみます
B.ある鳥が鴨のように見え、鴨のように泳ぐならば、それはたぶん鴨である。鴨は鴨のように鳴くことがある。
D.ある鳥が鴨のように見え、鴨のように泳ぎ、鴨のように鳴くならば、それはたぶん鴨である。

鳥が鴨のように鳴くことに失敗するとします
この時、Bの定義を利用した場合はそれは鴨です
しかし、Dの定義を利用すれば鴨ではありません

"見る人"が決めた定義が重要です



>>Jitta on the wayさん
>どのメソッドでもって「ソレである」と定義するか、まず決めにゃならんのですわ。
このコメント(2009/01/27 18:12)はばっちりです
ただし、コードの方は残念ながらダメダメです。正しくあらわせていません

class 消火器 {
 //確認用=SelfTest
 bool 消火器のように見える();
//略
};

このコードでは、消火器のように見える();ことがtrueのときに正しいのかfalseの時に正しいのかがわかりません

両方ありえるパターンとして、消しゴムで消せるボールペンを考えて見ましょうか
class ボールペン{//いわゆる普通のボールペン
 bool 消しゴムで消せる();//falseのときに正しい
};
class 消しゴムで消せるボールペン{
 bool 消しゴムで消せる();//trueのときに正しい
};

消しゴムで消せる();というIFをもっただけでは、それがtrueかfalseかどちらを正しいとしているのかがわかりません
コメントで書いた"//trueのときに正しい"ことまであわせて"定義"なので、
"//trueのときに正しい"こともコードとして表したいし、表すことが可能なはずです

>>(正しい)状態(の値)は、抽象化によって削除します。
これは間違いだと思いますよ
OOP以外の全ての抽象化では正しい状態の値の定義をサポートしています

抽象化というのは、必須のもの以外を削除することであり、状態を削除することではありません
必須であればそれが状態であろうがプロセスであろうが削除してはいけません

抽象化の問題として
「この中にあるものを、"赤いもの"と"そうでないもの"にわけなさい」
という問題があるとき、
「"赤"は状態なので抽象化できません。抽象化の技法では不可能です」
という答えが本当に正しいと思いますか?
ちょっとした勘違いであると信じましょう



>>επιστημηさん
>となると非破壊検査可能でないかぎり認められんてーことすかね。
うーーーん
現実問題として、破壊を伴うような定義を作ることはほぼないです
ただ、否定するような条件を思いつかないことと、破壊を伴うような定義があることで何か矛盾が起こるわけではないので
今のところあえて破壊を伴うような定義を否定はしません

>んな悠長なことしてられっか。目の前で燃えてんだぞ。「消火器」って書いてあるからにはなんとかなんだろー、ひっつかんで天ぷら鍋に投げ込む。それで消えなかったら改めて別の手を考えるはず。
この場合は、"消すことの可能な消火器"という定義を使っていませんね
"消せそうなもの"(根拠として脳内の知識DB)という定義を使って
"水"、"鍋のふた"、"消火器"等を見つけて、"消火器"を選んだわけです(水は ハズレですけど)

この時結果的に消火器を見つけたからといって"消すことの可能な消火器"という定義を使ったわけではないんですよ
この時の判断として求めていたのは"消せそうなもの"であって、「ちゃんと火が消せる消火器」ではなかったって事です。実際には。

>>要は「モデルは十人十色」ってゆーアッタリマエなおはなし?
これにもかかわってきます
モデルは人によって違います。
さらに言えば、一人のひとが複数のモデル=定義を持ち、使い分けます
人間であれば消火器に関して複数の定義を持っていても別に不思議ではありません



>>状態が絡むから型を同定するには動かさにゃならん。
>>さらにちゃんと動くかは外部要因にも絡むから結合動作させにゃならん。
>>つまり本番(と同等)の環境を用意して実際にスイッチ入れにゃならん。
これは全然違うかもしれません
何度でも言いますが、現段階ではソフトウエアを主体としてください
もっと細かく言うなら、"動作中"のソフトウエアを想定してください
「モデルは十人十色」であり、"ソフトウエア"自身がモデルを持っているとしても問題ないはずですよね?
ソフトウエアが独自のモデルを持ち、開発者が独自のモデルを持ちます
ソフトウエアと開発者がそれぞれ違うモデルを持つからこそ、バグ(=開発者の思惑と違う)が存在するわけです

今私が注目しているのはソフトウエアの持つモデルであって開発者のモデルではありません
開発者の視点は入れてはいけません
今の私のモデルでは、(視点),(定義),(対象) の3つの要素しか想定していません
視点をソフトウエアに設定した時、開発者は第三者でありこの世界の外側の存在です


>型を同定するには
型を同定するのではなく、
ソフトウエアが、ソフトウエアの持つ型を使用して外部要因を同定します(厳密に言えば内部のものもできるけどここでは略)


>さらにちゃんと動くか
これはおそらく開発者視点ですね?であれば今の私の考察とは無関係です
ソフトウエアを主体としたとき、ほぼ全てのどんなソフトウエアでも、常にちゃんと動きます
たとえそれが開発者の思惑と違うものであったとしても、
ソフトウエアは、ソフトウエアの持つ定義を基準として正しく判断ができます



>>インドリさん
アンケートにより勘違いの場所が大体絞れました。
そもそものカテゴリが伝わってないと・・。なるほど。

今までの経緯は大体こんな感じかなぁというのを
私の視点から例に出して見ます

私 「今からパンの作り方を説明します」
相手「はーい」
私 「まず小麦粉を用意します」
相手「それはなんでしょうか?」
私 「これがパンの材料なんですよ。これを・・」
相手「パンはもっとふわふわしたものですよね?これは粉ですよ」
私 「これは小麦粉なので粉ですね。」
相手「何で粉のことをパンと呼ぶのですか?」
私 「これは小麦粉であってパンではありません。これを・・」
相手「パンでないのに"パン"という単語を使うのは不適当です」
私 「?????」

もちろんパン=OOPです

やりたいのは、OOPはどんな仕組みなのか?ということです。
OOPは抽象化の応用であるといわれているので、
"抽象化"という材料を使って、"OOP"を作ることができるのではないか?と考えたわけです
成功しても失敗しても面白そうだなと。

そもそもOOPの正しさを考えるためには、OOPの理論は直接は使えません
OOPが正しいのはOOPが正しいからだ、というトートロジーになってしまいますから。
OOPが何かを考えるとき、OOP以外のことがでてくるのは当たり前なのですよ

だから今考察しているのはOOPではありません。主に抽象化+αです
今の考察がいくらOOPとずれていても、ずれていること自体に問題があるとは思えません
OOPと違うという指摘もあまり意味があるとは思えないです


# re: ダックテストを考える3 オブジェクトの正当性 2009/02/06 16:57 ちゃっぴ

> 抽象化でもプログラムでも"白い犬"という"白い"ことと"犬"という条件を両方とも満たす抽象的な定義を簡単に作成/使用できますが、
> オブジェクト指向プログラミングの概念では表現できません

そういう class を作ればいいだけのような。
それが様々な要素を比較検討した結果最適であれば利用すればいいでしょう。
どちらかというと、その例が必要な状況ってかなり限定されると思いますが。

Explorer の例は、Explorer で表示されているものが実体と違っていることが存在することを許容するよう構成されているから問題がありません。
私が主張したかったことは外部要因が絡むものは、すべて失敗する可能性があるので失敗しても問題が無いように構成する必要があるということです。

なんか、object 自体に状態を含ませる、すなわち抽象化の度合を引き下げるべきであるとの意見に聞こえてしまいますが、それによってうれしいことって何でしょうか?

抽象化度が上がればそれだけ処理を共通化させることができ省力化につながりますが、抽象度を下げることによる利点ってどのようなものを想定していますか?

以前書かれていたように、事前確認による実行成否の保障ですか?
その実行に影響を与える要因が内部要因のみ (つまり、限定された状況) であればそれは正しいと言えます。
それでも、抽象化度の低下による不利益と天秤にかけた上で判断する必要がありますが。

他には無いのでしょうか?

# re: 小麦粉かな? 2009/02/07 22:11 Soda

色々な考え方があって面白いですね。
私は、ダックテストとかダックタイピングという言葉があることを初めて知りましたよ。(^^;
私がこーいうものかーと理解したダックタイピングと、あるふさんが考えているものは考える順番が逆のようでした。
私は、ダックタイピングを「本当は鴨ではないものを、鴨のように見せる」為のものだと考えたんですよ。

その結果、ダックテストが不要なものだと連想しました。
だって、鴨に見せるためにした結果なんだから、鴨であるかどうかなんていらないですよね?
私は、ダックテストの発想がダックタイピングを作り出したと考えたので、ダックタイピングがオブジェクトを特定する目的で利用することは想像しませんでした。

そのように考えたので、あるふさんが上げている例を見たときに、違和感を感じました。

私は、オブジェクトに抽象化するのって、「異なるものを、大雑把(抽象的)に同じものとして考えてしまえー」ってことだと思ってたんですよ。(^^;
これまでのログを見ると、あるふさんは、オブジェクトをオリジナル(あるふさんの言葉でリソースかな?)の正しい複製として表現できるか?と考えているように見えます。

どちらも抽象化だと思いますが、方向性がほぼ逆で、面白いですね。
あるふさんの考えている抽象化は、プログラムで扱えるようにするための記号化であり、それ以上でもそれ以下でもなかったのかな?
そのために、第一段階として、よりオリジナルに近いオブジェクトを求めているのでしょうか?

これが、パンの例でいう小麦粉だと感じたのですが...違うかな?(^^;
私のようにオブジェクトを考えてしまうと、最初に用意される材料が異なるから違和感を感じるのかな?
それは、小麦粉じゃなく、別の粉じゃないのかなと。(^^;;;;;

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/08 12:51 あるふ

>>ちゃっぴさん
>object 自体に状態を含ませる、すなわち抽象化の度合を引き下げるべきであるとの意見に聞こえてしまいますが
状態を含ませることが抽象化の度合を引き下げるとは全く考えていません
もともと抽象化では状態を含むので、必須な状態を切り捨て場合は間違った抽象化になると考えています
状態をサポートできればより正しい抽象化が表現できます
より正しい表現が可能というのは、何よりも大きな利点だと思います

ただ少し気になったのは、もしかして「全てのオブジェクトに状態制約をつけるべき」と私が主張していると思っていますか?
それであれば誤解ですね
私が言っているのは状態をサポートするべき、であって状態制約をつけるべきとはいっていません
状態制約が一つもなく常に有効なオブジェクト、要は現状普通にあるインターフェースはもちろん必要であると考えています

状態制約を要求されたときに限り、状態制約を含む定義が必要になります
>その例が必要な状況ってかなり限定されると思いますが。
比率の問題はあれど、これについては同意見です

あとは単に立ち位置の問題だけですね。
私は、状態制約を含む定義をデフォルトと考え、一部では状態制約がない定義があると考えています
ちゃっぴさんは、状態制約がない定義をデフォルトと考え、一部では状態制約を含む定義があると考えています
立ち位置が違うだけで、同じ認識であり、この点に関して対立点はなくなったと判断します。OKですか?



>>その実行に影響を与える要因が内部要因のみ (つまり、限定された状況) であればそれは正しいと言えます。
このエントリにより、全ての条件は変数、つまり内部要因としてあらわせることを示しました。(用語のスコープあってますか?)
ですので、内部要因のみの話に限定します
この点に関してもOKですね



>>(利点) 他には無いのでしょうか?
今回のエントリで、全てのオブジェクトはboolとして表すことができる、としました
ここまでこれれば、全てのオブジェクトに対して論理学が適用できるようになります
それはとんでもないメリットですよ
これについてはもう少し先で扱います


どうやらちゃっぴさんが関心の高そうなSelfTest()でいうのであれば・・
ちょっと変り種を出してみましょうか
少し前に"OOコード養成ギブス"(興味があれば検索してください)っていうのが話題になったのですけど、
このうちの"else禁止"を結構簡単に守ることができるようになります。
オブジェクトに対してガード句を適用できるのが、一番大きい
else禁止っていうかなり厳しい規約を作っているのはうちだけかと思ったんですけど他でもあったのが驚きです

else禁止にすると、インデントが浅くなるし、関数は小さくなるし、無理な名前がつけにくくなります。
SelfTest()を使う使わないは置いといて、else禁止はとても面白い規約なので、オススメです。
場合によっては劇的に考え方が変わると思いますよ




>>Sodaさん
なぜそう思ったのかのヒントをください・・

私が主張しているもの
・本当は鴨ではないものを、鴨のように見せることができる。(鴨の定義を満たしていれば、それが鴨でなくても鴨とみなす)
・(本当の)鴨であるかどうかなんていらない。(鴨の定義を満たすかどうかだけが重要で、例えば生物学における鴨かどうかはどうでもよい)
・「異なるものを、大雑把(抽象的)に同じものとして考えてしまえー」("大雑把"な定義を作り、それを全て満たすものを同じものとして扱う)

私が主張していないもの
・ダックタイピングがオブジェクトを特定する目的で利用する(オブジェクトは特定しません。オブジェクトを使って、オブジェクトでないものを特定します)
・よりオリジナルに近いオブジェクトを求めている(オリジナルに近いかどうかは全く無関係で、見る人の定義を満たすかどうか。オリジナルとはどれだけ離れてても全くかまいません)


ですからおそらく、Sodaさんとほぼ同じ考えだと思いますよ
おそらく少しだけ違うのはオブジェクトの扱いですね。私はダックテストにおける"ある鳥"は
オ ブ ジ ェ ク ト で は な い と考えています。
ここに関しては、一つ前の私のレスの>>Jittaさんあてのものを参照してください

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/08 18:30 ちゃっぴ

> 状態を含ませることが抽象化の度合を引き下げるとは全く考えていません

いえ、引き下げることになると思いますよ。
例示された "白い犬" ですが、これは "犬" よりも明らかに抽象度が下がっていますよね。

> もともと抽象化では状態を含むので、必須な状態を切り捨て場合は間違った抽象化になると考えています

例えば、犬といっても犬種はいろいろありますよね。必要であればその犬種毎に class を作ったっていいと思います。その状態が普遍であることが保証できるのであれば。その上で、抽象度を高めるよりも下げた方が総合的に利点が大きいのであれば利用する。そういうもんだと思いますよ。

> 私は、状態制約を含む定義をデフォルトと考え、一部では状態制約がない定義があると考えています
> ちゃっぴさんは、状態制約がない定義をデフォルトと考え、一部では状態制約を含む定義があると考えています

その状態というのが静的に定まったものであるならば、ごく当然なことだと思いますよ。問題なのはその状態が静的ではなく動的に変化する場合で、そういう場合では逆に足枷となって跳ね返ることが多いと思っています。

その状態が普遍でない場合にはどうゆう対処をとるのでしょうか?

ぱっと思いつくのは状態ごとに class を用意し、その都度 cast するとかの方法ですが、動的に変化する状態ごとに class を作成するのは激しく面倒くさくないですか?

個々の状態毎に class を作成することの方が利点が大きい状況であれば同意しますけど、そのためには様々な要素を考慮して判断を下す必要があると思います。

> このエントリにより、全ての条件は変数、つまり内部要因としてあらわせることを示しました。(用語のスコープあってますか?)

全てのというのは違うでしょう。すでに認めていることですが、外部要因の影響を受けるものが数多く存在することは間違いないですよね。そういったものを扱う場合、

> ある条件を確認した後、その結果がある期間において変化しないと決め付けてしまうという方法です。

上記は危険です。必要とされる要件により変化しないと決めつけることはありますが、それは実体が異なることがあることを許容しているので、当然失敗することが存在する前提で問題ないように作成する。そういうこと無しには成り立たない論理でしょう。

失敗することを許容するなら、guard clause で除外することできませんね。つまり、主張されている利点が失われると思うのですが、いかがでしょうか?

> else禁止

個人的には、それがそんなにいいものだと思いません。
Else を使うべきか否かはその状況によりけりではないですか?
Else を利用する方が効果的であれば利用する。効果的でないのであれば else を無くすようにする。そういうもんだと思いますよ。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/08 18:37 ちゃっぴ

なんか、正直現状の OOP と乖離が無くなってきているような気がするのは気のせい?

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/09 1:40 Soda

>>私が主張していないもの

うーーん、たぶん、「状態を含ませる」と主張していることが私にとっては、オリジナルに近づけすぎてるんだと思います。
あとは「抽象化」って言葉の強さですかね?
「~を抽象化した」って聞くと「区別できる限界まで大雑把にした」って想像してしまったと(^^;
「状態を含ませる」ことでオブジェクトを細分化していると感じるんですよ。
C++のclassで言えば、派生されたclassを先に考え、後から基本classを考えているように見えたんです。

少し前に戻って、

>>(A:抽象化)->(B)->(C:オブジェクト指向/ダックテスト)->(D)->(E:OOP概念/ダックタイピング/OO分析/OO設計)->(F)->(G:OOPを利用した実装)

私は、このように綺麗な流れで考えてないのかなぁ。
私の考え方だと、ダックテストが存在していないんだと思います。
ソフトウェア工学用語(?)のOOP概念、OO分析、OO設計って言葉が私の中では、何になるのかわからなかったり(^^;
ずれてることを言ってしまうかもしれませんが、

(1:やりたいことがある)->(2:それを満足させる能力を考える)->(3:その能力をもったオブジェクトを考える)

こんな感じで、感覚的にはオブジェクトが最後なんですよ。
だから、ダックテストに該当するとこがなく、ダックタイピングに該当する2しかないんです。
能力がインターフェースになるのかなぁ、私がわかる言葉だと仮想関数にまで落ちてしまいますが(^^;
能力が先にあって、その能力を持たせたものを後で考えているんですよ。

状態を含ませることはできますが、重視していないんです。
能力を発動させようとした結果で状態がわかるという感じですかね。(^^;

結果的に同じものができるのかもしれませんが、考える順番が逆に近いんです。
そのために、あるふさんの例で登場するオブジェクトは、私にとって、オリジナルに近いものと感じるんですよ。

>>おそらく少しだけ違うのはオブジェクトの扱いですね。私はダックテストにおける"ある鳥"は
>>オ ブ ジ ェ ク ト で は な い と考えています。

上で私の言っているオブジェクトとあるふさん想定している用語としてのオブジェクトは一致しているでしょうか?
ここまでのログは何度か読み直しているのですが...ちと自信がなかったり(^^;
あるふさんはダックテストを重視しているように見えるのですが違うのでしょうか?
本題は別にあって、そんなに重要ではないが、多数説明しているので、重視しているように私が錯覚しているのでしょうか?

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/14 15:10 Jitta

> このソフトウエアの外に作られた設定ファイルに注目して下さい。
> この設定ファイルは、間違いなく設定ファイルクラスではありません。
> この設定ファイルは、間違いなく設定ファイルクラスのインスタンスでもありません。
 ここまでは同意。

> だから、クラスとしての特性をもてませんし、クラスのインスタンスとしての特性ももてません。
> クラスでもクラスのインスタンスでもないので、OOPオブジェクトとしての特性を持ちません
 ここは、反対。
 なぜなら、その設定ファイルは、クラスとして表した「設定ファイル」の、元になったものだからです。ですから、クラス「設定ファイル」の特性を全て持っています。
 そして、確かに実行ファイルの外にあります。しかし、「設定ファイル」オブジェクトには、外部に永続化することができるという特徴があるでしょう。永続化できるなら、永続化した内容を取り込むこともできるでしょう。このとき、外部にあるファイルは、ファイル オブジェクトのリソース(資源)、ソース(元)などと言えるでしょう。

 私のブログ エントリ、「「オブジェクト指向」ってなんじゃらほい?」で、「やっちまった」と思ったことがあります。その1で「オブジェクト志向プログラミングについて考える」としながら、その3では「オブジェクト志向開発」にまで、話を広げていることです。その4を書こうとして、あるふさんのはじめの方のエントリで、biacさんが「オブジェクト指向、何ですか?」としつこく尋ねていた理由がわかりました。ええ、スコープが違うのです。
 同じように、あるふさんは、biacさんの問いに対して、「オブジェクト指向理論」と答えたはずです。そのスコープの範囲で話をしましょうよ。つまり、プログラミングの話は理論を実践する方法のひとつであり、方法はいくつでもあります。


> ちゃっぴさんは外部要因と呼んでいますし
 ん?ちゃっぴさんがいわれている「外部要因」って、そういうフレーズでは出てきていませんよね?メソッドが成功したか失敗したかによってオブジェクトの有効性を判断するのはどうか。ファイルにアクセスできないこともある。例えば、他の実行ファイルが排他的につかんでいるから。この「他の実行ファイルが排他的につかんでいるので開けない」というのが、開こうとしている実行ファイルの外にある要因だ、と書かれているのではないですか?外部にあるファイルが外部要因なのではなく、なにかができる/できないの原因のことではないですか?


> ソフトウエアの中にある設定ファイルの概念と、実際の設定ファイルは別物です
> そして"ソフトウエア"はその両方を扱わなければいけません
 下の行には賛成、上の行には反対。
 「別の領域にある」という意味では、別物です。しかし、ソフトウェアは、その設定ファイルそのもの(同等のもの)を扱うように設計、実装されています。もちろん、ソフトウェアは抽象的に設定ファイルを表していますが。この、「そのもの(同等のもの)を扱う」という意味で、同じものです。1つめか2つめのエントリあたりのコメントで、「導き入れる」と表現したとおりです。


> このコードでは、消火器のように見える();ことがtrueのときに正しいのかfalseの時に正しいのかがわかりません。
 え~!!!それって、オブジェクトが決めるんですか?!「観察者」が決めるんじゃないですか?そう書いてあるように読み取っているのですけど。。。
→ 『ダックテストを考える2』
> 今回は、ダックテストにおいて誰が"鴨の基準"を持つのかを考えて見ます
> 登場人物?は"鳥"と"鳥を見る人"ですね。今回はこれに加えて、"第三者"も加えてみます
> #1.複数の人が鴨を見れば、複数の鴨の基準ができる。
> 何を持って鴨とするかは、鴨(らしきもの)自身を見ても全くわからない、ということです
> 鳥を見る人にとっての鴨の基準がわからない限り、鳥を見る人にとっての鴨を見つけることはできません。
 「消火器のように見えるメソッドが true を返すときに正しい」と、メソッドのコメントに書いてしまえば、それはクラスが状態を定義しているのであって、観察者が定義しているのではないですよね?!

 消火器のように見えるメソッドは、どうしようか、かなり迷いました。本番用としている外観メソッドが、Object を返すのは、そのためです。ここは、消せるメソッドのように、「消火器のように見える(観察者)」とするべきでした。こうすることで、観察者に判断を委譲できます。
 つまり、何をもって「~の様である」とするかは、観察者が決めるもので、これは観察者の知識との照らし合わせで行われるものです。決してオブジェクト自体が「俺は消火器のように見える」と主張するわけではありません。


> class ボールペン{//いわゆる普通のボールペン
>  bool 消しゴムで消せる();//falseのときに正しい
> };
 ボールペンで書いたものは消しゴムで消せるかもしれませんが、ボールペンが消しゴムで消せたらエライことです:p いや、これはほんの冗談ですが、あるふさんが書かれていること全てに渡って違和感を感じることです。「誰が」に、着目していない。「誰が」に着目することこそ、「オブジェクトに志向する」ことではないでしょうか。
 そんなわけで、このクラス分けは、変な感じです。2009/02/06 16:57 のちゃっぴさんのコメントに、「そういう class を作ればいいだけのような」とあるように、「「白い犬」クラスと「犬」クラスを分けるんだ」とは受け取っていません。このボールペンでいうと、「ボールペン」クラスと「消しゴムで消せるボールペン」クラスですね。それを「分ける」というのは、今までのエントリからは理解できませんでした。一つのオブジェクトが「犬/白い犬」とか「ボールペン/消しゴムで消せるボールペン」という“状態”を持ち、メソッドが成功したか失敗したかによって、メソッドを呼び出した側で、状態を判断すると行っていると思っていました。違うのですね?
 コンピュータでなにかをするなら「Pen」が欲しいのであって、書ければなんだっていいのです。つまり、抽象化してしまうわけです。「書くもの」と抽象化することで、消しゴムで消すだの消せないだのは関係なくなります。ボールペンだろうが鉛筆だろうが、サインペンでもフェルトペンでも、油性も水性も関係ないのです。何かに書く。そういう特徴だけを抽出します。それが抽象化です。すると、ボールペンとか鉛筆とは関係なく、書くことも消すこともできるペン クラスができます。
 ボールペンも、犬も、コンピュータ プログラミングの中でクラス化する必要が出てくることは、まずありません。それを「コンピュータ プログラミングで必要な具体例を見せて」というのが、ちゃっぴさんの言われていることではないでしょうか。
 もちろん、在庫管理では、それぞれの商品が在庫としていくつあるか知るために、分ける必要が出てきます。でもその時には、「商品」という見方で抽象化するため、書くことができる、書いたものが消せるというようなことは重要ではなく、特徴として抽出されません。もちろん、お客さんから「消せるボールペンを」と言われるかもしれませんけど。
(雑談:消せたらボールペンの意味ないだろ。消せない、つまり改ざんできないからボールペンを使うのに。)

ついでに、「抽象」とは、
「事物や表象からある性質・要素・共通性をひき出して把握すること。また、把握して一般的な概念をつくること。「─化・─論」⇔具象・具体」
です(出典:明鏡国語辞典)。

 なにより、一番の違和感は、犬、鴨、ボールペンなど、およそソフトウェアで扱わないようなものをクラス化しているところです。特に、「鴨のように見える」メソッドを鴨クラスが持つなんて、おかしいですよね?鴨が、「自分は鴨かもしれない、鴨じゃないかもしれない」なんて思っているのでしょうか?どんな鴨であれ、鴨自身が「鴨かも?」と判断したりしません。判断するのは観察者です。にもかかわらず、観察者によって異なる外観を受け取るわけではありません。もちろん、見る方向が違えば形は変わりますし、飛んでいるときと泳いでいるときでも、形は違います。そういう違いを抽象化によって排除し、鴨としての特徴点だけを受け取って判断するはずです。このあたり、現実をそのままプログラミングしようとしているところにとても違和感を感じるのですが、あるふさんには当たり前のことなのでしょうか?

 ちゃっぴさんがいわれている「具体的な」というものは、あるふさんがエントリ「無効をサポートするオブジェクト」で、「いったんこの手法に慣れてしまうと、引数のオブジェクトにガード句を使えないのが不満で不満でしょうがなくなりますw」と書かれていることです。実際に開発でその手法を使われたから、このように書かれているわけですよね?その、開発したものを示してください。守秘義務で明かせないなら、「買い物カート」クラスで説明してください。ウェブ ショップで実装されている買い物カートです。


 あと、「"ダック テスト"」にしても「"duck test"」にしても、およそプログラミング関係のページでは見かけないのですよ。唯一、「ダック・タイピング」の由来として出てくるだけで。このことから、ダック・テストはコンピュータ プログラミングとは無関係の言葉だと判断します。
 これはどういうことかというと、上の違和感と同じです。あるふさんが考えていらっしゃる「ダック・タイピング」と、私が考えている「ダック・タイピング」は、一致したと思えます。しかし、先に「鴨や犬をクラスとして表現し、プログラミングの説明をすることには違和感がある」としたように、プログラミングでダック・テストを実現しようとすることには、違和感を覚えます。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/16 3:20 あるふ

>>ちゃっぴさん
>いえ、引き下げることになると思いますよ。
>例示された "白い犬" ですが、これは "犬" よりも明らかに抽象度が下がっていますよね。
ん--、ちょっと意味がわかりません
"白い犬"が必要であるとき、"犬"という定義では白い犬を表す表現として不十分です
何も条件がなければ白い犬よりは犬のほうが確かに抽象度は高いですが、白い犬が必要であれば犬という定義は間違っているので比較できません


>>動的に変化する状態ごとに class を作成するのは激しく面倒くさくないですか?
あれ?状態ごとにクラスを作成しなければいけないなんてうっかり書いてましたっけ?
定義を正しく表現できるのなら、プログラムにおいてそもそもクラスにすることにはこだわっていませんよ
どちらかといえばクラスだけ(とりわけインターフェースだけ)では無理ではないかという立場なわけで。

クラスのインスタンスを動的に生成された定義だと考えるととても簡単に解決できます
クラスのインスタンスを定義以外のものだと考えているならば、状態ごとに class を作成するしかないかもしれませんね


>>なんか、正直現状の OOP と乖離が無くなってきているような気がするのは気のせい?
あってますよ。
もう少し寄り道すると思いますが、これからだんだん近づいていって、最後には"現状の OOP"とまったく同じになる予定です
そもそもそういう趣向です




>>Sodaさん
>「~を抽象化した」って聞くと「区別できる限界まで大雑把にした」って想像してしまったと(^^;
これは・・あってるんですけどちょっと不安なので一応確認ということで、私の考えを載せます。
「区別できる限界まで大雑把にした」だけでは、実は意味不明なんです
誰がその操作をしたかが重要なんです

Aにとっての限界まで区別したものをA'としましょう。
このとき、Bにとって区別できる限界がA'かというとそうではないんです。
BがA'を認識できたとしても、さらにCとDに分割できるかもしれません

だから抽象化というのは、「○○にとって区別できる限界まで大雑把にした」というように、○○にとってとつけなければいけません
私が知る抽象化では必ずすべて"○○にとって"という条件がつきます。
あまりに自明すぎて省略されることは多いですけどね

Aにとって"白い犬"が必要であれば、最小が"白い犬"です。
Bにとって、"白い"と"犬"という二つの概念に分けることが可能だからといって、Aにとって"白い犬"という一つの概念が必要であることは変わりません

今はプログラマの立場ではなく、プログラムの立場で考えているので、よりオリジナルに近い概念を持つことは多いでしょうね


>>(1:やりたいことがある)->(2:それを満足させる能力を考える)->(3:その能力をもったオブジェクトを考える)
これだと、私のカテゴリわけだと、1:の時点ですでにE:あたりのような気がします。
OOPという概念があることを前提としていますよね?

私がやろうとしているのは、OOPという概念がない世界において
抽象化という概念からOOPを求められないかと考えているんです



>>Jittaさん
>>永続化した内容を取り込むこともできるでしょう。
取り込んだ時点でそれはすでに抽象化されたものなので、"取り込まれた永続化した内容"はオブジェクトです
"取り込まれた永続化した内容"と、設定ファイル実体に書かれているものは完全な別物です。
取り込まれた永続化した内容がオブジェクトだからといって、設定ファイル実体がオブジェクトだという根拠にはなりません


>>ですから、クラス「設定ファイル」の特性を全て持っています。
残念ながら「設定ファイル実体」は「設定ファイルオブジェクト」(ちょっと変えます)以外の特性を持ちますし、
「設定ファイルオブジェクト」は「設定ファイル実体」以外の特性を持ちます

大きな違いとしては、OOPオブジェクトとしての特性とアクセス権にあります。

アクセス権について
生成、コピー、削除権を誰が持つのか。
「設定ファイルオブジェクト」は、ソフトウエアが望めば生成だろうが、コピー、削除だろうが好きなときに好きに行うことができます。

「設定ファイル実体」は、まあたいていの環境では「設定ファイルオブジェクト」と大差ないのですが、実際にはOSによるファイルシステムアクセス権の制約がつきます。ソフトウエアが消そうと思ってもOSによるファイルシステムアクセス権を満たしていない限り、OSのせいで失敗します。

Admin権限でもUser権限でも、「設定ファイルオブジェクト」の生成はできるけれども、User権限でのみ「設定ファイル実体」を生成することができないという状況がありえますよね。
生成、コピー、削除権に関して「設定ファイルオブジェクト」と「設定ファイル実体」は全く違う特性(制約)を持つといえます。

単に違うだけではなく、制御権を持つ/持たないという極めて大きな特性が違うわけです



OOPオブジェクトかどうか。
「設定ファイルオブジェクト」であれば、OOPの基本的な要素である、継承、多態、カプセル化に対応していますよね。
「設定ファイル実体」はソフトウエアが継承、多態、カプセル化をすることができません。
反対というのであれば、「設定ファイル実体」がOOPとしての特性を持つということでいいのでしょうか?
では、「設定ファイル実体」がソフトウエアにとって継承、多態、カプセル化が可能というのがどういう意味なのか教えてもらえないでしょうか



もう一点だすならそもそも、「設定ファイルオブジェクト」は抽象化されたものであり、「設定ファイル実体」は実体ですよね。
ソフトウエアにとって、どちらが抽象化されたものか、どちらが実体かは区別がつくはずです

なんでこんなややこしい書き方をするかというと、後々こんな拡張をする気だからです
OOPオブジェクトとしての特性がなく、主体の外側にあるのでアクセス権が違うという理由でもって
ある視点から見ればオブジェクトであるものを、別の視点からは実体として扱えるようにします


>> このコードでは、消火器のように見える();ことがtrueのときに正しいのかfalseの時に正しいのかがわかりません。
> え~!!!それって、オブジェクトが決めるんですか?!「観察者」が決めるんじゃないですか?
決めるのは確かに「観察者」です。
ただし、オブジェクトの時点ですでに決まっています

観察者がオブジェクトを作って、そのオブジェクトを使って実体を観測します。

ボールペンの例でいきますが「消せるボールペン」といった場合、「消せるボールペン」という(消せるという値を持った)型の話であって、「ボールペン」という型は無関係です。
さらにいうなら、「消せるボールペン」がなんらかの実体をさしたときに初めて、観測者により真/偽が決定します。
「消せるボールペン」は真/偽どちらかですが、「消せるボールペン」自体に真偽があるわけではないです。




>つまり、何をもって「~の様である」とするかは、観察者が決めるもので、これは観察者の知識との照らし合わせで行われるものです。
私は、観察者の知識との照らし合わせに使った全ての条件そのものを"オブジェクト"と呼んでいます
私の材料もそろってきたので、そろそろここに踏み込みましょう

私はオブジェクトは「抽象化されたもの」である、と考えています
もちろん現段階ではソフトウエアを主体として考えます。だから"ソフトウエアによって抽象化されたもの"です
上の設定ファイルの例で考えて見ましょうか。


ソフトウエアにとって、設定ファイルの「実体」とはなにか?上の例で言う「設定ファイル実体」、ファイルそのものです。

「設定ファイルクラス」は何か?
"設定ファイルとは何か"を含んでいるもの、要は定義です。
もちろん抽象化されたものなので、オブジェクトです。
「設定ファイルクラス」とは定義かつオブジェクトです


さて。一番問題なのが「設定ファイルクラスのインスタンス」です。これは何か?
"設定ファイルとは何か"を含んでいるもの、要は定義です。
まあ実体といえなくもないんですけどね。クラスを定義とすればインスタンスは定義の実体(本物の定義)です。結局定義であるわけですが。
もちろん抽象化されたものなので、オブジェクトです。
「設定ファイルクラスのインスタンス」とは定義かつオブジェクトです



前に私は「オブジェクトとは妄想にあたる」と書きました
妄想と現実の違いが何かというと、背景となるルールの違いです
妄想は、妄想した人(もしくはモノ)のルールに従います。
現実は、現実のルールに従います

クラス/クラスのインスタンスは、ソフトウエアのルールに従って動きます
「設定ファイル実体」は、現実のルール(ここではOS)にしたがって動きます。決してソフトウエアの独断だけでは制御できません



Jittaさんにとってのオブジェクトとはどんなものですか?
できるだけ詳細に、厳密な定義が聞きたいです
・オブジェクトとは何か。
・どんな特徴をもてばオブジェクトと呼ぶのか
・生成/消去が可能なのか不明なのか
・継承、多態が可能なのか不明なのか
・誰にとってのオブジェクトなのか
・Aにとってのオブジェクトが、Bにとってオブジェクトではないというのがありうるのか絶対にそんなことはないのか
私は今、主体をソフトウエアにしているので、これもぜひほしいです
・仮にソフトウエアを主体としたときはどうなのか



>>ボールペンについて
そもそもの前提が違います
>>もちろん、お客さんから「消せるボールペンを」と言われるかもしれませんけど
このように「消せるボールペンを」と言われた時という限定条件において、
「消せないボールペン」という定義がなければ区別ができないでしょ?ということをずっと述べているわけです
とっても簡単なことなんですけど、何が理解できないのかまったく理解できません

Jittaさんが示してくれた例は、「ボールペン」が求められたときには「ボールペン」の定義があればいいといっているに過ぎません。
「ボールペン」の定義を使って「消せないボールペン」を見つけることはできません(ただし偽ではなく恒真ではないの意味)
「消せないボールペン」という定義を使うからこそ、「消せないボールペン」を見つけることができるのです。


こっちのほうを、リクエストされたウェブ ショップの例で説明してみましょう。手法のほうは、今の時点では伝えきる自信がないので後回しとさせてください。

>>「買い物カート」クラスで説明してください。ウェブ ショップ
もう少し範囲を広げてウェブ ショップシステムでいいですか?

お客様が「赤いボールペン」がほしかったとしましょう
さらに条件として150円以下、かつお客様の好みのものを望むとします

お客様はおそらく、検索窓を開いて
「赤 ボールペン」
などと入力するのではないでしょうか

検索開始ボタンを押すと、赤色のボールペンのリストが表示されますよね。(*1
そのリストにあるものはすべて赤いボールペンです。

その赤いボールペンのリストから、150円以下のものをお客様が自分で見つけ、さらに好みのもので絞り込みます。




(*1 の時点のウェブ ショップシステムに注目します
このとき、なぜ赤色のボールペンのリストを表示できたかというと、
"赤"と"ボールペン"という条件から、赤いボールペンという定義を生成し
赤いボールペンと赤いボールペンでないものに分類したからです。

このプロジェクトを成し遂げるには、必ず赤いボールペンという定義をどこかで生成しなければいけません
ボールペンの定義だけでは黒いボールペンや青いボールペンが混じってしまうし、
インターフェースだけで赤という状態を表すことができません


まあ、実際にこれをプログラミングするのであれば、データベースから文字列検索するだけなので
プログラマから見れば、赤いボールペンどころかボールペンすらでてきません。
そもそも定義を生成するという意識すらないのが普通かも

システムから見た場合は、"赤"という値と"ボールペン"という 赤いボールペンを検索するための正しい値を知っているからこそ検索ができるわけですよね。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/16 19:44 あー

なんかもやもやしてた霧が晴れた気がします。
SelfTest (というか状態のサポート?) は、"Tell, Don't Ask" (求めるな、命じよ) の原則を破っているから気持ちが悪く感じるんですね。

オブジェクトと実体を区別しているのも、せっかく捨象したものをなぜまた持ってこようとしてるのか分からなかったんですが、上の原則を前提として考えていたのが問題ということですか。

でも、上の原則を捨て去る気にはなれませんね。
遠回りに説明するより、「これは便利だ」と思わせるような具体例を示してもらえないでしょうか?

言葉だけの説明じゃなくて、実際のコードとしても示してもらえるとありがたいです。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/16 22:37 ちゃっぴ

>> 動的に変化する状態ごとに class を作成するのは激しく面倒くさくないですか?
> あれ?状態ごとにクラスを作成しなければいけないなんてうっかり書いてましたっけ?

私の想定ではと暗に示していますよ。

>> ぱっと思いつくのは

> クラスのインスタンスを動的に生成された定義だと考えるととても簡単に解決できます

動的に inctance が生成されるのは現状の OOP でも同じですが、class (member methods 等) も含めて動的に生成されるということでしょうか? つまり、人工知能のような感じで動的に処理を生成とか。そういう話なら理解できます。現状の OOP の概念では解決できませんね。

それによってもたらされる利点は確かに存在しますが、現時点では欠点の方が上回っているため実現されていないと思っています。

想定と違っていたら指摘してください。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/16 23:12 Soda

>>誰がその操作をしたかが重要なんです

抽象化を行ったプログラマ以外の人を想像できなかったんですが、そんなに重要なことなんですか?

>>今はプログラマの立場ではなく、プログラムの立場で考えているので、よりオリジナルに近い概念を持つことは多いでしょうね

上のほうで(2009/01/20 23:24)、既にJittaさんが同じようなことを問いかけているのですが、私にはプログラムの立場という概念が理解できていません。
現実のものをプログラムへ取り込もうと考えた場合、プログラムで利用しやすい形態への変更が必要だと思います。
あるふさんは、これを抽象化と言っていると私は思っています。

プログラムが自分の意思をもっているわけではないので、どんな抽象化を行うのかは、プログラマが決めるしかないと思うのですよ。
そして、どのような抽象化を行うかは、プログラムの目的や利用方法を基に、プログラマが決定するんだと思います。

白い犬の例が書かれていますが、プログラムの立場とプログラマの立場の違いが私には解りません。
Aにとって”白い犬”という概念が必要だったとして、”白い犬”を最小の単位にしたのはプログラマであるAですよね?
プログラムの立場という概念が理解できないのですが(^^;;;;;;

>>OOPという概念があることを前提としていますよね?

正直に答えますと、私は、OOPって区分がよくわかっていないんですよ(^^;;;;;;;
だから前提にするもなにも、どの部分がOOPなのか、わからない。

>>私がやろうとしているのは、OOPという概念がない世界において
>>抽象化という概念からOOPを求められないかと考えているんです

この文章を何度も読み直したのですが、よくわからないんですよ。
あるふさんはOOPを求めようとしている。
それは、抽象化という概念から求めようとしている。
ただし、OOPという概念は存在させてはいけない。
私は、OOPという概念があることを前提としているらしい。

結果として「やりたいことがある」と思考した時点でNGってことですよね?

素朴な疑問として、目的を持たない「抽象化」って存在するんですか?
目的があるから「抽象化」するんじゃないんですか?

>>インターフェースだけで赤という状態を表すことができません

実はこっちもわからなかったり(^^;
どんな色か問い合わせるインターフェースじゃ駄目なんですか?
インターフェースって動作だけじゃなく、値を返すこともできるし、状態を確認するのにも使うと思うのですが、違うのかな?(^^;
ボールペンの中に赤や黒などの色属性があればいいだけだと思うのですが・・・あれ?これがあるふさんの言う定義ですか?
でも、今までの文章を見ていると「赤いボールペン」というものを定義したいみたいだから違うのかなぁ。
「ボールペン」で「赤い」ものだと考えて、「ボールペン」classから派生して「赤いボールペン」を作ればインターフェースで、
ただの「ボールペン」と「赤いボールペン」は区別できますよね?

私の考え方だと、なにかおかしいですか?

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/17 11:11 あー

> 動的に inctance が生成されるのは現状の OOP でも同じですが、class (member methods 等) も含めて動的に生成されるということでしょうか? つまり、人工知能のような感じで動的に処理を生成とか。そういう話なら理解できます。現状の OOP の概念では解決できませんね。

Smalltalk を出すまでもなく、Ruby や Python でクラスやメソッドの動的生成は可能ですよ。
インスタンスが属するクラスを動的に変更することすら可能です。
http://d.hatena.ne.jp/sumim/20090122/p1
あなたの言う、現状の OOP の概念とはなんですか?

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/17 11:51 ちゃっぴ

> Smalltalk を出すまでもなく、Ruby や Python でクラスやメソッドの動的生成は可能ですよ。
> インスタンスが属するクラスを動的に変更することすら可能です。
> http://d.hatena.ne.jp/sumim/20090122/p1
> あなたの言う、現状の OOP の概念とはなんですか?

話には聞いていましたが、そういうことができるんですか~。
これは考えかと変えんといけませんね。
ご指摘感謝です。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/17 21:57 Jitta

> 取り込まれた永続化した内容がオブジェクトだからといって、設定ファイル実体がオブジェクトだという根拠にはなりません
 それって、外部から眺めているから、じゃないですか?
 実行ファイルは、インスタンスが「プログラムの外にある設定ファイルを元にインスタンス化される」様に作られます。すると、実行ファイルにとってインスタンスは、設定ファイルそのものではないですか?
 「開発者視点ではなく、プログラム視点で」とおっしゃるように、プログラム視点で見ると、外にある物はさわれない(さわれないどころか存在さえ知らない)わけですから、それが投影されたオブジェクトがそのもの全てではないでしょうか。真の姿を知っているのは、開発者です。プログラムにとっては、クラスは真の姿を説明した物です。そのクラスが具象化したインスタンスは、プログラムにとっては、設定ファイルそのものです。
 実際の設定ファイルにアクセス権があろうがなかろうが、クラスにそのことがインプリメントされていなければ、プログラムにとっては関係ありません。その辺は、プログラムが扱えるように抽象化されたときに削り落とされた、プログラムが扱う設定ファイルの本質とは関係のない部分です。

 この辺、Table Talk Role Playing Game でマスターをやった経験があると、実感できると思います。マスターは、ゲーム世界の神です。全てを想像(創造)し、全てを知っています。しかし、NPC をプレイするときは、全てを知っていてはいけません。NPC が知っていると設定した範囲で、知っていることだけを頼りに判断する、ということをプレイします。プレイヤーも同じか。マスターから「大きなキノコがノコノコ歩いている」と言われて、「マイコニッドだ。刺激すると、毒の胞子をばらまく。」とプレイヤーが思っても、キャラクターがそれを知っているかどうかはわかりません。「うまそうだ。ちょうど腹も空いているし、焼いて食べよう。」とプレイしなければならないかもしれません。
 開発者は、プログラムの外も含めて、全てを知っています。しかし、プログラムは教えられたことしか知りません。「このクラスのインスタンスは“設定ファイル”だ」と教えられたなら、そのインスタンスが設定ファイルの全てです。「等しくない」と言えるのは、開発者だからです。

---

> 決めるのは確かに「観察者」です。
> ただし、オブジェクトの時点ですでに決まっています
 わかりません。。。決めるのが「観察者」なら、どうしてオブジェクトの時点で決まっているのでしょう?オブジェクトの時点で状態が固定しているのはわかります。その状態が「正しいか正しくないか」、すなわち「求めている物か、違う物か」は、観察者が決めるのではないでしょうか?だったら、観察者が定義する物が、オブジェクトとして決まっているのはおかしいのではないでしょうか?

 そもそも、「観察者」って、誰ですか?「実行ファイル」と、その実行ファイルを作った「開発者」、どちらでしょうか?あるいは、どちらでもない?どちらでもないなら、その観察者は、どのように実行ファイル中に存在しているオブジェクトの状態に絡んでくるのでしょう?

> ボールペンの例でいきますが「消せるボールペン」といった場合、「消せるボールペン」という(消せるという値を持った)型の話であって、「ボールペン」という型は無関係です。
 無関係なら、どうして型の定義をするのでしょうか?
…と書きかけたけど、2009/02/16 3:20 に「あれ?状態ごとにクラスを作成しなければいけないなんてうっかり書いてましたっけ?」と書いてあるので引っ込めます。私も状態ごとにクラスを定義するのだと思っていた、ということです。
 「ウェブ ショップ アプリケーション」ですが、せっかく示していただいたところを恐縮ですが、私の意図とは違っています。私が「買い物カート」と指定したのは、買い物カートに「空」「物が入っている」という状態があるからです。この状態が、“変化する”からです。「会計」に進むときには「空の買い物カート」を弾きたいわけです。「空の買い物カート」と「物が入っている買い物カート」の2つのクラスを定義するのかと思っていたのですが、どうでしょう?それをどのようにコード化するのか、疑問に思いました。

---

 以上2つより、あるふさんの視点は、「開発者」、「プログラム」、「観察者」など、一定していないように思います。あるいは、説明するときに切り替えたことを伝えなければならないのに、伝えていないと思います。

----------

Sodaさん
> でも、今までの文章を見ていると「赤いボールペン」というものを定義したいみたい
 私もそう思っていたのですが、2009/02/16 3:20 の様に、違うみたいです。
 ボールペンのインスタンスの中から、「赤い」ものを特定する方法を、クラス定義の中に含めなければならない、と言うことのようです。この「含めなければならない」には、クラスを継承することもそうだし、何らかの判定メソッドを定義することも含まれるのでしょう。
 そうすると、ダック・タイピングがその名の通り「型」しか同定しないことに対し、オブジェクトを同定できると。
 でも、「赤いボールペン」と「青いボールペン」、「3色ボールペン」、「蛍光ボールペン」、「ノック式ボールペン」など、存在するインスタンスに対して全てを判別できるようなメソッドを提供する?

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/17 23:33 Soda

Jittaさん
>>ボールペンのインスタンスの中から、「赤い」ものを特定する方法を、クラス定義の中に含めなければならない、と言うことのようです。この「含めなければならない」には、クラスを継承することもそうだし、何らかの判定メソッドを定義することも含まれるのでしょう。

やっぱりそうなのかなぁ。
固定概念として「オブジェクト≒class」と考えてるのがいけないんですかねぇ。(^^;
それとも、「何のために区別したいんだろう?」って考えること自体がいけないのかなぁ。
過去の例では、class名でしか表現していないから、どんなことが定義になるのか判別しにくいんですよねぇ。

前に、Childというclassが表現されていましたが、あの時、Humanという別のclassがなぜメンバ変数だったのかも謎なんですよ。
Humanというclassから派生してChildを作るのではなく、なぜメンバ変数なのか。
派生させれば簡単にできそうなのに、あえて行わないのには理由があるんだと思うのですが・・・
OOPの概念を使わないってことが、制限になっているのかなぁ、まだよくわからないです。

>>でも、「赤いボールペン」と「青いボールペン」、「3色ボールペン」、「蛍光ボールペン」、「ノック式ボールペン」など、存在するインスタンスに対して全てを判別できるようなメソッドを提供する?

どうしても、先にやりたいことを考えてしまいます。(^^;;;;;
全てを「ボールペン」として扱いたいことは想像しやすいんですが、その逆なんですよねぇ。
データベースみたいなものなのかなぁって想像してしまいます。
全ての「ボールペン」を個別に扱いたいならば、抽象化しないでそのまま使うのかなぁ?
個々の違いは、オブジェクト自体で処理させて、扱うのは「ボールペン」だけにしたいなぁと、めんどくさがり屋の私は思うわけです。

私は、あるふさんはボトムアップの考え方なのかなぁって想像していたんです。
もっとも細分化された部分を先に用意し、徐々に抽象化していくようなイメージだったんです。
でも、あるふさんはトップダウンと言われてたし、まったく異なる考えなんだろうなぁと。

用語の捉え方に引っかかって、本質的な部分ではないところが広がり、わかりにくくなっているのかなぁ?
同じことを言っているのに、表現の違いで別物に感じてるだけだったり(^^;;;
もう少し先に進めば、明確になるような気がします。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/19 7:13 Jitta on the way

> それとも、「何のために区別したいんだろう?」って考えること自体がいけないのかなぁ。
んー、それは、必要だと思います。区別する必要があるのか、あるなら何によって区別するのか。それを考えないと、無尽蔵にクラスがあふれてしまうじゃないですか。

> 前に、Childというclassが表現されていましたが、あの時、Humanという別のclassがなぜメンバ変数だったのかも謎なんですよ。
ですね。たいてい、Human から Child を導出するでしょうね。SelfTest を仮想関数にして、Child から Human の SelfTest を呼び出せば、「人間じゃなければ子どもじゃない」と出来ますから。

> 用語の捉え方に引っかかって、本質的な部分ではないところが広がり、わかりにくくなっているのかなぁ? >>
> 同じことを言っているのに、表現の違いで別物に感じてるだけだったり(^^;;;
だから、用語の選定は大事なんじゃないでしょうか。
私も、「状態のサポート」以外は同じだと思うのですが…つか、状態を知っているのが誰か?って所の求めるものが違うのか?

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/19 18:53 Soda

Jittaさん
>>んー、それは、必要だと思います。区別する必要があるのか、あるなら何によって区別するのか。それを考えないと、無尽蔵にクラスがあふれてしまうじゃないですか。

色々考えたんですが、区別などの意思を加えるのは、もっと後の段階なのかなと。
その無尽蔵にあふれている状態こそが、あるふさんの表現したい「A:抽象化」であり、だからこそ、ダックテストの鳥はオブジェクトではないと考えているのかなと。
それなら、私の考え方だと「E:OOP概念/ダックタイピング/OO分析/OO設計」と言われたこともわかるような気がします。
こーなんていうか、私だと無意識に飛ばしている部分の話なのかなぁと。
区別するのは、「C:オブジェクト指向/ダックテスト」に該当し、区別している流れでダックテストがでてきたのかなぁ。

>>だから、用語の選定は大事なんじゃないでしょうか。
プログラマの共通言語であるコードで会話してくれれば、認識のブレは少ないのでしょうが、コードだと概念自体を説明するのは難しそうですねぇ(^^;

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/19 23:07 あるふ

>>あーさん
"Tell, Don't Ask" の原文らしきもの(の機械翻訳)とかwebで見つかる程度の物を見る限り、
どちらかといえば守っているように見えるんですけど、ちょっと判断が付きません

適当に2つのクラスを作ってみましょう
class TestA{
AAAAA* m_AAAAA;
public:
int SelfTest(){
if(m_AAAAA == 0){return err;}
return 0;
}
};
class TestB{
BBBBB* m_BBBBB;
public:
int SelfTest(){
if(m_BBBBB == 0){return err;}
return 0;
}
};

TestAでいえば、"m_AAAAAが有効な値をさしている"ことを条件とする定義ですね
有効な間は"TestAとして"機能するけど、無効な時は"TestAとして"機能しません(いくつかを除きほぼ全てのメンバ関数が無効になる)

TestAとTestBはどちらもメンバ変数のポインタが無効な時に無効になります
しかし、呼び出し側からはm_AAAAAやm_BBBBBがあることや、判断の方式を意識する必要がありません
これによって、仕様変更があった時、例えばm_BBBBBをなくしたり、参照にしたり、条件が増えたりしても呼び出し側はあまり影響を受けません


"Tell, Don't Ask" の意味が、「呼び出し側が、呼ばれる側のメンバ変数の存在を知っていてはいけない」
という意味だけなら、かなり厳密に守っています
他に意味があるのかどうかはよく読み取れませんでした



うーむ。しかし説明していない要素をふんだんに使ってしまいました(8割くらい未定義な感じ)。
本筋でこのあたりにたどり着くのは・・今のペースだと半年後とか1年後のような気がします
のんびりいきましょう



>>ちゃっぴさん
>class (member methods 等) も含めて動的に生成されるということでしょうか?
概念だけでいえば、この表現はかなり近いです。だから現状の OOP の概念では解決できません
そういった動的に生成される型を必要としているにもかかわらず、OOP の概念では解決できないため
抽象化から引っ張ってきたのが、状態という定義のサポートです


状態という定義をサポートすれば、オブジェクトの定義の動的生成が簡単にできます
状態が定義であれば、オブジェクトの定義として規定された状態が変われば別の定義になるということですからね
(当たり前のことですが、定義として規定されていない状態がいくら変わろうとも別の定義にはなりません。ここは注意してください)

状態を定義として扱うことができるとして考えれば
"白い犬"や、"黒い犬"という型を作ることができます

"白い犬"と、"黒い犬"と、"赤い犬"が必要だったとしましょう
プログラマなら間違いなくこう考えるはずです
「 T 色の犬という型ジェネレータを作って、色違いは自動生成しよう」

では T 色の犬を作ってみましょうか
class T色の犬{

-------
int SelfTest(){
if(犬.color != m_color){return err;}
return 0;
}
};

m_colorが白の時はこれは白色の犬という定義になりますし、m_colorが黒の時は、これは黒色の犬という定義になります
templateクラスからクラスを生成するのと同じような感覚です

状態を定義として扱うことができるという環境下では
クラスは型ジェネレータであって、本当に型として扱うことができるのはクラスのインスタンスです


命題を表現するためには、定義の動的な生成が必ず必要になるのですが、
ちゃっぴさんの言うとおり、新しい仕組みを作るのは非常に負担が大きいです
ですから、クラスのインスタンス生成を、動的な定義の生成として扱えるように、
概念の方を若干いじったということです。

状態を定義として扱うことができるというのは、私が勝手につけた条件です
だから実は最終的にはこの条件を消します。一つも状態の定義がないという特殊な状況を想定することによって。




>>Sodaさん
・プログラムの視点でみるということ
うーん。これはちゃんと伝わっている人がほぼ0に近いですね
コメントではなくメインのほうで取り上げたほうがよいかもしれません

プログラマの視点でプログラムを見た時と、プログラムの視点でプログラム(自分自身)を見た時では
何もかもって言うぐらい全く違うものになりますよ

ざっと思いついただけでもこんな感じ↓
・正しさの基準と責任
・外内の向き
・ソースの編集時がメインなのか、実行時がメインなのか
・コンパイル時


最も重要な正しさの扱いについてはSodaさんも大体わかってるじゃないですか
>プログラムが自分の意思をもっているわけではないので、どんな抽象化を行うのかは、プログラマが決めるしかないと思うのですよ。
>そして、どのような抽象化を行うかは、プログラムの目的や利用方法を基に、プログラマが決定するんだと思います。
まさにそのとおり。
その上でプログラムの立場に立つとどうなるかは自明ですよね??

プログラマが何が正しいかを決めるので、プログラムは既に正しいとされた基準を持っているということになります
"プログラマにとって正しい"ことを保証する責任はプログラマにあるので、
プログラムには"プログラマにとって正しい"事を保証する責任はありません


このことから導かれるのは、
開発者にとっての利点・欠点を考えたり、開発者にとって正しいかどうかといったことは、
的外れであってなんら意味のない指摘だということです。
もちろん"プログラムの立場に立ったとき"限定です
開発者の立場に立ったり、プロジェクトの立場に立てば、開発者にとっての正しさは極めて重要になるんですけどね。

プログラムとその周りという小さな世界で本質をつかんだ後、適用先を広げるという流れを予定しているのです



では以上を踏まえた上で、実際にはプログラマの考えとプログラムの考えが違ったとしましょう
プログラマの立場から言うと、プログラムが間違っているという結論になります
プログラムの立場から言うと、プログラマが間違っているという結論になります

真実なんてものは存在しないので、これは単に立ち位置の問題であってどちらも正解です




では次。向きについて。
あるクラスがあるとして、そのクラスがインターフェースを持ちそのメンバ関数の中でWin32と通信をするとします
さて、クラスのインターフェースとWin32との通信では、どちらが外でどちらが内でしょうか

プログラマにとっては、クラスのインターフェースが外でWin32との通信が内とすることが多いと思います
クラス(ひいてはプログラム)にとっては、クラスのインターフェースが内でWin32との通信が外です



あとは生存期間ですね。
プログラマにとってはコンパイルが終わるまでがプログラムですけど、(このあたりの取り方は人によってかなり違うと思いますが)
プログラムにとっては、実行時こそがメインになるのでは。
このことから、プログラム視点で見た時に限り、コンパイル時に結合されたものを、結合された状態で捉えることも可能ですね


多分探してみればもっともっと出てくるのではないでしょうか




>>>OOPという概念があることを前提としていますよね?
>正直に答えますと、私は、OOPって区分がよくわかっていないんですよ(^^;;;;;;;
うーーん。区分なんてないと思いますよ
単に作るのか使うかの違いだけです

OOPというクラスがあるとすれば、私の立ち位置はクラス内部の実装側で、Sodaさんはどちらかといえばクラスの利用者側
OOPというソフトがあるとすれば、私がソースで、Sodaさんはそのソフトの使い方

OOPという定理があるなら、私はその定理の作り方を考えているのに対し、Sodaさんは使い方を考えているように見えます


OOPを見るための視点が違うというか・・。経路が違うんですよ

なんとなくですがこんな感じ

やりたいこと--------→OOP---->やりたいことを満たすプログラム
抽象化________________↑




>>結果として「やりたいことがある」と思考した時点でNGってことですよね?
はい。今の時点ではこれは、次の2つともNGです

私は今大きなテーマとして、OOPを求めるということを目標としています
(未だに本題に入っていないということがわかりにくくしていますね。展開遅くてスミマセン)
だから やりたいこと=OOPを求める なので、これ以外を想定していたらテーマをはずしています

私は、小さなテーマもいくつか作っています
しかしこれらは今は全て、"プログラムの立場に立つ"事を前提としています
上で説明したように、プログラムの立場で見ている限りは「やりたいことがある」というのはピントをはずしているように見えます





>>Jittaさん
Jittaさんにはまず、プログラムの外にある実体の存在を見つけてもらわなければいけません
このイメージを共有できていないことが全ての問題の原因に見えます
このイメージを共有できないうちに他の話題に行くのは危険ですね。
ほかの事はこれが終わるまで全て後回しにします

>>プログラム視点で見ると、外にある物はさわれない(さわれないどころか存在さえ知らない)わけですから
プログラムは外にあるものを見つけることもできるし、触ることもできます

では簡単にエクセルで説明しましょう
エクセルを起動し、ファイル->名前をつけて保存 これでファイルを作成できました
では次に ファイル->開く で先ほどのファイルを開いてみましょう。 これでファイルを見つけることができました


これらの動作のことを私は、エクセルがファイルを保存し、エクセルがファイルを開くと表現します。
ちょっと言い換えて、プログラムがファイルを保存し、プログラムがファイルを開くと表現します。

プログラムが外のものを見つけることも、触ることもできてしまいましたね

また、プログラムがファイルを保存し、プログラムがファイルを開くという動作をしたとき、
プログラムの中ではファイルというオブジェクトが存在しているはずですよね(どういう形態かは問いません)


Jittaさんの想定するプログラムは、人間にたとえれば脳だけを対象にしたものに見えます
私の想定しているものは、脳も含むし、手や足も含むものとしての人間です
内面と外面の両方を持つ個体です

私の想定するプログラムという用語のほうが、広い意味を持たせているようですね

キノコの例が出ていたのでそれで説明しましょう
人間の目の前にキノコがあるとします
人間は、目で見ることによってキノコの存在に気づきます
目で見るというのは実際には網膜を経由して、脳で処理しています
人間にとってキノコの画像、キノコの情報は、脳にしかありません

人間は、脳にあるキノコのイメージと、人間の外にある実際のキノコが"別"であることを知っています
(目を閉じたとき、脳にあるキノコの画像は消えるが、人間の外にある実際のキノコが変わらずそこにあることを知っています)
そして、脳にあるキノコの情報を使って、外にあるキノコと通信・・さわったり食べたりすることができます


どうでしょうか。
プログラムが自分の中にオブジェクトをもちつつ、プログラムの外にある実体にアクセスする図がイメージできないでしょうか?





限界なので今日はここまでで

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/21 14:40 ちゃっぴ

>> class (member methods 等) も含めて動的に生成されるということでしょうか?
> 概念だけでいえば、この表現はかなり近いです。

そういうことですか。

> T 色の犬

前提としては、color field の値が SelfTest() の実行中で変化しないということでいいですよね。
つまり、multi thread で動かさず shared memory に置かれていないとか。

それでも、これ正直効率悪いだけだと思うんですよ。

以前条件分岐が省略できる利点があると主張されていましたが、条件分岐を無くすためだけに class を自動で作成するのでは、どうやっても効率低下が避けられないと思います。現在の programming 概念を取っ払ったとしても、効率よくする方法って将来的にも無理じゃないかなぁと。

その効率低下という欠点に比べて、条件分岐を無くすという利点は遥かに低いと思います。

とはいえ、下記を完全に否定しているわけではなく、

> クラスのインスタンス生成を、動的な定義の生成として扱えるように、
> 概念の方を若干いじったということです。

Class が変わることによって扱う処理を追加する必要がある状況では、有効な手法じゃないかと思います。うまく扱う具体的な方法は浮かびませんが。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/22 7:22 Jitta

>> SelfTest (というか状態のサポート?) は、"Tell, Don't Ask" (求めるな、命じよ) の原則を破っているから気持ちが悪く感じるんですね。
> "Tell, Don't Ask" の原文らしきもの(の機械翻訳)とかwebで見つかる程度の物を見る限り、
> どちらかといえば守っているように見えるんですけど、ちょっと判断が付きません
 SelfTest というメソッドがあることで、これによって外部から求める事ができる、ということです。
ex. http://www.pragprog.com/articles/tell-dont-ask
「Procedural code gets information then makes decisions. Object-oriented code tells objects to do things.」
訳:「手続き型言語は、情報を得た後、判断をします。オブジェクト指向コードは、オブジェクトに何かをするように命じます。」
「That is, you should endeavor to tell objects what you want them to do; do not ask them questions about their state, make a decision, and then tell them what to do.」
訳:「つまり、あなたが必要とすることをするようにオブジェクトに命じるように努めるべきです。それらの状態について尋ね、判断し、それから何かをするように命じないでください。」

 このように、SelfTest によって状態という「情報を得」、有効無効を「判断」してから使用しようとしているので、「"Tell, Don't Ask" (求めるな、命じよ) の原則を破っている」と感じます。
(あるふさんの中では違うのかもしれないけど、他の人へ伝わっているのはこういう事。)

 ご提示の TestA が、m_AAAAA に何らかのポインタが設定されていないと「インスタンスが有効ではない」ということなら、コンストラクタで m_AAAAA を設定する、ファクトリー メソッドで設定したオブジェクトを生成するなど、インスタンスが用意された時点で有効でしかないように作ります。何らかの都合で設定できなかったなら、例外を生成します。


> >class (member methods 等) も含めて動的に生成されるということでしょうか?
> 概念だけでいえば、この表現はかなり近いです。だから現状の OOP の概念では解決できません
> そういった動的に生成される型を必要としているにもかかわらず、OOP の概念では解決できないため
> 抽象化から引っ張ってきたのが、状態という定義のサポートです
 すでにちゃっぴさんへのコメントで示されているとおり、動的にクラスを生成できるオブジェクト指向プログラミング言語があります。というか、最初の OOPL である SmallTalk は、できます。C++ や Java, C# には出来ないというだけです。また、JavaScript も、ある意味動的にクラスを作り出せる OOPL といえるでしょう。逆に、動的にクラスを作り出せるからこそ、ダック・タイピングの考え方が必要なのですけどね。

> クラスは型ジェネレータであって、本当に型として扱うことができるのはクラスのインスタンスです
 やっと「クラスと、クラスのインスタンス」を同義に扱う理由がわかった(T^T)
 それならそれで、「第n回ぐらいで扱います」くらい、言って欲しかった。

# re: ダックテストを考える3 オブジェクトの正当性 2009/02/23 22:27 あるふ

>>ちゃっぴさん
うーん。まだそれなりに隔たりがありますね

>>class を自動で作成するのでは、
違います
クラスのインスタンスを生成すること(及び定義として規定された値が変化すること)を、
定義の生成と呼びます、ということです
(もちろん値が定義として既定できるという条件の時のみ。当然現在のOOPではこれを定義の生成とは言いません)

だから言語がクラスと呼んでいるものの生成はしません
クラスのインスタンスの生成や、値の変更がそこまで問題視するほど効率が悪いとは思えません

これらの前提の上で、member methods 等 も含めた新しい定義を動的に生成できます
実例を見てみると、それだけ?と思うようなたいしたことないことですけどね。これはもうちょっと後に出します






>>Jittaさん
>>"Tell, Don't Ask"
そうそう。私もそのページを見たんですよ
その部分だけではなく、全文を訳してください

突っ込みを入れるのであれば、どうすればよいのかではなく、”なぜそうしなければいけないのか”を取り出すのが筋というものではないですか?
提示された理由は「呼び出し側が、呼ばれる側のメンバ変数の存在を知っていてはいけない」程度しか読み取れなかったのですけれど。


形式だけで言うと、というか"Tell, Don't Ask" にとっては、
SelfTest()は、「情報を得」ていません




>>すでにちゃっぴさんへのコメントで示されているとおり、動的にクラスを生成できるオブジェクト指向プログラミング言語があります。
これは方向性がまるで違います(詳しくない言語なので、もしかしたら私の勘違いかもしれませんが)。

状態の定義をサポートするためには、動的な定義生成が絶対に必要です
しかし、動的な定義生成をサポートしても、必ずしも状態の定義をサポートされるわけではありません
(逆は必ずしも真ならず)

定義とは正しい状態を含むことができる、という前提を採用した時、
C++ や Java, C#は動的な定義生成をサポートしています

# re: ダックテストを考える3 オブジェクトの正当性 2010/07/06 17:48 ghd

オブジェクトは正しい状態と正しくない状態の2値、つまりbool値となれるので、
オブジェクトが他のオブジェクトの条件の一つとなることも可能になります
http://www.linkslondonsale.com/
http://www.panbeadssales.com/

# Posts like this brghiten up my day. Thanks for taking the time. 2012/10/18 7:56 Asha

Posts like this brghiten up my day. Thanks for taking the time.

# <url>http://www.insurquotestoday.com/|insurance quotes</url> 2223 <url>http://www.carinsurshopping.com/|car insurance</url> 1526 2012/10/29 23:16 Maryellen

<url>http://www.insurquotestoday.com/|insurance quotes</url> 2223 <url>http://www.carinsurshopping.com/|car insurance</url> 1526

タイトル
名前
URL
コメント