読者です 読者をやめる 読者になる 読者になる

エンジニアの箱

サーバ構築とか、Ciscoルータの設定とか、コーディングに関してのなにがしを書きます。

オブジェクト指向とは「抽象化」である

現在オブジェクト指向を再度勉強しなおしていて、「ああ、こういうことだな」っていう解を見つけた気がするので記事を書いています。なお、この記事は「プログラミング言語を用い、何か一つのアプリケーションを作り上げたことがある」人向けです。


タイトルの通り、オブジェクト指向とは抽象化を行なう概念です。我々は日々生活する中で無意識のうちに「抽象化」を行なっています。
例えば、漫画・技術書・文庫・雑誌、これらはすべて具体的な概念ですが、抽象的な概念に直すと「本」です。本の要素とは下記のとおりです。

  1. 開くことができる
  2. 閉じることができる
  3. ページめくりができる
  4. ページは紙でできている
  5. 文字もしくは絵(図)が書いてある
  6. 読むことができる
  7. 表紙がある
  8. タイトルがある
  9. 大きさがある程度限定される(大きさに種類がある)

こんなところでしょうか。これらの性質を持ったものを「本」と呼び、書いてある内容や大きさによって漫画・技術書・文庫・雑誌など呼び方が変わります。さらに、漫画・技術書・文庫・雑誌も実は抽象的な概念であり、実際は「ドラゴンボール」・「オブジェクト指向における再利用のためのデザインパターン」・「レ・ミゼラブル」・「日経ソフトウェア7月号」などが具体的な概念となります。これは階層的に表すことができます。


├漫画
│└ドラゴンボール
├技術書
│└オブジェクト指向における再利用のためのデザインパターン
├文庫
│└レ・ミゼラブル
└雑誌
 └日経ソフトウェア7月号

このように無意識のうちに抽象化を行ない、「ドラゴンボールがほしい」となればそれは本であるから本屋に行き、なおかつ本屋の中でも漫画コーナーを探す、という行為につながります。またドラゴンボールを読むときはドラゴンボールを開き、読み、ページをめくり…といった動作を行ないます。これはドラゴンボールでもレ・ミゼラブルでも同じことです。漫画と文庫は同じ本であるために同じ使い方をすることができます。

ここまではさも当たり前のことを書きましたが、実はこれがすごく重要です。抽象化されることにより、「漫画」の使い方を覚える必要がないということです。「本」の使い方さえ知っていれば「漫画」の使い方をいちいち学習する必要はありません。もっと言うと、「本」の使い方さえ知っていれば「ドラゴンボール」の使い方を覚える必要がないということです。技術書・文庫・雑誌においても同じことです。これこそが抽象化の威力です。もしも人間が抽象化という概念を理解できなかった場合、「ドラゴンボール」を購入したら「ドラゴンボール」の読み方を習得しなければなりません。そして「テニスの王子様」を購入したら「テニスの王子様」の読み方を習得しなければならないのです。


さて、ここまでは概念の話でした。これをプログラミングに落してみましょう。

public class Book
{
    // タイトル
    public String title { get; private set; }
    // 大きさ
    public String sizeType { get; private set; }


    // コンストラクタ
    public Book(String iTitle, String iSizeType)
    {
        this.title = iTitle;
        this.sizeType = iSizeType;
    }

    // 本を開くメソッド
    public void Open()
    {
        // 本を開く処理
    }

    // 本を閉じるメソッド
    public void Close()
    {
        // 本を閉じる処理
    }

    // 対象ページまで移動する(ページめくりを行なう)メソッド
    public void TurnPage(int pageNumber)
    {
        // ページをめくる処理
    }

    // 現在開いているページの内容をPageContentsオブジェクトとして取得するメソッド
    public PageContents Read()
    {
        PageContents pageContents = new PageContents();
        // ページの内容(PageContents)を取得する処理
        return pageContents;
    }
}

これが本オブジェクトですね。続いて漫画です。

public class Comic : Book
{
    // コンストラクタ
    public Comic(String iTitle, String iSizeType) : base(iTitle, iSizeType)
    {
    }
}

