純粋オブジェクト指向言語を思考実験してみるテスト

関数言語風なところ(LINQ)や、手続き型の関数の羅列を取り除いて、オブジェクト指向オンリーでプログラミングをする言語を妄想(笑)してみます。個人的には、純粋オブジェクト指向言語は Java がそれに近いのですが、もうちょっと何とかするいう形で。

まず、オブジェクト指向言語の重要な要素を挙げると、

1)カプセル化(隠蔽化)できる。
2)ポリフォリズム(多態化)できる。
3)継承関係がある。

なところです。

ここで、焦点を当てるのは「カプセル化」です。
もともと、オブジェクト指向の最初は、オブジェクト同士のやりとは「メッセージ」を使ってやり取りをしています。

objectA -> message -> objectB

のような繋がりになります。このメッセージ(message)は、objectA のメソッドなのか、objectB のメソッド(リスナー?)なのかは、定義されません(とか思っています)。

また、メソッド(関数)の呼び出しは、C言語やC++の表記上、複数の引数とひとつの戻り値、という決まりがありますが、実は戻り値は複数でも構わないのです(F# のタプルと同じですね)。

objectA.Method
{
  (retA, retB, ... ) = objectB.Method(paramA, paramB, ... )
}

な形です。

さて、手続き型の流れの場合は、if 文を使ってフロー制御をしますが、純粋オブジェクト指向の場合は if 文の扱いは、ちょっと慎重になります。

if ( a != null ) {
  if ( b != null ) {
    objB.Method( a, b );
  }
}

のように呼び出し前にチェックを入れますが、純粋オブジェクト指向では呼び出し時のチェックをしません。
これは、パラメータの整合性のチェックは、呼び出されたオブジェクト側の責務であり、呼び出し側では判断がつかないためです。もう少し詳しく言うと、隠蔽化を進めるとどのパラメータが正常値であるのかは、呼び出されたオブジェクトしか分かりません。

なので、責務を明確にするために、

// 呼び出し側では、パラメータチェックをしない
objB.Methd( a, b )

// objB の中でパラメータチェックをする
void objB.Method( string a, string b ) {
  if ( a == null ) return ;
  if ( b == null ) return ;
  // メソッド内の処理をする
}

この場合、objA から objB への問い合わせが非常に多く発生するため、パフォーマンス的には良くない(と想像される)のですが、オブジェクト指向の視点から言えば、これが正しいのです。なお、オブジェクト指向でのメソッド呼び出しのコストは「0」となっています。なので、呼び出しが多くても少なくてもスピードは関係ありません(ということになっています)。

この部分、責務を明確にする、ということで、objA で判別するべきか、objB で判別するべきか、というので見解が分かれそうですよね。例えば、次のコードを見てください。

if ( a == "masuda") {
  objB.Method( a, b );
}
// objB の中でパラメータチェックをする
void objB.Method( string a, string b ) {
  if ( a == null ) return ;
  if ( b == null ) return ;
  // メソッド内の処理をする
}

こうなっていた場合、a == “masuda” は何を意味するのでしょうか?ここだけ見ると、変数 a の内容が “masuda” の時に、objB.Method を呼び出す、という条件にしかならないので、これがオブジェクトの内部を考慮してのものなのか、オブジェクトを呼び出すときの条件なのかが判断がつきません。なので、他のところで、

if ( a == "tomoaki" ) {
  objB.Method( a, b );
}

と違う値で呼び出していることを確認した時に、オブジェクトの呼び出し側がつけている条件(呼び出されているクラスの前提条件ではない)ということが判断できます。
なので、書き方として、

・呼び出し側で判断する制御文
・隠蔽化を強化するための制御文

の2つを区別しないといけません。

objB.Method( string a, string b ) {
	// 前提条件
	if ( a != null ) {
	if ( b != null ) {
	// 処理内容
	if ( a == "masuda" ) {
		objC.Method( a );	
	}
	}}
	return ;
}

のように書き分ける必要があるのですね。
たしか、アスペクト指向の書き方として、そんなのがあった覚えがあります。


obj.Method.Before( string a, string b ) {
	if ( a == null ) return ;
	if ( b == null ) return ;
}
obj.Method( string a, string b ) {
	// 処理内容
	if ( a == "masuda" ) {
		objC.Method(a);
	}
	return ;
}
obj.Method.After( string a, string b ) {
	...
}

Method.Before では、本体 method の前処理を担当して、主にパラメータをチェックします。
Method.After では、後処理を担当します。

…と書いたところで、力尽きました orz もうちょっと大雑把に議論したほうがいいみたい。

カテゴリー: 開発 パーマリンク