前章までJavaでプログラミング言語を利用して、簡易なクラスを作成し何かしらの処理を表現できるようになってきたと思います。
本章では、オブジェクト指向言語としてJavaの構文を理解してきましょう。
オブジェクト指向言語とは、開発者が実現したい「IPOモデルにおける処理」を
それぞれの目的別の「オブジェクト」単位に処理を委譲する事で実現するプログラムパラダイムです。
オブジェクトとは、以下から構成されます。
オブジェクトがメッセージ(入力情報、出力情報)をやり取りし、
オブジェクトの各処理を実行する事で全体として「IPOモデルにおける処理」を実現します。
データは、「メンバーフィルード」を意味します。処理は、「メソッド」を意味します。
処理がオブジェクト枠から飛び出して表現されているのは、他のクラスから利用できることを意味します。
データと処理は、0~N個で構成されます。
オブジェクト指向言語を教えるときに必ず出てくるのが、「車」「バイク」「犬」「猫」等です。
私自身は、これでオブジェクト指向言語を教えるのが大嫌いです。
何故なら、そのような例えは開発現場で実際に起こり得ない事象で例えているからです。
オブジェクト指向言語を理解して頂くために、2004年~2017年の役15年間のWeb3階層アーキテクチャにおける
Webシステムの流れからオブジェクトを理解して頂きたいと思います。
ECサイトのAmazonや楽天で商品を検索して、商品を一覧表示する事を想像して下さい。
※.図中のブルーの色は、データ(メンバーフィルド)を意味します。
※.図中の円枠、楕円枠はオブジェクトを意味します。
ユーザのリクエストから開始してデータベースから情報を得るまでに、最低クラスが
Controller,Service,Dao,dtoA,dtoB,sql,Connectionの計7つあります。
connectionから開始して画面を返すまでに最低クラスが、ResultSet,resultC,resultB,resultA,Viewの5つが必要になります。
全体を通して、合計12個のクラスが必要なります。
何故そのようにクラスが多くできるかといえば、Controller,Service,Daoクラスそれぞれ単独に
決まりきった機能を表現し、どのクラスにも依存しないように設計するとそれぞれの処理に
入力情報を格納するDtoクラス、出力情報を格納クラスが最低1セットできます。
それぞれのクラスはどこのクラスから実行されるかは意識しません。
それぞれのメソッドの主機能を実行することだけに集約します。
これによりクラスそれぞれの処理の目的が明確になり、結合密度が疎結合になります。
結果として、どのクラスから呼ばれても利用できる汎用性の高いクラスになります。
このクラスの単独性と関係性を明確にする方法がオブジェクト指向言語です。
JavaEE(Servlet)が出始めた1998年からStrutsが誕生した2001年までに起きていた悪い事例です。
この当時は、Javaにおけるクラス設計やオブジェクト指向言語らしいソースを記述できるエンジニアは、少なかったです。
昔からC言語、smallTalkなどを5年以上プログラム経験した方で更にオブジェクト指向言語及びJavaを海外のサイトから
英文の情報を山ほど読み理解した人だけが、オブジェクト指向言語らしいクラスの構成をしていました。
そのような方は、100人に1人下手すると1000人に1人ぐらいの根っからのプログラム好きな人に限られていました。
そのごく一部の方が、Strutsフレームワークのようなものを独自で構築している時代でした。
それ以外の方の多くは、残念ながら当時の私も含め上記図のような悪い例のソースを記述していました。
この悪い例が問題なのが、以下の点です。
Web3階層のクラス設計を2017時点ここまで鮮麗されてきたのは、
Rod Johnson著書「Expert One-on-One J2EE Design and Development」が出版されてからです。
更にこの著書をベースにしたフレームワーク「SpringFramework」が出現したことにより、
Web3階層におけるWebサービスのクラス設計が日本でも浸透し、品質が向上しました。
用語 | 説明 |
---|---|
オブジェクト (Object) |
オブジェクトは状態(state)と振る舞い(behaviors)を持ち何かしらの意味・目的を具現化されたものです。 1つのオブジェクトは、1つのクラスから生成されたインスタンスです。 私は、オブジェクト指向を説明するときには、 「データ(状態、属性など)」と「処理(機能、主目的を実現する処理)」と説明します。 処理は、機能でも適した日本語訳だと思います。 |
クラス (Class) |
クラスは、その型のオブジェクトがサポートする動作、状態を記述する テンプレート、青写真として定義することができます。 即ち、クラスとはオブジェクトを生成するための設計図または雛形といえます。 |
インスタンス (Instance) |
インスタンスとは、利用者がオブジェクトを利用するために1つのクラスから生成されたオブジェクトの意味です。 クラスの対義語として、利用されます。 |
メンバーフィールド | オブジェクトの状態(state)即ちデータを表現するために用意されたプログラム構文上の単語です。 |
プロパティ | メンバーフィールドをgetter/setterで他のクラスへ公開したメソッドです。プログラム構文上の単語です。 |
メソッド | オブジェクトの振る舞い(behaviors)すなわち処理を表現するために 用意されたプログラム構文上の単語です。 |
オブジェクト指向言語では、以下の基本概念を実現させるための構文を用意しています。
次頁以降に各事項について説明します。
前述したWeb3階層アーキテクチャに出現するクラスを整理整頓すると4パターンのいずれかに該当します。
オブジェクトの目的は、意味ある情報の塊を管理します。
情報の塊は、メンバーフィルドに定義され、プロパティメソッドで公開されます。
ビジネスロジックなどの処理を一切持ちません。
Contorller,Sercie,Daoなの入力情報、出力情報として利用され、デザインパターンでData Transfer Object(DTO)を意味します。
オブジェクトの目的は、意味ある処理の塊を管理します。
処理の塊は、メンバーフィルドを一切持たず、情報は利用するクラスからオブジェクトを渡します。
これは、ユーティリティクラスやDtoに対する定型処理など簡易のロジックを纏めたクラスです。
Contorller,Sercie,Daoなどで関数的に利用されます。
オブジェクトの目的は、ビジネスロジック、データアクセス、画面作成など決まったロジックを管理します。
主な処理を実現するために、他の処理専用のオブジェクトをメンバーフィルドに1~N定義します。
メンバーフィールドに設定したオブジェクトに処理の一部を委譲します。
総合的に1つのメソッドで1つの目的のあるビジネスロジックを実現するオブジェクトです。
オブジェクトの目的は、オブジェクトの所持するメンバーフィールドに対して加工・操作を行います。
他クラスと処理を委譲して、メソッド内でメンバーフィルドを操作し、
処理終了後のこのオブジェクト自体を呼び出し元に結果として返します。
これは、1.と3.の混合パターンで、クラス定義でできる全ての事を実行しています。
このパターンのクラス設計は、高度なクラス設計能力を必要とされます。
このパターンを用いたクラスは、オブジェクト指向言語のスキルに依存し易く、
品質にバラつきがでやすいパターンなので注意が必要です。
私は設計時や開発時にこのクラスのパターンが出現した場合には、他のパターン以上にレビュー回数を増やし、
運用性の低下やスパゲティクラスにならないようにしています。
クラスの定義については、 初めてのJavaと Javaの構文を主体に Javaの基本章で説明しています。
オブジェクト指向言語は、Javaに関わらず何かしらの処理を実現しようとすれば、
品質の良し悪しに関わらず実現できてしまいます。
オブジェクト指向言語は、クラス設計でクラスの定義を鮮麗させる事で、
拡張性、運用性、再利用性などを高めるための言語です。
沢山の1流のソースファイルと書籍を読むことと1行でも論理的に深く考えてソースファイルを書く事で、
オブジェクト指向言語らしいクラス設計が自然と身につける事ができます。