ふみあきのこと

ブラック企業に学ぶオブジェクト指向!カプセル化・継承・ポリモーフィズムをわかりやすく解説

プログラミング初心者にとって、オブジェクト指向はかなり厄介な概念です。

私も苦労しました。

まわりの人に聞いても、ふわっとした答えしか返ってきませんからね。

 

というのも、「オブジェクト指向とは?」って「人生とは?」と同じくらい曖昧なので、答える側も困るわけです。

ほかのサイトでも、以下のように書かれていました。

 

明確な答えがないのだから、ざっくり雰囲気理解しておけばいい。

出典:エンジニアの入り口

 

というわけで今回は、オブジェクト指向の雰囲気をざっくり理解できるように、わかりやすい例を用意しました。

みなさんの大好きな、ブラック企業をモデルにした解説です。

 

オブジェクト指向の基本である、以下3つを説明します。

  1. カプセル化
    →ぶっ倒れるまで働き続けろ!
  2. 継承
    →労働基準法?なにそれおいしいの?
  3. ポリモーフィズム
    →お前ら全員ぶっ倒れるまで働け!

 

【カプセル化】ぶっ倒れるまで働き続けろ!

オブジェクト指向の基本、ひとつ目はカプセル化です。

以下のような解説が一般的ですね。

  • 外部からのアクセスを遮断する
  • 公開したくないデータを隠す
  • クラスの中身を意識させない

 

「なるほど…、わからん!」って感じではないでしょうか。

それでは、今回モデルになっていただくブラック企業の面々に登場してもらいましょう。

以下の2名です。

  1. 社長クラス(Shacho)
  2. 社畜クラス(Shachiku)

 

社長クラスと社畜クラス

まずは、社長クラス(Shacho)

社畜をひとりだけ雇っているとして、社畜クラスのフィールド変数(_shachiku)を定義しています。

 

あとは、社畜の体力(HP)がゼロになるまで働かせるメソッド(OrderShachiku)

ぶっ倒れたらもう役に立たないので、休憩(Rest)させてあげます。

 

つぎに、社畜クラス(Shachiku)

仕事をするために必要な体力(_hp)をフィールド変数として定義。

「こいつ疲れてきてるな…」とかは他の人でもわかるので、体力はプロパティ(HP)で公開してあげます。

 

あとは、働くメソッド(Work)と休むメソッド(Rest)

働けば体力(_hp)が減るし、休めば回復します。

 

体力をカプセル化する理由

ここでポイントになるのは、社畜クラスの体力(_hp)が private になっていること。

つまり、カプセル化です。

社長クラスを含め、ほかの人からは直接アクセスできません。

 

では、なぜ直接アクセスできないようにするかというと、先ほど触れた以下の2点ですね。

  • 公開したくないデータを隠す
  • クラスの中身を意識させない

 

公開したくないデータを隠す

社畜クラスの体力(_hp)は、ほかの人に公開するものではないです。

それはなぜか。

公開するのは不自然だからです。

 

オブジェクト指向は、現実世界の考え方をプログラミングに反映するものですからね。

現実的に考えると、以下のようになります。

  • 社畜の体力をしらべる
    →可能
  • 社畜の体力を増減する
    →不可能

 

「調子はどうだ?」って聞いたり、顔色を見たりで、社畜の残り体力はわかりますよね。

でも、ほかの人がおもむろに、社畜の体力を増減させることは不可能です。

プロパティのGetterを公開していて、Setterが非公開なのは、それが理由。

 

カプセル化せずに体力(_hp)を Public にすると、以下のようなことが起こりえます。

社長クラスによって体力を引き上げ、1ヵ月で720時間くらい働かせる裏技。

 

でも、現実世界でそんな超人が生まれることはあり得なくて、超異常事態なわけです。

つまり、現実世界のバグ

 

そんなバグは起こったらダメだから、体力(_hp)にアクセスできるのは社畜クラスの中だけにしよう。

そういうお話。

そうしないと、社畜の体力がバグったときに、原因調査にめちゃくちゃ時間かかりますから。

 

以下のようなイメージですね。

【カプセル化した場合】
・ほかの人は社畜をドーピングできない
・社畜が自分でドーピングしたんだろ?
社畜クラスの中だけ調べろ!

