「オブジェクト指向」カテゴリーアーカイブ

オブジェクト指向用のカテゴリー

インスタンス変数とローカル変数の違い

Webシステムは基本的に複数人で同時利用されるのが前提のため、マルチスレッドアクセスを考慮した設計・実装を行う必要があります。業務でJavaの各変数とスレッドセーフについて考える機会があったので、「インスタンス変数とローカル変数の違いとスレッドセーフとの関係」について今回は整理してみようと思います。

Javaでの変数毎のメモリ管理イメージ


    上記は変数毎のメモリ管理イメージとなります。Javaではクラス変数やインスタンス変数はヒープ領域と呼ばれる共有メモリ領域へ保存されます。複数のスレッドで共有され別のスレッドに書き換えられる可能性があり,スレッドセーフではありません。対してローカル変数はJavaスタックと呼ばれるスレッド固有メモリ領域へ保存されます。スレッド固有領域なので別のスレッドに書き換えられる可能性はないのでスレッドセーフとなります。

インスタンス変数とは

  • サンプルコード
  • メソッドの外に記述します。staticは付けません(staticが付くとクラス変数になります)。
  • ヒープ領域と呼ばれる共有メモリ領域へ保存される為、宣言しただけではスレッドセーフにはなりません。
  • スレッドセーフを保つ為には初期化する必要があります。
    • コンスラクタで初期化
    • インスタンス宣言時に初期化
    • 最初のget時に初期化
  • 他のスレッドからの更新を防ぐ為、修飾子はprivateにする必要があります。
  • 当該クラス内の任意のメソッドから参照可能となります。

ローカル変数とは

  • サンプルコード
  • メソッド内に記述します。
  • そのメソッドが実行中の間だけ有効となります。
  • Javaスタックと呼ばれるスレッド固有メモリ領域へ保存される為、スレッドセーフとなります。

DTOとVOの違い

様々な業務でシステム開発をしているとDTOやVOというクラスが出てきて違いが曖昧になってくる事があるので両者の違いについて整理しておきます。

DTO(Data Transfer Object)

  • 基本的には値をまとめて受け渡す事のみを目的とするクラス。
  • DTO(Data Transfer Object)はデザインパターンの一つ。
  • 過去、J2EEではVO(Value Objects)と呼ばれていた。
  • VOとは違い、値は変更可能なのでsetterメソッドを持つ。

VO(Value Objects)

  • VO(Value Objects)もデザインパターンの一つ。
  • インスタンスコンストラクタでプロパティを初期化してプロパティの変更(set)は外から出来ないようにするクラス。
  • VOは不変である事が前提のため、MVC間で使用する場合にはDTOを用いた方が相性が良い。
  • VOクラス例

オーバーロードとオーバーライドの違い

javaでプログラミングしていると必ずと言っていいほど「オーバーロード」や「オーバーライド」という言葉が出てきます。復習も兼ねて今回は両者の違いについて整理してみます。

オーバーロードとは

  • 同一クラス内の同一メソッド名で、「引数の型」、「引数の数」、「引数の並び順」のいずれかが異なるメソッドを複数定義すること。
  • 同一クラス内の同一メソッド名でも「戻り型」、「アクセスレベル」、「引数名」、「throws節」が不一致している場合はオーバーロードとは見做されないのでコンパイルエラーになります。
  • Javaでのオーバーロード実装例

    JUnit

    実行結果(コンソール)

    得意なプログラミング言語は「JavaScript」です。
    私の母国は「日本」です。
    得意なプログラミング言語は「JavaScript」です。

オーバーライドとは

  • 親クラス(スーパークラス)で定義されているインスタンスメソッドを、子クラス(サブクラス)で再定義すること。
  • 親クラス(スーパークラス)のメソッドを変更することは出来ませんが、子クラス(サブクラス)に特化した機能を付与する事は可能です。
  • アクセス修飾子が「private」以外でオーバーライドは適用対象となります。(例:「public」・「protected」)
  • オーバーライドする側はオーバーライドされる側と「戻り型」、「メソッド名」、「引数型」、「引数の数」が全て一致する必要があります。どれか一つでも異なる場合はオーバーライドとは見做されません。
  • Javaでのオーバーライド実装例

    スーパークラス(親クラス)

    サブクラス(子クラス)

    JUnit

    実行結果(コンソール)

    得意なプログラミング言語はJavaです。
    得意なプログラミング言語はCです。

MVCモデルについて

Webアプリケーションを作成する上で重要になってくるのがMVCと呼ばれるソフトウェア設計モデルです。

MVCとは

  • ソフトウェアを「Model」・「View」・「Controller」という3要素の組み合わせでシステムを実装する方式です。

