Nm

目次

Blog 利用状況

書庫

日記カテゴリ

無効をサポートするオブジェクト

前項の無効をサポートするオブジェクトがどんなものかを、他の手法と比較して考えて見ます

・テストファースト
仕様の洗い出しのためにテストを作成するという意味では同じです。
どちらも動的なテストができるという意味では同じです。
クラスを作成するときに、最初にSelfTest()を作ってしまうのも同じです。

違いは、繰り返しテストを削除したことと、このテストを本番コードにも組み込むということです。
繰り返しテストを取るのか、本番コードに組み込むことによるさまざまなメリットをとるのか・・。

両方のいいとこ取りをするのがベストですかね。

 

・ダックタイピング
クラスの作成権、編集権が見る側に全権があるという意味で、SelfTest()オブジェクト指向とほぼ同じです。
理念は同じなのですが、現在のダックタイピングは静的に表現されることが多いです。
見る側の思惑と現実が同じかどうかの検証は動的である必要があります。

現在のダックタイピングと、SelfTest()オブジェクトは、動的か静的かが主な違いです。

 

・契約プログラミング
SelfTest()は、事前条件そのままという意味で同じです。
事前条件以外を使用しないという意味では違います。

現在の契約プログラミングでは、静的解決を目標にしているものが多いため、
現在の契約プログラミングとはかけ離れているかもしれません。

SelfTest()は、動的テストを重要視しています。

 

・ネットワーク
オブジェクト指向を、オブジェクト間、オブジェクト-リソース間の通信と考えれば、通信の手法が使えるはずです。
ネットワークの場合、切断の要因が相手にあることがあるため、
常に接続されているかどうかを確認しなければいけません。この考えはSelfTest()と同じです。

 

・デザインパターン
Nullオブジェクトが最も近いです。
全てのクラスがNullオブジェクトにもなれることをサポートしなければいけない、と考えるとSelfTest()と同じです

 

・ガード句
極めて相性がよい、というよりはオブジェクト指向をガード句に対応させたものがSelfTest()オブジェクト指向といっても過言ではないです。
どんなクラスに対しても有効なガード句を使用可能になります

 

・関数型
全てのクラスが"無効な状態"をサポートするため、戻り値でクラスのインスタンスを安全に返すことができます
(初期化に失敗しても例外を出さない。コード上に矛盾も起きない)。
この使い勝手が、関数型と少し似ているかもしれません

 

・状態遷移
必要性を感じなくなります。
SelfTest()は、全ての状態を考慮した上でどんな時にでも正しく動くことを目指すため、
特定のパターンに依存する状態遷移は必要がなくなります。

むしろ状態遷移の上位互換に近い(全てのパターンを考慮するという意味で)のですが、その分難しいともいえます

 

もっともイメージしやすいのはおそらく、テストファーストを本番コードに組み込んだもの、ですかね。
実際メリットの半分くらいはテストファーストと同じです。

なぜ本番コード、つまり動的にテストをしなければいけないのかは、
オブジェクト-リソース間の通信(メッセージ)と捉えているからです。
通信であれば、接続テストは必須ですよね?

オブジェクト指向の外を見てみれば、案外と普通の手法です

 

 

無効をサポートするオブジェクト手法のメリットを考えて見ます。
まず一つは、テストファーストと同様、仕様の理解を深めます。

 

もう一つは、プログラムの構造をシンプルにすることが可能な点です。
??わかりませんね。

まず構造化定理を思い出してください。
全てのプログラムは順次、反復、分岐で表現できます。

このうち分岐は全て、あるオブジェクトが有効か無効かで表すことができます。
ある処理をするとき、"全ての必須のオブジェクトが有効であれば"、
順次、反復のみであらわすことが可能です。
分岐がなければ、反復は順次と読み替えても対して問題にならないでしょう。

必須のオブジェクトが一つでも無効であれば、それは制約を満たしていないので処理が中断します。

つまり、プログラムを順次と中断だけで表現することができるようになります。

 