そして最終的に、インスタンス化しオブジェクトを操作します。

static void Main(string[] args)
{
    Comic DragonBall = new Comic("ドラゴンボール", "文庫版");

    DragonBall.Open();
    PageContents pageContents = DragonBall.Read();
    DragonBall.Close();
}

もうお分かりだと思いますが、Bookクラスの使い方さえ分かっていればDragonBallオブジェクトの使い方はおのずと分かるわけです。もちろんコーディングの仕方によってはその関係を壊すこともできます。ですが、基本的にはスーパークラスがBookクラスである以上、DragonBallオブジェクトはBookクラスの使い方に準拠されるわけです。つまりDragonBallオブジェクトを抽象的にBookクラスとして理解してコーディングができるというわけです。


私自身オブジェクト指向について勉強中ということもあり若干「?」な部分もあるかと思いますが、言いたいことは「抽象化」です。コーディングをする際にメソッドに処理を切り分ける行為も抽象化ですし、定数を作る行為も変数もデータ型も抽象化の一種です。その抽象化をより極めたのが「オブジェクト指向」であると言えると解釈しています。「もの」という最も抽象的な概念からどんどん具体化していって…ということであるからオブジェクト指向なのでは、ということです。よく巷にある「現実のものに即したほげほげ」みたいな説明は私にとってはいまいち分からず、どこが現実のものに即した考えなのかさっぱりだったのですが、最近この考え方をするようになってからかなり腹に落ちた感があります。恐らく「現実のもの」という指向ではなく、本当に「もの」指向であるということなのでしょう。ちなみにですが、「メッセージ」の概念については割愛しました。メッセージでやり取りをするという話も結局はメッセージという抽象的なインターフェイスによりオブジェクト間のやり取りを行なうって話なので、まずは抽象化について理解できていないとメッセージのやり取りっていうのも「?」って話になるので。カプセル化とか継承とか多態性も結局のところは抽象化の話だと思ってます。すべては抽象的にものを捉えるために、です。



最後になんで抽象化がプログラミングに取り込まれたのか、背景的なものを類推したので考察まで。プログラマないしSEであれば、コーディングを行なう機会は多いでしょう(特にプログラマはそれが生業ですし)。コーディングには絶対に起こりうる事態として2つあります(もっとあると思いますが代表格を書きます)。1つ目は仕様変更です。2つ目は同じようなコードを各所に実装することです。1つ目については、プログラムと言うのは全体の整合性を考えて書かれるものであるために、途中で仕様変更を行なうと必ず「ひずみ」が生じます。この「ひずみ」が大きくなることで、見通しの悪いコードができあがり、バグの温床となります。2つ目については、いわずもがな。コピペです。これは単独では問題がありませんが、1つ目が関わってくると最悪です。コピペで書いていた処理をすべて変更しなければならず、1つでも変更漏れがあろうものならたちまちバグと化します。これが小さなプロジェクトであればよいのですが、大きなプロジェクトでなおかつ実力がてんでバラバラのプログラマ・SEが関わっていると問題は複雑になります。
これらの問題を解決するためには、コードを抽象化し、上で書いたようなBookクラスを作るようにすればよいのでは、というのがオブジェクト指向誕生における経緯になるのではないかと思います。DragonBallオブジェクトに仕様変更があった場合、変更するのはBookクラスのみで済みます。さらに、他の箇所で使っているなにがしオブジェクトについてもBookクラスを変更すれば済む話です。これが抽象化の威力です。仕様変更に強くなるほか無駄なコードを埋め込む必要がなくなります。もちろん概念を正しく理解し正しくオブジェクト指向を使用していることが大前提にはなるほか、オブジェクト指向銀の弾丸ではないので100%の抽象化には至っていません(言語によるのかもしれません)。ですがこれを使用することでより我々の思考に近い形でコーディングを行なえることは間違いないでしょう。それが故にオブジェクト指向は誕生から40年以上も経過しているにも関わらずこれほど利用されている概念になっているのではないかと思います。