【カプセル化していない場合】
・だれがドーピングした!?
・社長か!?同僚か!?取引先か!?
容疑者が多すぎだろハゲ!

 

クラスの中身を意識させない

それから、カプセル化することで社長クラスの仕事を減らすことができます。

オブジェクト指向が登場するまでは、社長がいつも社畜の面倒をみていました。

以下の3つです。

  1. 社畜に仕事をさせる
  2. 社畜の体力を減らす
  3. 社畜を休ませる

 

でも、現実的に考えると「②社畜の体力を減らす」って、社長がすることではないですよね。

「なんでワシがせなあかんねん」ってなります。

コードにすると以下のとおり(赤枠の行が増えた)

 

これだと社畜を管理することにコストがかかって、社長が大変です。

将来的に、上司クラスが現れたらどうなるか。

社長だけでなく、上司も社畜の体力(_hp)を管理しないといけないですね。

 

それに、現実的に考えても不自然です。

「お前、いまから体力マイナス10な!」とかありえないですよね(神様は例外として)

社畜の体力が増減するのは、本人が働いたり休んだりしたことによる副次的な結果であるはず。

 

コードにすると以下のとおり。

 

そこらへんも含めて、やはり社畜の体力(_hp)はカプセル化するべきなのです。

働くか休むことによって、社畜自身に体力を管理させる。

そうすると、社長も上司も社畜を管理するコストから解放されます。

 


【継承】労働基準法?なにそれおいしいの?

オブジェクト指向の基本、ふたつ目は継承です。

これは簡単ですよ。

労働基準法と就業規則みたいな親子関係です。

 

ホワイト企業の就業規則

とはいっても、私は労働基準法に精通していないので変なところがあるかもしれません。

でも、イメージはつかめるかと。

 

まず、労働基準法がこんな感じだとします。

ただの例なので、ツッコミはなしね。

【労働基準法】
1. 労働時間は1日に8時間とする
2. 休日は1週間に2日とする

 

これをコードにすると、こうなります。

RodoKijunho というクラスです。

 

お次は就業規則ですが、とりあえずホワイト企業用のものをつくってみましょう。

【就業規則 ホワイト版】
1. リフレッシュ休暇は年10日とする
2. その他は労働基準法に準じる

 

「労働基準法に準じる」っていうのが、まさしく継承のことです。

コードにするとこんな感じ。

RodoKijunho を継承した ShugyoKisokuWhite です。

 

親クラスの労働基準法(RodoKijunho)にあるものは、それを継承した子クラスにすべて引き継がれます

なので、労働時間は8時間、週休は2日…などは、定義しなくても大丈夫。

強いて言うなら、継承するクラスを指定するくらいですね(上画像の赤枠)

 

で、「継承のなにがおいしいの?」って話なんですが、以下のとおりです。

  • 同じコードが量産されない
  • 変更するのは1ヵ所でOK
  • つまり、保守性の向上!

 

就業規則は会社の数だけ存在するので、言うまでもなくめちゃくちゃ多いです。

多分、1000万とか(もっとかな?)

それだけあるのに、労働時間や週休のルールがひとつずつ書いてあったらどうなるでしょうか。

 

「労働基準法の労働時間を7.5時間にします!」とか言い出したら、すべての就業規則を書き直さないといけないですよね。

めちゃくちゃ大変。

 

なので、「労働基準法に準じる」っていう文言だけ入れとこうっていうお話。

C#なら “: RodoKijunho”、Javaなら “extends RodoKijunho” など。

労働基準法だけ直せば、すべての就業規則に即反映です。

 

ブラック企業の就業規則

ついでに、ブラック企業の就業規則もつくってみました。

こんな感じ。

【就業規則 ブラック版】
1. 労働時間は1日に20時間とする
2. 休日は労働基準法の1日減とする
3. その他は労働基準法に準じる

 

コードは以下になります。

クラス名は ShugyoKisokuBlack

 

ここでのポイントは、就業規則ブラック版が労働基準法のルールを”上書き”していること。

いわゆる「オーバーライド」です。

労働基準法就業規則
労働時間8時間20時間
週休2日2 – 1日

 

労働時間については、労働基準法のルールがいくらホワイト化しても関係ありません。

世間では7時間になっても、ブラック企業では20時間のまま。

週休については「労働基準法の週休 – 1日」なので、世間よりもすこしブラックな状態が維持されますね。

 

