オブジェクト指向言語

前章までJavaでプログラミング言語を利用して、簡易なクラスを作成し何かしらの処理を表現できるようになってきたと思います。
本章では、オブジェクト指向言語としてJavaの構文を理解してきましょう。

オブジェクト指向言語とは

オブジェクト指向言語とは、開発者が実現したい「IPOモデルにおける処理」
それぞれの目的別の「オブジェクト」単位に処理を委譲する事で実現するプログラムパラダイムです。

オブジェクトとは、以下から構成されます。

  • データ(状態、属性などの特定の情報の纏まり)
  • 処理(データの操作、オブジェクトの主目的となる処理)

オブジェクトがメッセージ(入力情報、出力情報)をやり取りし、
オブジェクトの各処理を実行する事で全体として「IPOモデルにおける処理」を実現します。

データは、「メンバーフィルード」を意味します。処理は、「メソッド」を意味します。

処理がオブジェクト枠から飛び出して表現されているのは、他のクラスから利用できることを意味します。
データと処理は、0~N個で構成されます。

オブジェクトの説明

オブジェクト指向言語を教えるときに必ず出てくるのが、「車」「バイク」「犬」「猫」等です。

私自身は、これでオブジェクト指向言語を教えるのが大嫌いです。
何故なら、そのような例えは開発現場で実際に起こり得ない事象で例えているからです。

オブジェクト指向言語を理解して頂くために、2004年~2017年の役15年間のWeb3階層アーキテクチャにおける
Webシステムの流れからオブジェクトを理解して頂きたいと思います。

入力情報と処理実行の流れ

ECサイトのAmazonや楽天で商品を検索して、商品を一覧表示する事を想像して下さい。
※.図中のブルーの色は、データ(メンバーフィルド)を意味します。
※.図中の円枠、楕円枠はオブジェクトを意味します。

  1. 利用者がWebブラウザの商品検索画面から「検索条件」を入力して「検索ボタン」を押下します。 検索結果が欲しいというリクエスト(要求)をブラウザからサーバーに送信します。
  2. urlに該当したControllerクラスの処理Aにrequest情報(オブジェクト)が渡ります。
  3. 処理Aは、入力値チェック等をした後商品検索機能の入力値としてdtoAオブジェクトを生成し、
    メンバーフィールドに設定されたServiceクラスの処理Bメソッドに検索処理を依頼します。
  4. サービスクラスの指定された処理Bメソッドがデータベースから情報を取得する役割を持つ
    Daoクラスをメンバーフィルドに所持します。
    データベースの処理を依頼するため、処理Cの入力引数となるdtoBオブジェクトを生成します。
    商品情報テーブルに情報を検索する処理Cメソッドに実行を依頼します。
  5. Daoクラスは、メンバーフィルドにデータベースへの接続オブジェクトであるコネクションを所持しています。
    処理Cメソッドは、入力情報を判定し、該当するSQLを動的に生成します。

ユーザのリクエストから開始してデータベースから情報を得るまでに、最低クラスが
Controller,Service,Dao,dtoA,dtoB,sql,Connectionの計7つあります。

出力情報と処理結果の流れ

  1. connectionオブジェクトからsqlの検索結果であるResultSetオブジェクトを処理Cに返します。
  2. Dtoクラスの処理Cメソッドでは、ResultSetオブジェクトから
    resultC(これもDtoです。)オブジェクトを生成して、結果をServiceオブジェクトの処理Bメソッドに返します。
  3. 処理Bメソッドは、Dtoの戻り値resultCからで検索結果サービスとしてresultBオブジェクトを生成し、
    呼び出し元のControllerオブジェクトの処理Aに戻り値として返します。
  4. 処理Aメソッドは、画面必要な情報としてresultBを加工したresultAを生成します。
    処理Aメソッドは、画面(HTML)を出力するためのViewクラスにresultAを渡し、HTMLの出力処理を委譲します。
  5. Viewオブジェクトは、resultAオブジェクトを基に情報を加工して、HTMLファイルを出力します。
    これをレスポンスとして、呼び出し元のWebブラウザに返す事で画面が表示されます。

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フレームワークのようなものを独自で構築している時代でした。

