添付ファイルの追加

ログイン済のユーザのみが添付ファイルをアップロード出来ます。

添付ファイル一覧

Kind Attachment Name Size Version Date Modified Author Change note
png
utility_class1.png 5.3 kB 2 01-7-2011 01:01 ytp
png
utility_class2.png 6.4 kB 2 01-7-2011 01:02 ytp
png
utility_class3.png 8.3 kB 2 01-7-2011 01:02 ytp
png
utility_class4.png 4.3 kB 1 02-7-2011 01:24 ytp
png
utility_class5.png 4.5 kB 2 02-7-2011 02:07 ytp
png
utility_class6.png 30.7 kB 1 05-7-2011 02:05 ytp
png
utility_class7.png 9.6 kB 5 31-12-2011 20:50 ytp
png
utility_class8.png 12.3 kB 5 31-12-2011 20:50 ytp
png
utility_class9.png 7.4 kB 1 22-7-2011 03:29 ytp

This page (revision-42) was last changed on 14-8-2016 22:57 by ytp

This page was created on 12-4-2011 01:29 by ytp

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Difference between version and

At line 1 added one line
2016-05-17 に加筆しました。
At line 3 changed one line
関数を正確に表現すると、「__クラス変数にもインスタンス変数にも一切アクセスしないメソッド__」です。次の例が関数です。\\
関数を正確に表現すると、
*クラス変数にもインスタンス変数にも一切アクセスしないメソッド
です。次の例が関数です。\\
At line 17 changed 2 lines
クラス変数にもインスタンス変数にも一切アクセスしないということは、そのオブジェクトが持つデータ構造に依存しないことになります。\\
「クラスとはデータ構造」という原則に、これは明らかに反します。関数を作ってしまうとデータ構造と処理が分離されてしまい、保守性が下がってしまいます。\\
クラス変数にもインスタンス変数にも一切アクセスしないということは、
*そのオブジェクトが持つ__データ構造に依存しない__
ことになります。\\
*クラスとはデータ構造
という原則にこれは明らかに反します。そして、
*関数を作ってしまうとデータ構造と処理が分離される
ことになり、保守性が下がってしまいます。\\
At line 21 changed one line
関数を作ってはいけないのだから、__ユーティリティクラスと世間で言われるクラスも当然作ってはいけません__。ユーティリティクラスというのは関数の単なる集まりであり、データ構造を持たないクラスだからです。\\
関数を作ってはいけないのだから、
*ユーティリティクラスと世間で言われるクラスも当然作ってはいけない
ことになります。ユーティリティクラスというのは関数の単なる集まりであり、データ構造を持たないクラスだからです。\\
At line 25 changed one line
次の二つのケースでは例外的に関数を許します。
次の3つのケースでは例外的に関数を許します。
At line 27 changed one line
#別メモリ空間で稼働するシステムとの間でオブジェクトが持つデータを受け渡す場合
#異なるクラスを同一の処理で扱いたい場合
#別メモリ空間で稼働するシステムのオブジェクトが持つデータを受け取る場合
At line 30 changed 3 lines
!メイン関数
OSがアプリケーションを起動する場合、メイン関数が起点となります。OSは、起動パラメータをデータとしてメイン関数に渡します。この起動パラメータ(データ)とメイン関数(処理)は分離されざるを得ません。そのため例外となります。\\
メイン関数の中には必要最低限の処理のみを記述するようにし、業務用クラスのインスタンスに処理を早く委譲すべきです。\\
!!メイン関数
OSがアプリケーションを起動する場合、メイン関数が起点となります。OSは、起動パラメータをデータとしてメイン関数に渡します。この時、
*起動パラメータ(データ)
*メイン関数(処理)
の二者は、プログラムの外部から与えられるもの(パラメータ)とプログラム処理として分離されざるを得ません。そのため例外となります。\\
メイン関数の中には必要最低限の処理のみを記述するようにし、
*業務用クラスのオブジェクトに処理を早く委譲すべき
です。\\
At line 34 changed one line
!別メモリ空間で稼働するシステムとの間でオブジェクトが持つデータを受け渡す場合
!!異なるクラスを同一の処理で扱いたい場合
At line 52 added one line
!1.何かのメディア(媒体)に読み書きしたい場合
At line 57 changed one line
の2つが分離されます。この__「相手側のシステムとの間で受け渡す処理」を関数として実装する__必要が出てきます。相手に渡せるのはデータのみであり、そのデータをやりとりする処理が別に必要となるからです。\\
の2つが分離されます。つまり、
*相手側のシステムとの間で受け渡す処理を関数として実装する
必要が出てきます。相手に渡せるのはデータのみであり、
*そのデータをやりとりする処理を独立させた方が効率が良い場合が多い
からです。\\
At line 61 changed one line
しかし、受注伝票や発注伝票の中に「RDBに書き込む」「RDBから読み込む」ようなメソッドを持ち、その中からRDB関数(群)を利用することによって、受注伝票や発注伝票を扱うアプリケーション側からはデータ構造と処理が一体化されている正しいクラスとして扱えます。次のような形です。\\
しかし、受注伝票や発注伝票の中に「RDBに書き込む」「RDBから読み込む」ようなメソッドを持ち、その中からRDB関数(群)を利用することによって、受注伝票や発注伝票を扱うプログラムクラス側からはデータ構造と処理が一体化されている正しいクラスとして扱えます。次のような形です。\\
At line 64 changed one line
__O/Rマッパ(Object Relation Mapper)__がJDBCドライバの上位に配置されることが実際の開発では多いのですが、そのO/RマッパがRDBストレージの代理として表現されることによって、オブジェクト指向により近い実装になります。O/RマッパがJDBCドライバを隠蔽することにより、受注伝票や発注伝票などからは、__RDBオブジェクトに処理を委譲している__形を取ることが出来ます。
__O/Rマッパ(Object Relation Mapper)__がJDBCドライバの上位に配置されることが実際の開発では多いのですが、そのO/RマッパがRDBストレージの代理として表現されることによって、オブジェクト指向により近い実装になります。O/RマッパがJDBCドライバを隠蔽することにより、受注伝票や発注伝票などからは__RDBMSオブジェクトに処理を委譲している__形を取ることが出来ます。
At line 87 added 14 lines
\\
!2.異なるクラスをComparatorによって比較したい場合
JavaのAPIで提供されているjava.util.Comparatorインタフェースのcompare()メソッドは関数です。
%%prettify
{{{
public int compare(T o1, T o2)
}}}
/%
o1およびo2オブジェクトのクラスそのものが__java.lang.Comparableインタフェース__を実装していれば、Comparatorインタフェースによる比較は必要ありません。しかし次のような時があります。\\
*Comparableインタフェースを実装していないオブジェクトを比較したい
*比較したいオブジェクトが異なるクラスである
上記のような場合は自作のComparatorを作る必要が出て来ます。次のようなイメージです。\\
[utility_class9.png]\\
この項で説明した関数は、オブジェクト指向の前身である「構造化言語」の特徴を引き継いだものです。このページのタイトルは「関数禁止」となっていますが、それは安易に関数を量産してしまうことを戒めているのであって、上記のように理解した上で使うことは問題ありません。\\
At line 67 changed 2 lines
!!「層」が増えるほど関数が必要となる
前項で説明したように、外部のメモリ空間で稼働しているシステムとのやりとりが発生する境界ではデータ構造を持たない関数が必要になります。これは言い方を換えると、「RDB層」「アプリケーション層」などのような__層(Layer)があればその境界線で関数が必要になる__ということです。次の図を見て下さい。\\
!!別メモリ空間で稼働するシステムのオブジェクトが持つデータを受け取る場合
前項で説明したように、外部のメモリ空間で稼働しているシステムとのやりとりが発生する境界では、オブジェクトではなくデータのみをやりとりする必要があります。これは言い方を換えると、
#RDB層
#アプリケーション層
などのような
*層(Layer)があればその境界線で関数が必要になる
ということです。次の図を見て下さい。\\
At line 70 changed 3 lines
上の図は、一般的な3層構造アプリケーションの動きのうち、画面の情報をRDBに格納するまでの流れを表しています。層と層の間はオブジェクトをそのまま渡せないため、電文という形でデータを渡します。電文を受け取るプロセスは各層での処理の起点の役割、つまりメイン関数と同等の機能を負います。そのため関数にならざるを得ないのです。例外の1番目で書いたのとほとんど同じ理由です。\\
例えばアプリケーション層の起点ではHTTP電文を受け取ってオブジェクトへと変換します。この動きをメイン関数と比較すれば、起動パラメータがHTTP電文と替わるだけであることが解ります。Javaサーブレットを使ったWebアプリケーションの場合、サーブレットそのものがこの関数になっています。
次の例は__javax.servlet.http.HttpServlet__の__doPostメソッド__ですが、サーブレットアプリケーションにおいてリクエストを電文として受け取る処理の起点になります。レスポンスを戻り値としはいませんが、引数として受け取った__HttpServletResponseオブジェクト__に対して__返りの電文(データ)__を出力する形の関数を実装することになります。\\
上の図は、一般的な3層構造アプリケーションの動きのうち、画面の情報をRDBに格納するまでの流れを表しています。層と層の間はオブジェクトをそのまま渡せないため、
*電文という形でデータ構造を渡す
ようになっています。電文を受け取るプロセスは、
*各層での処理の起点の役割、つまりメイン関数と同等の機能
を負います。そのため関数にならざるを得ないのです。例外的に関数を許す場合の1番目で書いたのとほとんど同じ理由です。\\
例えばアプリケーション層の起点ではHTTP電文を受け取ってオブジェクトへと変換します。この動きをメイン関数と比較すれば、__起動パラメータがHTTP電文と替わるだけ__であることが解ります。Javaサーブレットを使ったWebアプリケーションの場合、サーブレットそのものがこの関数になっています。
次の例は__javax.servlet.http.HttpServlet__の__doPostメソッド__ですが、サーブレットアプリケーションにおいてリクエストを電文として受け取る処理の起点になります。レスポンスを戻り値としてはいませんが、引数として受け取ったHttpServletResponseオブジェクトに対して返りの電文(データ)を出力する形の関数を実装することになります。\\
At line 79 changed one line
結果として、上記のような__層分けを出来るだけ行わない方が本来のオブジェクト指向に近づけます__。「データと処理の分離」の発生頻度が減るからです。\\
結果として、
*層分けを出来るだけ行わない方が本来のオブジェクト指向に近づける
のです。「データと処理の分離」の発生頻度が減るからです。\\
!!まとめ
*クラス変数にもインスタンス変数にもアクセスしない処理(つまり関数)を作ってはいけない
*ただし以下は例外
**メイン関数
**異なる複数のクラスを同列視したい場合
**「層」の間
!!コラム
このページを読んで、「ユーティリティクラス無しで実際の開発が出来るわけがない」と感じた人は多いでしょう。裏返すとそれは、オブジェクト指向的でない実装が現場でいかに蔓延しているかを表していることになります。\\
ユーティリティクラス無しで実装するためには以下の二種類のクラスを見逃さずに設計することが必須です。\\
*[小粒クラス|小粒クラス]
*[リンゴ一山(ひとやま)クラス|リンゴ一個とリンゴ一山は異なるクラス]
小粒クラスは、システムをまたがった再利用を促進します。一度作れば色々な業務で利用でき、保守性を向上させます。\\
リンゴ一山クラスは、同じ処理があちこちで実装される危険性を排除します。\\
\\
これらのクラスをしっかりと設計すれば、「関数とユーティリティクラスっていらないんだ」と気付くことでしょう。\\
Version Date Modified Size Author Changes ... Change note
42 14-8-2016 22:57 4.816 kB ytp to previous
41 10-8-2016 19:57 5.217 kB JimmiXS to previous | to last cbhXdk http://www.FyLitCl7Pf7kjQdDUOLQOuaxTXbj5iNG.com
« This page (revision-42) was last changed on 14-8-2016 22:57 by ytp