Delegateとは?
Delegate(デリゲート)とは、日本語訳で代理人や委譲という意味を持ちます。
このデリゲートは「あるクラスは他のクラスのインスタンスに処理を任せる(委譲・依頼)」というデザインパターン(処理の流れ)をプロトコルを用いることで実現できるというものです。
メリットは?
移譲先を意識する必要がない
まず最初に処理を任せるクラスは、どのクラスがどのような処理をするのかとういう事を意識しなくてよくなります。
再利用ができる
プロトコルや処理を任せるクラスは変更せずに、処理を行うクラスだけ変更すれば処理内容は変わるので、プロトコルや処理を任せるクラスは再利用することが可能になります。
メリットは上記のようになりますが、メリットを聞いてもピンと来ないと思うので、ソースコードを読み解きながら理解していきましょう!
サンプルコード
//プロトコルを定義
protocol Select {
//処理内容のないメソッドを定義
func chooseWeapon()
}
class Master {
//Select型の変数delegateを宣言
var delegate: Select!
func say() {
print("お客さん、何をお求めですか??")
//変数delegateのchooseWeaponメソッドを指定
delegate.chooseWeapon()
}
}
//Selectプロトコルを適合したHero1クラスを定義
class Hero1: Select {
//Selectプロトコルで定義したメソッドの処理内容を指定。
func chooseWeapon() {
print("龍鱗の鎧をください")
}
}
//Selectプロトコルを適合したHero1クラスを定義
class Hero2: Select {
func chooseWeapon() {
//Selectプロトコルで定義したメソッドの処理内容を指定。
print("ユニコーンのランスをください")
}
}
//定数MasterOriginalにMasterクラスを代入
let MasterOriginal = Master()
//定数Hero1OriginalにHero1クラスを代入
let Hero1Original = Hero1()
//MasterOriginalの変数delegateにHero1を代入
MasterOriginal.delegate = Hero1Original
//MasterOriginalのsayメソッドを実行
MasterOriginal.say()
//実行結果
お客さん、何をお求めですか??
龍鱗の鎧をください
解説
//プロトコルを定義
protocol Select {
//処理内容のないメソッドを定義
func chooseWeapon()
}
まず最初にSelectプロトコルを定義します。このプロトコルをクラスなどに適合することで、プロトコル内のプロパティやメソッドが適合されたクラスでも使えるようになります。
class Master {
//Select型の変数delegateを宣言
var delegate: Select!
func say() {
print("お客さん、何をお求めですか??")
//変数delegateのchooseWeaponメソッドを指定
delegate.chooseWeapon()
}
}
次にMasterクラスを定義します。この中では変数delegateをSelect型として宣言しており、定義したプロトコルは型としての利用も可能です。これでdelegateに対してメソッドやプロパティを指定することで、プロトコル内のメソッドやプロパティを使うことができます。
そして次は、sayメソッドを定義します。処理内容としてdelegate.chooseWeapon()をさしているので、プロトコル内のメソッドを実行しています。しかし現時点では、処理内容が記述されていないので何も起こりません。
//Selectプロトコルを適合したHero1クラスを定義
class Hero1: Select {
//Selectプロトコルで定義したメソッドの処理内容を指定。
func chooseWeapon() {
print("龍鱗の鎧をください")
}
}
//Selectプロトコルを適合したHero1クラスを定義
class Hero2: Select {
func chooseWeapon() {
//Selectプロトコルで定義したメソッドの処理内容を指定。
print("ユニコーンのランスをください")
}
}
次はSelectプロトコルを適合したHero1とHero2クラスを定義します。これらのクラス内では、プロトコル内で定義のみされていたchooseWeaponメソッドの処理内容が記述されています。これでクラスごとに処理内容の違う同名のメソッドを実行する準備が整いました。
//定数MasterOriginalにMasterクラスを代入
let MasterOriginal = Master()
//定数Hero1OriginalにHero1クラスを代入
let Hero1Original = Hero1()
//MasterOriginalの変数delegateにHero1を代入
MasterOriginal.delegate = Hero1Original
//MasterOriginalのsayメソッドを実行
MasterOriginal.say()
次に定数MasterOriginalにMasterクラスを代入し、インスタンス化します。
そしてHero1Originalにも同じようにクラスを代入し、インスタンス化します。
次にMasterOriginalのdelegateにHero1Originalを代入し、sayメソッド内のdelegate.chooseWeapon()をHero1のメソッドに変更します。
最後にMasterOriginalのsayメソッドを実行します。
//実行結果
お客さん、何をお求めですか??
龍鱗の鎧をください
結果として上記のように出力されます。