実際のプログラミングでは、まるまる上書きするケースはあまりないと思います。

親クラスの処理結果を引き継いで、なにか付け足すときが多いですね。

上の例でいうと、週休みたいな感じ。

 

【ポリモーフィズム】お前ら全員ぶっ倒れるまで働け!

オブジェクト指向の基本、三つ目はポリモーフィズムです。

これはなかなか難しい。

ひと言で強引に説明するなら、「お前ら全員はたらけ!」という社長からのひとつの号令で社畜たちが別々の仕事をこなす感じです。

 

社長クラスの部下が増えた

先ほど助っ人として活躍した、社長クラスと社畜クラスを呼び戻しましょう。

ちょっと見ない間に社長はパワーアップして、社畜を3人ゲットしました。

 

せっかく3人もいるので、それぞれの社畜に担当の仕事を与えたとします。

たとえば、以下のとおり。

  • 社畜1:営業
  • 社畜2:総務
  • 社畜3:開発

 

このとき、社長は社畜に対してどのように命令を出すべきか…というのがポリモーフィズムの観点。

まず、なにも工夫しなければ以下のようになります。

 

正直なところ、上記は最悪のパターン。

スパゲティコードに突入です。

デメリットは以下のとおり。

  1. 社長クラスがIF文で忙しくなる
  2. 社畜クラスのメソッドが激増
  3. ほかの社畜が増えると更に悪化

 

とくに、3つ目がしんどいですね。

経理や設計など、ほかの社畜が増えると上赤枠のIF文がどんどん増えていきます。

かといって、社畜クラス自身に仕事を切り替えさせたら、その中でIF文が大量にできる。

 

結局のところ、社長クラスか社畜クラス、どちらかにIF文の連鎖が誕生します。

“IF文を増やすたびにバグを生むリスクにさらされる”ので、かなり最悪です。

 

IF文をクラスに変換する

ここで、オブジェクト指向のポリモーフィズムを導入してみましょう。

簡単にいうと「IF文をクラスに変換する」感じ。

 

まずは、社畜クラスを親クラスとして、子クラスをつくります。

以下のとおり。

  • 営業の社畜(EigyoShachiku)
  • 総務の社畜(SomuShachiku)
  • 開発の社畜(KaihatsuShachiku)

 

…その前に、継承するための準備として、親クラスの Shachiku をすこし調整しておきます。

変更点は以下のふたつ。

  • 体力(_hp)を private から protected へ
  • 働く(Work)をオーバーライド可能に

 

それから、子クラスの営業・総務・開発社畜をつくります。

親クラスの Work をオーバーライドして、それぞれ別々の仕事をするように実装します。

で、private から protected になった親クラスの 体力(_hp)を減らす。

 

最後に、社長クラスを調整します。

new Shachiku としていたところを new EigyoShachiku など、親クラスから子クラスに変更(上赤枠)

そして、それぞれに社畜に対して「働け!」と命令する(下赤枠)

 

こうすることで、3人の社畜はそれぞれ営業・総務・開発の仕事をしてくれます。

社長は「働け!」というひとつの指示を出しただけなのに…です。

立派な社畜に育ってくれましたね。

 

もう一度、変更前の社長クラスをのせておきます。

ビフォーアフターで比べてみてください。

 

まあ、ポリモーフィズムはそんな感じです。

以下がメリット。

  • 社長クラスが楽になる
  • IF文地獄から解放される
  • 追加・変更による影響がクラス内に限定される

 


オブジェクト指向の真価は保守フェーズで発揮される

オブジェクト指向によって、システム開発が楽になるのは言うまでもありません。

…が、ほんとうに楽になるのは保守のフェーズです。

 

まとめると以下のとおり。

【カプセル化】
1. 必要最低限の変数を外部に公開する
2. バグったときの変数調査が楽になる

【継承】
1. 共通するものを親クラスにまとめる
2. 変更するときに1ヵ所でOK

【ポリモーフィズム】
1. IF文の各分岐をクラスに閉じ込める
2. 変更するときの影響がクラス内に限定される

 

というわけで、オブジェクト指向の雰囲気はざっくりつかめたのではないでしょうか。

あとは、実践で知識に肉付けしていくだけです。

お互いがんばっていきましょう。

 



こちらの記事もおすすめ!