MVCモデルのイメージ

  • Model
    • Modelは、システムの中で処理の中核を担うビジネスロジック(アプリケーションが扱う領域のデータと手続き)を担当するシステムの本体部分に当たります。
    • データベースなどに格納された生のデータを隠蔽し、抽象化された形のAPIを通じて他のモジュールからのアクセスをコントロールするモジュールです。
    • Modelは入出力や表示といった処理は行わず、業務モデルの実装といった部分を担当します。
    • アプリケーション特有のルールやロジック(ビジネスロジック)を持ち、データの整合性に絶対の責任を持ちます。
    • データの変更をViewに通知するのもModelの責任となります。(Modelの変更を通知するのにObserverパターンが用いられることもあります)。
    • 多くのアプリケーションではデータの格納に永続的な記憶の仕組み(データベースなど)が使われています。
    • MVCの概念では、データの(UI以外の)入出力は取り扱わないので、データアクセスも本来MVCの概念の範疇を超えるものではありますが、敢えて言えばModelの中に隠蔽されると考えられます。
    • J2EEでは JavaBeans、EJBがモデルを担当します。
    • サーバサイドでいうserviceに関する処理を行なっています。
  • View
    • Viewは、表示、入出力といった部分を担当します。
    • Modelのデータを取り出してユーザが見るのに適した形で表示する要素です。
    • UIへの出力を担当します。
    • Modelが提供する抽象化されたデータを、どのような形式で人へ見せるのかを記述したモジュールです。
    • GUIアプリケーションの場合、使用するGUI部品や画面上のレイアウトを指定します。
    • 必要な情報をModelから取り出して画面へ表示させる為の処理を行います。
    • J2EEではServletやJSPで実装します。
    • 一般的な HTML表示に関してはJSP、そのほかの特殊なデータ(バイナリデータ)を出力する場合は Servletを用いるのが標準的な使用方法となります。
  • Controller
    • コントローラは、ViewとModelを制御します。
    • 自分自身では表示を行ったりロジックの実行は行わず、Viewからの入力に応じて、必要なロジックの実行をModelに依頼し、その結果表示をViewに依頼します。
    • ユーザの入力(通常イベントとして通知されます)に対して応答し、それを処理する要素です。
    • UIからの入力を担当します。
    • ViewとModelの間に位置して、ユーザーにどんな順序でデータを見せて行くとか、Viewを通したユーザーからの入力をModelへのAPIコールへとマッピングするのがこのモジュールの役割となります。
    • ModelとViewに変更を引き起こす場合もありますが、直接描画を行ったり、Modelの内部データを直接操作したりはしません。
    • J2EEではServletでControllerを実装します。
    • イベントはコントローラで受け取り、画面上構成するボタン(イベント)の数だけ処理があります。

MVCモデルのメリット

  • 並行開発
    機能毎の分離が明確になることにより独立性が確保出来る。
    ・開発の分業が可能になる
    ・専門家を配置しクオリティーを上げる事が可能になる
  • 再利用性
    コンポーネント間の依存性が最小限に抑えられる為、他の部分の影響を受けにくい。
    ・コンポーネントの再利用がしやすくなる
    ・他のコンポーネントの変更が原因で、複数の担当者が同一のソースに対してメンテナンスを行う、というような事態を避けることもでき、保守性も確保される

インスタンスとオブジェクトの違い

どうもJavaを学習していると色々なサイトで「インスタンス」と「オブジェクト」が混同して使用されている為、私も含めオブジェクト指向の初心者の方には混乱する一因にもなっています。一度、自分の頭の中の整理も含めておさらいしてみようと思います。

基本的にオブジェクト指向では、すべてのモノや事柄を「オブジェクト」として捉えています。この時点ではクラスという概念がなくても、オブジェクトは存在します。一方、インスタンスとはクラスという概念を具象化したものです。Java言語においては、すべてのオブジェクトはクラスから作られますので、すべてのオブジェクト=インスタンスとなります。このことから開発現場では「インスタンス」と「オブジェクト」を使い分けずに使用することが多い為、初心者の方が混乱する一因になっているようですね。

  1. ここで少し身近な具体例として「パソコン構成」をクラスに置き換えて考えてみましょう。
  2. パソコンの構成がイメージ出来たでしょうか?
    このままではただの設計図でしかないので、次にパソコンを生成するクラスを作成してみましょう。
  • 12行目でパソコン・クラスのインスタンスを生成しています。この作業を「パソコン・オブジェクトの生成」とか「パソコン・クラスのインスタンス化」という表現をしています。
  • さらにパソコンを注文するお客様のクラスを用意します。
    • パソコン製造業者がいないと、お客様が注文する相手がいませんので、7行目でパソコン製造業者・クラスのインスタンスを生成しています。
    • 10行目でパソコン製造業者のacceptPcOrderメソッドを呼び出す事により、パソコン・クラスのインスタンスを生成し、お客様クラスで使用出来るようにしています。
  • これらのソースコードから「クラス」・「オブジェクト」・「インスタンス」を一覧化してみるとこのようなイメージとなります。
    • 項目     サンプルソースの例だと                備考
      クラスPc、PcManufacture、Customer設計図
      オブジェクトクラスオブジェクト:Pc、PcManufacture、Customer
      インスタンスオブジェクト:pcIns、pcManIns
      設計工程で用いる俗語のようなもの。製造工程ではインスタンスと同義語と思ってもさほど差し支えない。
      インスタンスpcIns、pcManInsクラスを具象化した実体

    どうでしょうか?
    この解説である程度ご理解が進めば幸いです。それにしても日本語って難しいですね・・・。