Java
オブジェクト指向
読み物
新人プログラマ応援

妖精さんで分かるオブジェクト指向

概要

この記事では、オブジェクト指向の基本を「妖精さん」に(たと)えて解説します。
これを読んでいるプログラマーの皆さんは、妖精さんの召喚̪士(サモナー)であり(マスター)でもあります。ルビを振るとクールな気分がしますね。
みなさんが素敵な妖精さんを呼び出せるように、どんな妖精さんがいい妖精さんかを学んでいきましょう。

妖精さんのことを知ろう

トランプのカードを例にとって説明していきます。

Card.java
public class Card {
    // フィールド(=メンバ変数)
    private Suit suit; // マーク(ハート、スペード、ダイア、クラブ)
    private int number;// 数字(1~13)

    // メソッド(=関数)
    public Card(Suit suit, number) {// コンストラクタ
        this.suit = suit;
        this.number = number;
    }

    public Suit getSuit() {
        return this.suit;
    }

    public int getNumber() {
        return this.number;
    }
}

オブジェクト=妖精さん

妖精さんは、オブジェクト指向におけるオブジェクトのことです。妖精さんは、モノに宿ったり、コトを司る(=コントロールする)存在です。つまり、妖精さんはみんな、○○係や○○担当、○○役を持つ存在ということです。夜中にお掃除をする妖精さんや靴に宿って履く人を助けてくれる妖精さん、デンセツの妖精さんなど、みんな人間たちを手助けしてくれるのです。

クラス=魔法陣

どんな妖精さんを呼び出すかを決めるのが、魔法陣です。魔法陣には妖精さん自身のことだけでなく、妖精さんとの契約が書かれているのです。魔法陣は、オブジェクト指向におけるクラスのことです。妖精さんは真面目で素直なので、魔法陣に書かれている通りのことをしてくれます。魔法陣が書けたら、妖精さんを召喚しましょう。呪文は「サモン! フェアリー!」です。Java のソースコードでは、new が召喚呪文に当たります。

// 妖精さんの召喚呪文
Fairy alice = new Fairy();

フィールド=持っているものや知っていること

フィールド(=メンバ変数)は、妖精さんの「持っているもの」や「知っていること」を表わしています。自分自身がどんな性質を持っているかや、自分に協力してくれる他の妖精さんが誰かを、妖精さんは覚えておくことができます。
妖精さんは、自分の中身をじろじろ見られるのが嫌いです。
「ちょっと! 今すっぴんなんだけど! ちょ~恥ずかしい><」という女子高生と同じです。なのでフィールド(=メンバ変数)は publuc よりも private であることが望ましいです。なぜなら、public だと、妖精さんがいつイメチェンしたかや、今現在何をしているかが分からなくなって思わぬバグの元となるからです。始めの内は、迷ったらとりあえず private にしておく、でいいと思います。
もしも、妖精さんの持っているものを見せてもらったり変えたいときは、getter/setter(get○○○やset○○○という名前の)関数を介してやりとりしましょう。

メソッド=することやできること

メソッド(=関数)は、妖精さんの「すること」や「できること」を表わしています。「この仕事やっておいて」とか、「質問に答えて」などいろいろなことができます。そう、あなたが魔法陣(=クラス)に書いておけばね。

実は、上記のトランプの妖精さんはまだ妖精さんになっていません。値を持っていてそれを出し入れするだけでは単なる入れ物で、まだモノと人とのやり取りをしているに過ぎません。ここで例を出します。

public staric main(String[] args) {
    Card heart = new Card(Suit.HEART, 7);// SuitはEnum型です。

    if(heart.getNumber() >= 5) {
        System.out.println("このカードは5以上です。");
    } else {
        System.out.println("このカードは5より小さいです。");
    }
}

次に、妖精さんと人のやり取りを見てみましょう。

Card.java
public class Card {
    // ... フィールドとその他関数は上記と同じのため、省略 ...

    public boolean isOver(int number) {
        return this.getNumber() >= number;
    }
}
public staric main(String[] args) {
    Card heart = new Card(Suit.HEART, 7);

    if(heart.isOver(5)) {
        System.out.println("このカードは5以上です。");
    } else {
        System.out.println("このカードは5より小さいです。");
    }
}

たかだか、関数が一つ増えただけだと思われるかもしれませんが、妖精さんは、自分の仕事は自分の力でできることを望みます。単なるモノではないため、自分で考え行動できるのです。なので、マスターであるあなたがあれこれ考えるより、妖精さんの知っていることに関わる判断は、妖精さんに任せた方がいいです。新しい関数を作り、それに短くて分かりやすい、素敵な名前を付けましょう。

