Swiftのプロトコル指向プログラミングとは?初心者向けにやさしく解説!
生徒
「Swiftで“プロトコル指向プログラミング”ってよく聞くけど、何のことかさっぱりわかりません…」
先生
「それはSwiftの特徴を活かした考え方なんですよ。難しく聞こえるかもしれませんが、ひとつずつ見ていけば安心ですよ。」
生徒
「オブジェクト指向とは違うんですか?」
先生
「オブジェクト指向と似たところもありますが、Swiftならではの“柔軟でシンプル”なコードを実現できるのがプロトコル指向なんです。」
1. プロトコル指向プログラミングとは?
プロトコル指向プログラミング(Protocol-Oriented Programming)は、Swiftが得意とする設計スタイルの一つです。名前の通り、protocol(プロトコル)を中心に設計を進める考え方です。
従来のオブジェクト指向プログラミングでは、クラスを継承して機能を共有しますが、プロトコル指向では、protocolを使って“やるべきことの定義”を行い、それを構造体やクラスが実装します。
2. オブジェクト指向とプロトコル指向の違い
オブジェクト指向(Object-Oriented Programming)は、継承を使って機能を再利用します。例えば「動物」という親クラスを作って、「犬」「猫」などがその機能を引き継ぐという形です。
一方、プロトコル指向では、protocolを使って機能の定義を行い、それを構造体(struct)やクラス(class)がそれぞれ実装します。これにより、複数の型で共通の動作を実装しやすくなるのです。
3. 実例で学ぶプロトコル指向プログラミング
では、Swiftのプロトコル指向プログラミングを実際のコードで確認してみましょう。ここでは「動けるもの」というプロトコルを定義して、それを構造体に実装してみます。
protocol Movable {
func move()
}
struct Car: Movable {
func move() {
print("車が走ります")
}
}
struct Robot: Movable {
func move() {
print("ロボットが移動します")
}
}
let items: [Movable] = [Car(), Robot()]
for item in items {
item.move()
}
このように、構造体でも共通の機能(move)を実装でき、配列でまとめて扱えるのがプロトコル指向の大きなメリットです。
4. クラスより構造体とプロトコルを使う理由
Swiftではstruct(構造体)とprotocol(プロトコル)の組み合わせが推奨されることが多いです。理由は以下の通りです:
- 構造体は値型なので、安全で扱いやすい
- クラスのような継承の複雑さを避けられる
- 必要な機能だけを
protocolで定義できる
これにより、小さく分かりやすいコードを書けるようになります。
5. プロトコルの拡張で共通処理を追加できる
Swiftのprotocolは、extension(拡張機能)と組み合わせることで、プロトコルに共通の処理を実装することができます。これにより、コードの重複を減らせます。
protocol Printable {
func text() -> String
}
extension Printable {
func printText() {
print("出力内容:\(text())")
}
}
struct Book: Printable {
func text() -> String {
return "Swiftの教科書"
}
}
let b = Book()
b.printText()
Book構造体はtext()だけを実装すれば、printText()は自動的に使えるようになります。
6. なぜSwiftはプロトコル指向を推すのか?
Appleは、Swiftの設計段階から「プロトコル指向」を推奨しています。その理由は以下の通りです:
- 柔軟で拡張しやすい
- テストがしやすい
- 構造体(値型)を活かしやすい
- 重複コードを減らせる
これにより、安全性が高く、保守しやすいコードを書くことができ、アプリの品質向上にもつながります。
7. protocolとextensionで拡張性の高い設計
プロトコルと拡張機能を組み合わせると、追加機能を後から簡単に追加できるようになります。これは、「プラグインを差し込む」ような感覚に近いです。
たとえば、既存のプロトコルにログ出力の機能をあとから追加したい場合も、extensionで対応可能です。これにより、大きな修正をせずに機能を増やすことが可能になります。
8. プロトコル指向は初心者にもオススメ!
Swiftのプロトコル指向プログラミングは、難しそうに見えて実は「シンプルなルールに沿った設計」です。初心者の方にもわかりやすく、慣れれば自然とプロトコルを使ったコードが書けるようになります。
特に、複数の構造体やクラスで共通の機能を持たせたいときや、コードの見通しを良くしたいときに活躍します。