Adapter
デザインパターンとは
デザインパターンとはオブジェクト思考開発における先人たちが作り上げてきた便利な設計図です。
Gang of Four通称Gofが1994年に出版した『オブジェクト指向における再利用のためのデザインパターン』の中で23個の設計図が紹介されています。
Note
デザインパターンのサンプルコードはSwift4でまとめます。
アダプターパターンとは?
Adapterパターンは互換性のないクラスにインターフェースを組み込み互換性のあるものにするパターンです。
例えば2つメソッドがありクラスAでは1つしか持っていない際に、クラスAを修正するのではなく、インターフェースを作成して、Aを継承しインターフェースに準拠させたAdapterクラスを作成することで実装を追加します。
Adapterパターンは継承を利用した方法と、委譲を利用した方法の2つが用意されています。そしてSwiftではExtensionという機能があるので今回はサンプルコードを3つ用意しました。
サンプルコード
サンプルコードでは味噌汁と豚汁の違いは豚肉が入っているか否かという点に絞って考えてみました。
味噌汁クラスを修正せずにAdapterを使って豚汁を作ります。
継承、委譲、Extensionそれぞれ同じ動きをするものを作成しています。
サンプルコード(継承)
継承を使ったコードはこのようになります。味噌汁クラスは野菜の具材を表すvegetableIngredientsしか持っていません。
protocolで肉の具材を表すmeetIngredientを作成しAdapterクラスで2つを継承、準拠させることで味噌汁を豚汁にすることができています。
コード
class MisoSoup {
func vegetableIngredients(){
print("野菜の具材は人参、大根、ねぎ")
}
}
protocol PorkSoup {
func meetIngredient()
}
class Adapter: MisoSoup, PorkSoup {
func meetIngredient() {
print("肉は豚肉!!!")
}
}
呼び出し元
let porkSoup = Adapter()
porkSoup.vegetableIngredients()
porkSoup.meetIngredient()
コンソール
野菜の具材は人参、大根、ねぎ
肉は豚肉!!!
サンプルコード(委譲)
委譲を使ったAdapterパターンのコードはこのようになります。継承はせずメンバとして味噌汁を保持しています。
コード
class MisoSoup {
func vegetableIngredients(){
print("野菜の具材は人参、大根、ねぎ")
}
}
protocol PorkSoup {
func meetIngredient()
}
class Adapter: PorkSoup {
let misoSoup: MisoSoup
init(soup: MisoSoup){
misoSoup = soup
}
func meetIngredient() {
print("肉は豚肉!!!")
}
}
呼び出し元
let porkSoup = Adapter(soup: MisoSoup())
porkSoup.misoSoup.vegetableIngredients()
porkSoup.meetIngredient()
コンソール
野菜の具材は人参、大根、ねぎ
肉は豚肉!!!
サンプルコード(Extension)
Extensionを使うSwift独自の方法は継承、委譲のコードと違いAdapterクラスが存在しなくなります。
もともと味噌汁だったものに豚肉を投入して豚汁を作るイメージです。
コード
class MisoSoup {
func vegetableIngredients(){
print("野菜の具材は人参、大根、ねぎ")
}
}
protocol PorkSoup {
func meetIngredient()
}
extension MisoSoup: PorkSoup {
func meetIngredient() {
print("肉は豚肉!!!")
}
}
呼び出し元
let porkSoup = MisoSoup()
porkSoup.vegetableIngredients()
porkSoup.meetIngredient()
コンソール
野菜の具材は人参、大根、ねぎ
肉は豚肉!!!