プロトコル指向プログラミングについて調べてみた

  • 49
    いいね
  • 2
    コメント

プロトコル指向プログラミングという概念について、調べたことをまとめてみました。

プロトコル指向プログラミングとは

ものすごくざっくりいうと、プロトコル(Javaでいうインターフェース)を使ってプログラミングしようという概念です。

なんでプロトコル?

オブジェクト指向の問題を解決するためです。
どんな問題かというと、以下の点が問題でした。

  • オブジェクト同士が他のインスタンスを共有していることを知らずに参照してしまう(暗黙の共有)
  • 親クラスのメソッド、プロパティをそのまま引き継ぐため、初期化や上書きなどの調整が必要になる
  • 複数のサブクラスを作ってもそれらを関連付けする方法がないため、 型が統一できない

このような問題点がオブジェクト指向にはあるため、プロトコルを使ってクラス関係の壁をなくそうということで、プロトコルを使うのです

実際にやってみた

概念だけだとわかりづらいので、実際のコードで説明します
例えば、こういうプロトコルがあったとします

Person.swift
protcol Person {
    var name : String { get set }
    var age : Int { get set }

    // 人間なので息を吐かせます
    func bress()
}

人間の情報をプロトコルにしました
で、このプロトコルを職業がエンジニアの人とアイドルの人に準拠させます

Engineer.swift
struct Engineer : Person {
    var name: String = "watasi"
    var age: Int = 21

    func bress() {
        print("すぅ〜〜〜〜〜はぁ〜〜〜〜〜")
    }
}
Idol.swift
struct Idol : Person {
    var name: String = "Takagaki"
    var age: Int = 25

    func bress() {
        print("すぅ〜〜〜〜〜はぁ〜〜〜〜〜")
    }
}

これで二人共、人間になれました
が、それぞれ同じ処理を準拠させた構造体( struct )に実装しなければなりません。
面倒ですね。

これをSwiftの機能であるプロトコル拡張を使って処理をまとめてみましょう。

Person.swift
protcol Person {
    var name : String { get set }
    var age : Int { get set }

    func bress()
}

// プロトコルを拡張してメソッドを実装
extension Person {    
    func bress() {
        print("すぅ〜〜〜〜〜はぁ〜〜〜〜〜")
    }

これで準拠させた構造体にそれぞれ同じ処理を書く必要がなくなるのっで以下の記述のみでOK

Engineer.swift
struct Engineer : Person {
    var name: String = "watasi"
    var age: Int = 21
}
Idol.swift
struct Idle : Person {
    var name: String = "Takagaki"
    var age: Int = 25
}

こんな感じで、プロトコルで準拠させたクラスもしくは構造体にそれぞれ同じ処理を書かなくても、プロトコルに実装すれば効率の良いコードが書けるようになります。

メリットはなんなの

・処理をまとめることができるので、コードが綺麗に書けるようになるよ
・プロトコルは実体を持たないので、メソッドをオーバライドする必要がないよ

まとめ

プロトコル指向プログラミングとは、オブジェクト指向でやってきたクラス継承をプロトコルで行ってしまおうという考え方。
クラス間で共通の処理とプロパティがあるならプロトコルにかいてまとめちゃおう!
もちろんSwiftはオブジェクト指向でプログラミング可能ですが、そのオブジェクト指向の弱点であった部分を、Swiftではプロトコル指向の考え方を使って補いましたって話でした。

参考記事

http://qiita.com/mokumoku/items/2744c68fdb4bb53d0376
https://www.infoq.com/jp/news/2015/06/protocol-oriented-swift