分岐をなくすというよりはむしろ、初期化に持ってくるイメージに近いです。
RAII(Resource Acquisition Is Initialization リソースの確保は初期化時に)をもじって
SII(Selection Is Initialization 選択は初期化時に)とかどうでしょうか

 

もっともっと実装よりに言えば、全てのオブジェクトに対してガード句を使えるのが最大のメリットです
いったんこの手法に慣れてしまうと、引数のオブジェクトにガード句を使えないのが不満で不満でしょうがなくなりますw

int Func(Object obj){
    if(int res = obj.SelfTest()){return res;}//←これ。

    //何か
    return 0;
}

投稿日時 : 2008年12月23日 16:32

コメントを追加

# re: 無効をサポートするオブジェクト 2008/12/23 17:05 インドリ

これって、Objectに該当するオブジェクトにSelfTestに該当するものを導入するって話しかな?
動的契約プログラミング(所謂Assert手法)については、例外があるからあまりしないピヨ。
一応した事あるけど、保守性などを考慮したら例外処理に落ち着いたピヨ。
えっと、契約プログラミングについて誤解していると思うんだけど、この手法は品質保証の為に使用するもので、動的にしちゃうと納品先とかで発生して大変な事になるピヨ。
その点注意してね。
ネットワークについては、全てオブジェクトと考えるといいと思うピヨ。
オブジェクト指向では、取りようによっては、全てオブジェクトだからメッセージもオブジェクトなんだ。
あと、XML Webサービスなんかは位置透過性があるからリソースの概念が無くてもいけるとボクは思うピヨ。
純粋に行ったらリソースもオブジェクトだからね。
えっと、言い難いんだけど、あるふさんが何をテーマにしているか分からなくなったピヨ。
もっと説明した方がいいんじゃないかな?

# re: 無効をサポートするオブジェクト 2008/12/23 21:10 ちゃっぴ

> ネットワークの場合、切断の要因が相手にあることがあるため、常に接続されているかどうかを確認しなければいけません。

そうかなぁ?切断されているかどうかは実際にその処理を行ってみて、結果が返ってきて初めてわかるので、接続されているか確認することは重要じゃ無いと思いますけど。

事前確認が保障されるものって非常に限られると思いますが。。。

っていうかおいらの skill 不足か全般的に主張したいことがよくわかりません。。。

# re: 無効をサポートするオブジェクト 2008/12/23 23:46 ちゃっぴ

説明が不十分なので補足します。

切断されているかどうかがわかるのは実際に処理を行ったときだけです。

つまり、事前確認したところで実際に処理が成功するか失敗するかはわかりませんので、戻り値で返して都度確認するとか、例外を利用するとかの手法が必要になります。

実際に事前確認が確実に保証されていいと考えてよいものは local の memory でかつ排他的に扱えるもののみです。
なんか object に self check を組み込んで object 全体の有効性をあらかじめ判断しておけば coding が楽という主旨に見えるのですが、そうは問屋が卸さないと思います。

# re: 無効をサポートするオブジェクト 2008/12/24 5:51 インドリ

あっそうそう。
ネットワークについては、相手の他に自分が要因である事もあるし、相手も複数ありえるピヨ♪
相手と言っても、回線・交換機・サーバー…etcなど色々な相手が居るピヨッ注意してね♪

# re: 無効をサポートするオブジェクト 2008/12/24 9:12 774

ダックタイピングは基本動的ですよ?
あと、SelfTestは事前条件と言うよりは不変条件です。
あとあと関数型との比較はちょっとこじつけ感があるような・・・

初期化時に例外を出さないことはいいこことは思いません(C++はここでは置いときます)。
SelfTestだと原因の判定にif-else if羅列を、例外だとtry-catch-catchの羅列を使うだけの差じゃないでしょうか?

SIIはごくごく一般的なクラスベースのオブジェクト指向では、まさに多態により実現することですが・・・
SelfTestを利用する利点がわかりません。

# re: 無効をサポートするオブジェクト 2008/12/24 10:00 ゆーち

オブジェクトの有効性判定とオブジェクトのテストをSelfTest() だけで解決しようとするのは無謀だと思いますよ。