引数=教えること

引数は、妖精さんに「教えること」を表わしています。引数を介して妖精さんに必要なことを教えてあげましょう。
先ほど述べたように、妖精さんは、自分の仕事は自分の力でできることを望みますので、教えること(=引数)は少ない方がよりよいです。同じことを何度も教えることになるようなら、あらかじめコンストラクタや add○○○関数、set○○○関数を通して教えておいて、覚えた内容を使ってもらった方がいいです。仕事は、妖精さんに丸投げ任せてしまいましょう。その方が、妖精さんもマスターも幸せになれます。

エラー=危ないことやしてはいけないこと

エラー(=例外)は、妖精さんとマスターにとっての「危ないこと」や、妖精さんが「してはいけないこと」です。妖精さんは頑張り屋さんですが、頑張りすぎた結果、マスターにとって困ったことをしてしまうかもしれません。道に迷ったり、行ってはいけないところに行ったりしたら、とても心配です。それを未然に防ぐのがエラーです。妖精さんが危ないことをしそうになったらちゃんと止めてあげましょう。もっとも、危ないことがあったら止めるよりも、そもそも危ないことが起きないように魔法陣(=クラス)を書くのが最善ですよ。

いい妖精さんは、小さくてきれい

いい妖精さんは、小さくてスリムです。小さいということは、コードが短いということです。一人の妖精さんの担当する仕事が増えるほど、ソースコードが長くなり、体の大きなおデブ妖精さんになっていきます。他に、コードの重複も妖精さんが太る原因です。重複しているところは関数を作ってまとめたり、新しい妖精さんに仕事を分担したりして、ダイエットしましょう。
目標は「この妖精さんは何をする?」という問いに、一文で答えられるようにすることです。太った妖精さんにたくさんの仕事を任せるより、たくさんの小さな妖精さんに仕事を任せた方がいいです。妖精さんハーレムを作りましょう。
一方、ものすごく太った妖精さんは、になります。

イメージ画像

神妖精さんは、仕事は任せられるけれど、なぜ動いているのか分からない厄介な妖精さんです。いにしえのマスターたちが呼び出し、現役のマスターたちを恐れさせる存在です。神妖精さんに新しいことをしてもらおうとすると、膨大なバグとその可能性を生み出し、修正に一苦労、いや百苦労くらいします。なので、新しい魔法陣を書くときは、神を作ってはいけません。このセリフ、カッコいい……。
このような、プログラミングにおける「~べからず」をアンチパターンといいます。逆に、推奨される方法論をまとめたものが、デザインパターンといいます。もっとも有名なのは、GoF(Gang of Four: 四人組)と呼ばれ、これは全部で23個あります。プログラムの構文が分かるようになったら、調べてみるといいでしょう。


きれいなコードは、マスターにとって読みやすい(可読性が高い)コードのことです。数学者が数式に美しさを見出すように、プログラマーはソースコードに美学を持つのです。インデントが浅い、適切な名前がついているなど、いろいろなテクニックがあります。小さくてきれいな妖精さんを作るコツは、リファクタリングで検索して学習するといいです。

まとめ

妖精さんは、自分の力で考え、行動することを望みます。できる限り、妖精さんに仕事を任せてあげましょう。そして、たくさんの小さくてきれいな妖精さんが協力できるような仕組み作りを心がけましょう。

おわりに

私としては、オブジェクト指向を勉強するよりも、先にリファクタリングを勉強した方がいいと思います。何をすればいいかが分かると、オブジェクト指向が何のためにあるかが分かりやすくなるからです。私は、オブジェクト指向やデザインパターンの初歩を勉強してからリファクタリングを知りましたが、リファクタリングを勉強した後の方が、それらのパターンや考え方が明瞭に分かるようになりました。

それでは、いいね、ご感想、コメント等お待ちしております。

オススメ&参考文献

① この記事を読んで、同じ考え方をしている人がいるんだなぁと思い、この解説を書くことを決めました。オブジェクト指向がどんな理念から作られたかも分かります。
https://qiita.com/s_yuche/items/d46c7c843a56e6b2ebb7

② どんな妖精さんがいいかを7つの美徳として教えてくれます。全てがそうとは言い切れませんが、納得できる内容も多いです。
https://www.kaitoy.xyz/2015/10/28/seven-virtues-of-good-object/

③ 私はこの本でリファクタリングを勉強しました。とーーーってもオススメです。ただ、コードが省略気味だったり、若干内容が古いところもありました。なので、おおむね同じ内容のこちらをオススメします。
【Amazon】Java言語で学ぶリファクタリング入門