定義
Template Method パターン(テンプレート・メソッド・パターン)とは、GoF(Gang of Four; 4人のギャングたち)によって定義されたデザインパターンの1つである。「振る舞いに関するパターン」に属する。Template Method パターンの目的は、ある処理のおおまかなアルゴリズムをあらかじめ決めておいて、そのアルゴリズムの具体的な設計をサブクラスに任せることである。そのため、システムのフレームワークを構築するための手段としてよく活用される。
wikipediaから定義をお借りしました。
処理の大枠を共通化しつつ、肝心なところの処理をサブクラスやプロトコルの適合者に任せるためのパターンです。
Swiftでの実装パターンを2つ考えてみました。
クラスを使ったパターン(非推奨)
かけることはかけますが、javaのように abstract class
が言語仕様的に定義できないので、fatalErrorを使うしかないです。RxSwiftなどでも見られるパターンですが、できる限り使いたくありません。
class.swift
import Foundation
// ClassでTemplateMethodを実現
// Swiftでは抽象クラスがないのでクラスで表現
class ClassFileProcessor {
func readFile(fileName: String) throws {
if !fileName.isEmpty {
doProcessLine(line: fileName)
} else {
throw NSError(domain: "ClassFileProcessorError", code: 200, userInfo: nil)
}
}
func doProcessLine(line: String) {
fatalError()
}
}
class ClassSimpleFileProcessor: ClassFileProcessor {
override func doProcessLine(line: String) {
print(line)
}
}
let processor: ClassFileProcessor = ClassSimpleFileProcessor()
try! processor.readFile(fileName: "Super expensive.")
// Super expensive.
プロトコル拡張を使ったパターン
対してこっちはSwiftyにかけます。
protocol.swift
// プロトコルでTemplateMethodを実現
protocol FileProcessor {
func doProcessLine(line: String)
}
extension FileProcessor {
func readFile(fileName: String) throws {
if !fileName.isEmpty {
doProcessLine(line: fileName)
} else {
throw NSError(domain: "ProtocolFileProcessorError", code: 200, userInfo: nil)
}
}
}
struct SimpleFileProcessor: FileProcessor {
func doProcessLine(line: String) {
print(line)
}
}
let protocolProcessor: FileProcessor = SimpleFileProcessor()
try! protocolProcessor.readFile(fileName: "Super cheap.")