オブジェクトをいじるどころか、生成と削除についても依存性をなくしましょうという時代に、だれかが全権を持つんですよと言われ(ているようですので)るのも違和感を感じます。

>int Func(Object obj){
> if(int res = obj.SelfTest()){return res;}//←これ。
グローバル関数ですか?
オブジェクト指向なプログラム実装であれば、こういった関数へのオブジェクト引き渡しではなく、メソッドを呼び出す形になります。
int ret = obj.Func();
その場合、すべてのメソッド呼び出しに
if(obj.selfTest() == 0){
int ret = obj.Func();
}
こんなこと書かなきゃいけないんですか?


オブジェクト指向設計の中心は抽象化モデリングです。
映画じゃないんだからw、抽象化された、実物とは違うオブジェクトがプログラム中につくられるのは当然のことです。
世の中は、オブジェクト間の依存性とか利用する上での制約をできるだけ少なくするような方向で進んでますよ。

ところで、SelfTest() の戻り値はどんな意味なんですか?
エラーコード?クラス別に定義するつもりでしょうか?

一番のつっこみどころは、「SelfTest()で状態遷移が必要なくなる」でしょうか。
そんなことは不可能だと思います。

通信の切断についての記述とか、前項のChild(たぶん子供?)クラスとHuman(たぶん人間?)の実装でChildクラスのメンバに Human があるっての、ずいぶん間違っておられるように感じます。

# re: 無効をサポートするオブジェクト 2008/12/24 13:02 ん?

> クラスの作成権、編集権が見る側に全権があるという意味で、SelfTest()オブジェクト指向とほぼ同じです。
まず、SelfTest()オブジェクト指向って何ですか?
次に、ダックタイピングについて勘違いされているような気がします。
ダックタイピングについては以下をどうぞ(まだ未完成かつ更新の気配はなさそうですが・・・)。
http://shinh.skr.jp/h/?DuckTyping

> SelfTest()は、事前条件そのままという意味で同じです。
違います。
774さんも指摘しているように、どちらかというと不変条件に近いようですが、不変条件はメソッドリターン時にも成り立っている必要があるため、不変条件ですらありません。
契約プログラミングについては以下の書籍を参考にしてください。
http://www.amazon.co.jp/dp/4798111112

動的テスト、静的テストについても用語を誤用しています。
動的テストは実際に実行するテスト、静的テストはソース解析等を行うことによるテストを言います。

ネットワークについては他の方たちも指摘しているように、SelfTest()でテストしたところで、実際の接続時に切断してしまう可能性がありますので不十分です。

> 全てのクラスがNullオブジェクトにもなれることをサポートしなければいけない、と考えるとSelfTest()と同じです
違います。
Nullオブジェクトは呼び出し元で意識することはありませんが、SelfTest()は呼び出し側で意識する必要があるという部分で決定的に違うものです。
ifを絶つためにNullオブジェクトがあるのに、SelfTest()でifチェックをしているようでは本末転倒もいいところです。

> オブジェクト指向をガード句に対応させたものがSelfTest()オブジェクト指向といっても過言ではないです
過言です。
オブジェクト指向(プログラミングと仮定)がガード句に対応していないわけではないですよね?記述できますし。
どんなクラスに対しても有効なガード句が使用できたところで、ありがたみがあるわけではないですよね?

> 関数型と少し似ているかもしれません
全く類似点がありません。
関数型言語にも例外処理を取り入れた言語があることはご存知でしょうか?

> ・状態遷移
> 必要性を感じなくなります。
状態遷移がなくなるということはオブジェクト指向(やはりプログラミングと仮定)を放棄しているようにしか思えません。
SelfTest()が全ての状態を考慮した上でどんな時にでも正しく動いたからといって、他のメソッドがそうとは限りません。
というか、何が言いたいのかちょっとよく分かりません。

> 全てのオブジェクトに対してガード句を使えるのが最大のメリットです
以前実装にC++を使用しているためC++固有のことになりますが、C++では全てのオブジェクトのルートとなるクラスは必要ありません。
むしろ、それはC++の目指すところと逆方向といってもいいでしょう。
C++0xにObjectクラスが追加されていないことをもうちょっとよく考えて見てください。

このことから、全ての言語に共通するオブジェクト指向プログラミングというものは存在しないということになります。
C#にはObjectクラスはありますが、C++やJavaScriptにはありません。
また、C#やC++は言語要素としてclassを持ちますが、JavaScriptは持っていません。
どれもオブジェクト指向言語であることは疑いの余地はないと思いますが、このように捕らえ方が全く違うのです。

# re: 無効をサポートするオブジェクト 2008/12/24 19:07 Jitta

この連載で用いられている「オブジェクト指向」という言葉について、書き手と読み手が共通の理解を持っていません。その状態で話を進めても、読み手には理解できません。
あるふさんが使われている「オブジェクト指向」は、読み手が期待している「オブジェクト指向」とは違うようです。まずその事を理解してください。この用語について、共通の理解をすることを、まず第一としてください。
お願いします。

# re: 無効をサポートするオブジェクト 2008/12/24 23:30 インドリ

あるふさん、もう一度言うけど、オブジェクト指向というのは繋ぎ目の無い現実の情報を抽象化して、如何にシステムに落とし込むかの技法の総称なんだピヨ。
だから、あるふさんの意見を否定するとかしないとかじゃあなくて、あるふさんのオブジェクト指向が何を意味しているかわからないから困っているんだ。
みんなに先ずは伝える努力をした方がいいと思うな。

# re: 無効をサポートするオブジェクト 2008/12/26 8:18 あるふ

>>ちゃっぴさん
>接続されているかどうかは、実際に接続してみないとわからない
まさにここです。"接続されていること"を制約にとる場合、静的(コンパイル時)には絶対に保証できません
続きは次項、ダックテストで


>>774さん
>現在の)ダックタイピングは基本動的ですよ?
c++のtemplateでほぼ同等に表現できるという意味で、どちらかといえば静的というイメージが強いです。
これについては次項ダックテストで