それ以外の方の多くは、残念ながら当時の私も含め上記図のような悪い例のソースを記述していました。

この悪い例が問題なのが、以下の点です。

  • 処理A,処理B,処理C,処理Dが他の機能での使いまわしがし難い点
  • 必然として、処理A',処理B',処理C',処理D'というような類似機能が山ほどできます。
  • オブジェクトの目的(機能)が分離せず整理整頓されない混沌とした点
  • 結合密度が高く、1つのクラスを利用すると芋ずる式に要らないクラスを必要とした。
  • 役割の分担がされずにオブジェクトの関係がスパゲティソースになりやすい。

オブジェクトのクラス設計が確立した日

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)すなわち処理を表現するために
用意されたプログラム構文上の単語です。

オブジェクト指向言語の基本概念

オブジェクト指向言語では、以下の基本概念を実現させるための構文を用意しています。

  • クラス(Classes)
  • オブジェクト(Objects)
  • インスタンス(Instance)
  • メソッド(Method)
  • 継承(Inheritance)
  • カプセル化(Encapsulation)
  • 多様性(Polymorphism[ポリモルフィズム])
  • 抽象化(Abstraction)
  • メッセージ解析(Message Parsing)
    ※.XML,JSONなどのデータをオブジェクトに変換する機能。

次頁以降に各事項について説明します。

クラスの4パターン

前述したWeb3階層アーキテクチャに出現するクラスを整理整頓すると4パターンのいずれかに該当します。

1.データとプロパティのみ

オブジェクトの目的は、意味ある情報の塊を管理します。

情報の塊は、メンバーフィルドに定義され、プロパティメソッドで公開されます。

ビジネスロジックなどの処理を一切持ちません。

Contorller,Sercie,Daoなの入力情報、出力情報として利用され、デザインパターンでData Transfer Object(DTO)を意味します。

2.処理のみ

オブジェクトの目的は、意味ある処理の塊を管理します。

処理の塊は、メンバーフィルドを一切持たず、情報は利用するクラスからオブジェクトを渡します。

これは、ユーティリティクラスやDtoに対する定型処理など簡易のロジックを纏めたクラスです。

Contorller,Sercie,Daoなどで関数的に利用されます。

3.処理と処理のためメンバーフィルド

オブジェクトの目的は、ビジネスロジック、データアクセス、画面作成など決まったロジックを管理します。

主な処理を実現するために、他の処理専用のオブジェクトをメンバーフィルドに1~N定義します。

メンバーフィールドに設定したオブジェクトに処理の一部を委譲します。

総合的に1つのメソッドで1つの目的のあるビジネスロジックを実現するオブジェクトです。

4.その他混合パターン

オブジェクトの目的は、オブジェクトの所持するメンバーフィールドに対して加工・操作を行います。

他クラスと処理を委譲して、メソッド内でメンバーフィルドを操作し、
処理終了後のこのオブジェクト自体を呼び出し元に結果として返します。

これは、1.と3.の混合パターンで、クラス定義でできる全ての事を実行しています。

このパターンのクラス設計は、高度なクラス設計能力を必要とされます。

このパターンを用いたクラスは、オブジェクト指向言語のスキルに依存し易く、
品質にバラつきがでやすいパターンなので注意が必要です。

私は設計時や開発時にこのクラスのパターンが出現した場合には、他のパターン以上にレビュー回数を増やし、
運用性の低下やスパゲティクラスにならないようにしています。

クラスの定義について

クラスの定義については、 初めてのJavaJavaの構文を主体に Javaの基本章で説明しています。

最後に

オブジェクト指向言語は、Javaに関わらず何かしらの処理を実現しようとすれば、
品質の良し悪しに関わらず実現できてしまいます。

オブジェクト指向言語は、クラス設計でクラスの定義を鮮麗させる事で、
拡張性、運用性、再利用性などを高めるための言語です。

沢山の1流のソースファイルと書籍を読むことと1行でも論理的に深く考えてソースファイルを書く事で、
オブジェクト指向言語らしいクラス設計が自然と身につける事ができます。

そのオブジェクトは、「何の目的」のために作成するか
そのオブジェクトは、「何を表す」ために作成するか