At line 2 changed 4 lines |
クラスを定義する際にはユーザからの業務要件が基になりますが、それはシステムあるいはプログラム、つまりオブジェクト指向で言えばクラスの役割を規定しているだけです。役割を規定しただけではモノを決められないことは前述の通りです。\\ |
私たち開発者は、その役割を実現出来るモノはどういう状態であるべきかを考える必要があります。状態はデータ構造によって規定されます。\\ |
繰り返しますが、その内部の状態がどうなっているかはクラスを利用する側からはあまり重要ではありません。利用する側からは「何をしてくれるのか」が重要だからです。\\ |
しかしクラスの設計者は、「それをするためにはどうあるべきか?」を考える必要があります。 |
クラスを定義する際にはユーザからの業務要件が基になりますが、それはシステムあるいはプログラム、つまりオブジェクト指向で言えばクラスの役割を規定しているだけです。__役割を規定しただけではモノを決められない__ことは前述の通りです。\\ |
私たち開発者は、その役割を実現出来るモノはどういう状態であるべきかを考える必要があります。なぜならば、 |
*状態はデータ構造によって規定される |
からです。\\ |
繰り返しますが、その内部の状態がどうなっているかはクラスを利用する側からはあまり重要ではありません。「何をしてくれるのか?」が利用する側からは重要だからです。\\ |
しかしクラスの設計者は、 |
*それをするためにはどういうデータが必要か? |
を考えて決める必要があります。 |
At line 8 changed 2 lines |
クラスを設計する際に必要なのはデータ構造を考えることです。データ構造というのは「ひとかたまりとして扱いたい情報」です。\\ |
AクラスとBクラスを異なるクラスとして定義するということは、Aの情報のかたまりとBの情報のかたまりとの間に境界があるということです。境界がなければ同じクラスでも構わないからです。境界線を引いた上で、境界線の内側にある情報(属性)同士が同じクラスとして扱われるべきです。\\ |
クラスを設計する際に必要なのはデータ構造を考えることです。__データ構造というのは「ひとかたまりとして扱いたい情報」__です。\\ |
AクラスとBクラスを異なるクラスとして定義するということは、Aの情報のかたまりとBの情報のかたまりとの間に__境界がある__ということです。境界がなければ同じクラスでも構わないからです。境界線を引いた上で、境界線の内側にある情報(属性)同士が同じクラスとして扱われるべきです。\\ |
At line 21 changed 2 lines |
全てに共通するのが動詞となる名詞が付けられていることです。「送信する」「受信する」「制御する」「表示する」「管理する」です。\\ |
動詞になる名詞を持つということはすなわち処理に着目して定義されています。つまりそれは処理を共通化しようとしてクラス化されています。オブジェクト指向において共通化すべきなのは処理ではなくデータ構造なのです。\\ |
全てに共通するのが__動詞となる名詞が付けられている__ことです。「送信する」「受信する」「制御する」「表示する」「管理する」です。\\ |
動詞になる名詞を持つということはすなわち処理に着目して定義されています。つまりそれは処理を共通化しようとしてクラス化されており、誤っています。__オブジェクト指向において共通化すべきなのは処理ではなくデータ構造__なのです。\\ |
At line 27 changed one line |
これらは動詞を無理矢理名詞にしただけで本質は上記と変わりません。そしてこれらは「役割」を表現することがほとんどで、Interfaceとして定義されるべきものを多く含んでいます。 |
これらは動詞を無理矢理名詞にしただけで本質は上記と変わりません。そしてこれらは__「役割」を表現することがほとんどで、Interfaceとして定義されるべきもの__を多く含んでいます。 |
At line 30 changed 2 lines |
それではクラスにすべきものは何でしょうか?\\ |
システム要件の中に出てくる「物」と「結果」の2種類です。\\ |
それではクラスにすべきものは何でしょうか? システム要件の中に出てくる、 |
#物 |
#結果 |
の2種類です。\\ |
At line 33 changed 3 lines |
!!物クラス |
この種類に分類されるクラスは、実際に存在する物として人間が認識出来るものです。\\ |
データベースのマスタデータとして分類されるものです。 |
!【物クラス】 |
この種類に分類されるクラスは、実際に存在する物として人間が認識出来るものです。データベースのマスタデータとして分類されるものを多く含みます。 |
At line 46 added 3 lines |
*日付 |
*氏名 |
*画面上の座標 |
At line 42 changed one line |
!!結果クラス |
!【結果クラス】 |
At line 44 changed one line |
データベースのトランザクションデータとして分類されるものです。 |
データベースのトランザクションデータとして分類されるものを多く含みます。 |
At line 50 removed 2 lines |
*日付 |
*画面上の座標 |
At line 59 changed 4 lines |
このクラス図中の金額クラスは商品単価の金額値を持つクラスです。商品単価は「ある特定の日の商品の売り値(金額)」として定義されます。\\ |
日付クラスは、受注伝票クラスでも商品単価クラスでも利用されます。\\ |
ところがこのクラス図には問題となる部分があります。商品が受注個数を持つようになっていますが、受注個数は受注のたびに変わるため、商品の一部としてこれを持つのは無理です。正しくは、「商品/受注個数/商品単価」の組合せとする結果クラスとして持つべきです。受注明細と一般的に言われるものです。\\ |
これを訂正したのが次のクラス図です。\\ |
このクラス図中では、 |
*金額クラスは商品単価の金額値を持つクラス |
*商品単価は「ある特定の日の商品の売り値(金額)」として定義される |
*日付クラスは、受注伝票クラスでも商品単価クラスでも利用される |
と定義しています。\\ |
\\ |
ところがこのクラス図には問題となる部分があります。商品が受注個数を持つようになっていますが、受注個数は受注のたびに変わるため、商品の一部としてこれを持つのは無理です。正しくは、 |
*「商品/受注個数/商品単価」の組合せとなる結果クラスが必要 |
です。受注明細と一般的に言われるものです。これを訂正したのが次のクラス図です。\\ |
At line 75 added 8 lines |
\\ |
上記図での注意点は商品単価です。商品単価は、 |
*商品 |
*日付 |
の2つの要素によって決まりますが、このモデルでは、 |
#受注伝票が持つ日付 |
#受注明細が持つ商品 |
によって商品単価を特定します。 |
At line 65 changed 8 lines |
!!金額クラス |
商品単価クラスが持っている金額クラスを考えてみます。日本の通貨である円を前提にするならばクラスにするまでもなく、intなどの整数属性として持てばいいように思えます。\\ |
しかし金額クラスとして定義しておけば次のような振る舞いを持たせることが可能になります。\\ |
*消費税金額を返す |
*カンマと通貨記号で編集した文字列を返す |
日本において消費税計算は特に重要で、計算の基となる情報として「消費税区分(内税/外税/税額)」が必要になります。「税額」という区分値は、その金額が消費税自体を表す時に使います。また消費税率も必要ですが、これは全オブジェクトで共通なのでクラス変数として定義します。\\ |
これらを反映したのが次のクラス図です。\\ |
[amount_class.png] |
!!アプリケーションクラス |
上記の「物」と「結果」に加えて、アプリケーションプログラムそのものを具現化するクラスが必要です。次の3つがあります。 |
#レイアウトクラス |
#プログラムクラス |
#メインクラス |
At line 74 changed 12 lines |
!!日付クラス |
日付クラスは何かが実行された年月日を持っているクラスです。\\ |
日付クラスはとても汎用的に設計する必要があります。例えば、区切り文字で日付を編集した文字列を返すメソッドを実装するにしても、スラッシュ(/)で区切るメソッドやハイフン(-)で区切るメソッドなどいくつか必要になります。また、 |
*翌日の日付を返す |
*翌月の日付を返す |
*翌年の日付を返す |
なども持っていると使う側が便利です。\\ |
特に会計システムなどでサイト計算が必要な場合は、 |
*xx日後の日付を返す |
というメソッドも持ちます。\\ |
日本でのみ使われる前提のシステムの場合はロケールを意識しなくて済みますが、グローバルシステムの場合はシステムが稼働しているロケールも意識して日付編集を行う必要が出て来ます。\\ |
上記クラス図で解るように日付クラスは色々なクラスから利用されるため、色々な可能性を考えて設計する必要があります。\\ |
!【レイアウトクラス】 |
*画面レイアウトクラス |
*帳票レイアウトクラス |
画面や帳票のレイアウトを持つクラスです。Webアプリケーションの場合、画面レイアウトを専用に持つクラスがプラットフォームごとに用意されていることがあります。例えばJSPやASPです。\\ |
帳票レイアウトは出力メディアが様々なのでその時々で異なります。例えばExcelやPDF用のクラスを作成する必要があります。\\ |
これらのクラスは「__情報の配置図(レイアウト)__」であり、「物クラス」の性質を持ちます。 |
At line 97 added 39 lines |
!【プログラムクラス】 |
*画面プログラムクラス |
*帳票プログラムクラス |
*バッチプログラムクラス |
画面のボタンが押された時や帳票プログラムが起動された時に、どの物クラスや結果クラスを扱うのかという情報を持っているクラスです。\\ |
例えば入荷実績登録画面上で登録ボタンが押されると、 |
#入荷実績登録プログラムクラスの登録メソッドが呼ばれる |
#画面レイアウトクラスが持つ入力情報を受け取る |
#入荷商品ごとに在庫商品の数量を増加させる |
#入荷予定を消し込む |
というふうに、画面の情報を基に複数の結果クラスの状態を変えていく動きをします。\\ |
プログラムクラスはプログラム自身を具現化したものなので、 |
*プログラムID |
*プログラム名称 |
などの属性を持たせます。 |
|
!【メインメクラス】 |
アプリケーションが起動される入り口のクラスです。このクラスはメイン関数(メソッド)を持っているだけです。\\ |
メインは関数にならざるを得ないため、この中での処理はログ出力やエラー時の対応など最低限にとどめ、プログラムクラスのインスタンスに早く委譲するようにすべきです。\\ |
メインクラスはアプリケーションプログラム個別に作成する場合と汎用的に一つだけ持つ場合があり得ます。\\ |
|
!!アプリケーションのクラス構成 |
上記で説明したクラスを受注伝票登録画面のアプリケーションとして仕上げる場合、次のような構成になります。 |
[order_classes4.png] |
|
!!まとめ |
*中心となるクラスは「物」と「結果」 |
*動詞のクラスを作ってはいけない |
*クラスを抽出する前にオブジェクト図でまず考えてみる |
|
!!コラム |
「処理がクラスだ」と思っている開発者が大勢います。そう思っていなくても結果的にそういう実装になっている人も多いのです。\\ |
クラスを設計する際は、 |
*どんな情報が必要か? |
*どんな状態を持つ必要があるか? |
だけをひたすら追求するようにしてみて下さい。あとはそれらの組み合わせ方(関連)を考えるだけです。\\ |
それが出来るようになればきれいな設計に自然に近づきます。\\ |
\\ |
次: [小粒クラス] |