>これは不変条件
目からうろこでした。よくよく考えてみればこれはクラスの不変条件に近いですね。
いつでも無効になることができる(値が変わる)特性から、不変ではないと思い込んでましたが、
オブジェクトが有効な時に成り立つ時のみ不変条件と考えれば、納得できます。

>利点
では、最も定義に近い表現方法である、と思ってるからです
これについては次項ダックテストで

>>ゆーちさん
前半についてはダックテストで

状態遷移については、別でエントリたてます
ただ一点補足を。
状態遷移は、大枠での状態遷移と、状態遷移を利用した狭義の手法の2つがあると考えてます
状態遷移自体が必要ないはずがありません(汗
SelfTest()自身が状態制御なら、(他の)状態遷移の手法が必要なくなるは不可能ではないはずです。
なぜSelfTest()のほうがいいと私が考えるかは、ダックテストで

>>ん?さん
本、高いですね・・。探してみます

あとのことは、共通の前提を得ていないこと、問題の焦点が伝わっていないことが問題と思います
次項ダックテストで問題の焦点を明らかにしたいです


>>Jittaさん、インドリさん
方向性はある程度示したと思うので、定義に戻ります
次項ダックテストで、現在のオブジェクト指向から私がずらしたところを焦点に取ります

そこでまるっきり伝わらないようだと、お手上げかもしれません

# re: 無効をサポートするオブジェクト 2010/07/06 17:40 true religion

一番のつっこみどころは、「SelfTest()で状態遷移が必要なくなる」でしょうか。
そんなことは不可能だと思います。
http://www.ghdhairukmart.com/
http://www.linkslondonsale.com/

# I can't believe you're not palying with me--that was so helpful. 2012/10/20 18:07 Rutendo

I can't believe you're not palying with me--that was so helpful.

# <url>http://lf1medsoc.com/|auto insurance rates</url> 2192 <url>http://aixnmr.com/|infinity auto insurance</url> kwhjs 2012/11/08 2:17 Julissa

<url>http://lf1medsoc.com/|auto insurance rates</url> 2192 <url>http://aixnmr.com/|infinity auto insurance</url> kwhjs

タイトル
名前
URL
コメント