妹に着せ替えをさせていく様からオブジェクト指向の性質を説明する

  • 14
    いいね
  • 5
    コメント
この記事は最終更新日から1年以上が経過しています。

はじめに

FUN Advent Calendar 201516日目の記事になる予定のものでした。16日と88時間目の記事です。
このアドベントカレンダーについてはこちらを御覧ください。
また、内容は正確であることを心がけていますが必ずしも正しいものではない可能性がありますのでご容赦下さい。
ちなみに、コードはJavaですが構文の説明とかはしません。
お恥ずかしいことに英語力のなさを指摘されてしまったので修正しました。

前置き的なもの

プログラミングという世界において貴方は神と言っていいでしょう。世界の創造者たるあなたはあなたの支配する世界(=プログラム)を世界の理(=言語仕様)に沿って自由に構成することが出来ます。
そんな世界であなたはを作ったとしましょう。何故妹なのかとか誰の妹なのかといった議論はここではしないので好きに解釈して下さい。

あなたの最終目標は妹に安全に着せ替えをさせることですが、そのために越えなければいけないハードルをオブジェクト指向の観点から説明します。

オブジェクト-妹とは何であるかを定義する-

あなたは世界の創造者です。すなわち、あなたの世界に妹とは何かを知らしめる必要があります。また、着せ替えをするためには衣服とは何かを知らしめる必要があります。妹は自分が妹であることを知っていて、妹として振る舞うことが出来ます。衣服でも同じことがいえます。
仮にこのような定義をしたとします。

// この世界での妹の定義
class Sister {
    public Body body; // 妹の身体(定義は省略)
    // ここには妹が妹であるための要素が色々あるはず

    public Sister(Clothes clothes) { // 何らかの服を着た妹が創生される
        body = new Body(this);
        this.clothes = clothes;
        clothes.getOn(body);
    }
}

// この世界での衣服の定義(省略)
class Clothes {
    // ここには衣服の個性を決めるパラメータが色々あるはず

    public void getOn(Body s) {
        // 服を着る方法がここには書かれているはず
    }
}

これは非常に原始的な方法で、何らかの衣服を用意することであなたの世界に衣服を纏った妹を顕現させることが出来ます。しかし、この時点ではこの定義にいくつか問題があると言わざるを得ません。
具体的には、次以降の項目で説明します。

カプセル化-妹との対話的な着替えで邪神の魔の手から守る-

プログラミングの世界では八百万の神々が協力して巨大な世界を構成することが度々あります。時と場合によってはあなたの作った妹が他の神々によっていいように変えられてしまう可能性があります。例えば、上記の定義では顕現した妹の身体を好き勝手に弄ることが可能です。
このような魔の手から妹を守るために、妹には対話的に服を着れるようにする必要があります。すなわち、既に顕現している妹に「この服を着ろ」と指令し、妹がそれを理解して何らかの行動を起こすわけです。ただし、この命令によって妹がどんな行動を起こすかは妹の定義によるというのがポイントです。
妹に服を着る方法と今着ている服を見せる方法を追加します。

class Sister { 
    private Body body;

    public Sister(Clothes clothes) {
        body = new Body(this);
        putOnClothes(clothes);
    }

    // 渡された服を着る(コード上は変身シーンに近い)
    public void putOnClothes(Clothes clothes) {
        this.clothes = clothes;
        clothes.getOn(body);
    }

    // 着ている服を見せる
    public clothes showClothes() {
        return clothes;
    }
}

これによって、「妹の身体」を直接弄ることができるのは本人だけになります。よって、妹の身体を好きにすることはもちろん対話することなく妹の現在の衣服を剥ぎ取ったり無理やり着せたりすることはできません。また、服を着てもらう際に妹がどんな行動をするのかも顕現した妹が明かすことはありません。妹の定義によっては、渡された服が気に入らなければ着ることを拒否されるということもあり得ます。

ポリモーフィズム-着るという動作に多様性を持たせる-

妹に服を着る方法を教えることでだいぶ着せ替えに近づいた言えます。しかし、今度は衣服の方に問題があります。現状では、大雑把に身体に何かわからないけど服を纏っているということしか定義されていないことがわかるでしょうか。着せ替えというからにはトップスなのかボトムスなのかもしくは下着の類なのかくらいの選択はしたいものです。
そこで、ベースとなる衣類つまり現在のclothesを拡張して着るものに共通する着るという動作と身に付ける箇所に個性を付けたいと思います。それに併せて、妹にも身につけられる箇所を増やします。

class Sister {
    // 手足、胴体、頭を図示したようなもの
    private Map<BodyPart, ? extends Body> body;

    public Sister(List<Wearable> wearingList) {
        // 着るもののリストを渡して着替えさせる
        for(Wearable w: wearingList) {
            w.getOn(body.get(w.getBodyPart()));
        }
    }

    // 着替えるための色々な方法を可能にしておく
}

// 身体の部位の列挙
enum BodyPart {
    HEAD,
    HAND,
    :
}

// 例えば妹に履かせるパンツはこのようになる
class Pants implements Wearable<Hip> {
    ()
    public void getOn(Hip s) {
        // ここにはパンツを履く方法が書かれている
    }
}

// 着るものである印と着るための動作
interface Wearable<B> {
    public void getOn(B s);
    public BodyPart getBodyPart();
}

色々書きましたが、肝心なのは衣服に着るものという共通性を見出すことで、妹に着てほしいものリストを渡すだけで妹は着替えをすることが可能になるということです。
色々端折った部分はありますが、これで世界の創造者たるあなたは妹に安全に着せ替えをさせることができる環境を手に入れることができました👏

おわりに

この記事は某サークルでLTした時に喋ったものをベースにもうちょっと追加するなどして作りました。
雑な説明ですがオブジェクト指向に悩むプログラマの理解の一助となれれば幸いですしアドベントカレンダーとしての意義もあるかなと思います。

参考にしたもの

新人プログラマに知っておいてもらいたい人類がオブジェクト指向を手に入れるまでの軌跡
Wikipedia-オブジェクト指向
Wikioedia-オブジェクト指向プログラミング