技術とか戦略とか

証券レガシーシステムを8年間いじった普通のSEによるブログ。技術のみではなく趣味の戦略考察についても。

オブジェクト指向(カプセル化)

目次

https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM

-------------------------------
今回は、オブジェクト志向のカプセル化について書きたいと思います。
オブジェクト指向も参考書以上のことを書けそうにないという理由で飛ばそうと思っていたのですが、COBOLやCといった手続き型言語を使う現場からjavaを使う現場に移って、カプセル化の便利さを改めて実感したので記事にします。
もしかしたら、一般的な解説よりもこの記事の方がわかりやすいという方もいらっしゃるかもしれないので。
 
カプセル化とは、データ(変数)とそのデータに付随する手続き(メソッド)を一つのオブジェクトにまとめることを指します。
オブジェクト内のデータは、オブジェクトで定められた手続きを使用しないと操作することができません。
 
例えば、上司が遅刻した部下を叱るプログラムを作るとします。
この場合、下記のように、オブジェクト指向のプログラムでは、カプセル化された上司オブジェクトと部下オブジェクトを作成します。
上司オブジェクト…データ(従業員ID・始業時刻)、手続き(上司オブジェクトのデータのセット・上司オブジェクトのデータの取得)
部下オブジェクト…データ(従業員ID・上司従業員ID・出勤時刻)、手続き(部下オブジェクトのデータのセット・部下オブジェクトのデータの取得・叱られる)
 
その後、下記のように処理を実装します。
(①~④が事前の初期処理、⑤~⑥が主処理のイメージです)
①従業員IDを外から与え、部下オブジェクトを生成する。
②部下オブジェクトの上司従業員IDを手続きによりセットする。
③部下オブジェクトの上司従業員IDを手続きにより取得し、それを従業員IDとして与えることで上司オブジェクトを生成する。
④上司オブジェクトの始業時刻を手続きによりセットする。
⑤部下オブジェクトの出勤時刻を手続きによりセットする。
⑥上司オブジェクトの始業時刻と部下オブジェクトの出勤時刻を手続きにより取得し、それを用いて部下オブジェクトの叱られる手続きを実行する。
 
これが手続き型言語の場合は、オブジェクトという概念が存在しないため、下記のようにデータと手続きを全て公開された領域(上司に関するデータ・部下に関するデータという意識なしに自由に操作できる領域)で定義することになります。
上司データ(従業員ID・始業時刻)
部下データ(従業員ID・上司従業員ID・出勤時刻)
叱られる手続き
 
この場合、以下のような実装が可能になってしまいます。
・上司に関する処理をしているのに部下の手続きである「叱られる手続き」を使用してしまう
・叱られる手続き(部下に属する手続き)の中で上司データを書き換えてしまう
・叱られる手続きの中の処理の一部のみを外から使用してしまう
このような実装をしてしまうと、処理内容を理解しにくくなります。
また、上司の処理と部下の処理が入り乱れることでプログラム修正時の影響範囲も限定できなくなってしまいます。
(例えば、部下の叱られる手続きを改良する時に、その影響が部下だけでなく上司にも及んでしまう)
このような実装を防ぎ、保守性を確保するために、カプセル化が使われるというわけです。
 
なお、参考書では生き物をオブジェクトとする例が出されることが多く、今回の記事でも人をオブジェクトとしていますが、実務では「プリンターの設定」「画面の部品」といった概念的なものがオブジェクトになることが多いです。
しかし、概念的なものがオブジェクトとなっていたとしても、参考書や今回の記事の例と同じことが言えるので、そのことを念頭に入れて実務で使われるプログラムを見ることが重要です。

 

なお、今回の記事では取り扱いませんが、オブジェクト指向については、「カプセル化」の他に「継承」「多態性」といった概念も覚える必要があります。