Observer
デザインパターンとは
デザインパターンとはオブジェクト思考開発における先人たちが作り上げてきた便利な設計図です。
Gang of Four通称Gofが1994年に出版した『オブジェクト指向における再利用のためのデザインパターン』の中で23個の設計図が紹介されています。
Note
デザインパターンのサンプルコードはSwift4でまとめます。
オブザーバーパターンとは?
オブザーバーパターンは処理を通知してもらうことで、監視者(Observer)が常に監視対象(Subject)を見張っていなくても良いと言うものです。
例えば、電車の切符を例に出すとObserverは券売機でSubjectは人間です。
人間が電車に乗りたいと思ったら券売機で購入をします、券売機側は誰がいつ電車に乗るのかを監視していなくても人間の方から切符購入の通知がくるので通知が来たら処理をすると言うような感じです。
サンプルコード
サンプルでは宿題したかを先生に伝えると言うコードを出来るだけシンプルに作ってみました。生徒(Subjecdt)と先生(Observer)両方にプロトコルを準拠させ教え子が指定した先生に宿題をしたか伝えます。
ObserverとSubejectのプロトコル
先生には生徒に宿題したかを聞く抽象メソッドstudentHomeWorkを作りました。
生徒には宿題をした報告する先生を決めるaddObserverメソッド、宿題をやったことを先生に報告するnotifyObserversメソッド、宿題をするstudyメソッドを作成しています。
protocol Observer {
func studentHomeWork()
}
protocol Subject {
func addObserver(observer: Teacher)
func notifyObservers()
func study()
}
Observerクラス
先生(Observer)クラスはこのようになっています。解説用にかなりシンプルにしてあります。
studentHomeWorkメソッドは生徒(Subject)から通知を受け取り宿題したということを出力します。
class Teacher: Observer {
func studentHomeWork() {
print("生徒が宿題をやってくれました")
}
}
Subjectクラス
生徒(Subject)のクラスはこのようになっています。報告する先生が一人ではなく複数人いる可能性を考えて通知するObserverを配列で保持しています。
class Student: Subject {
var observers:[Teacher] = []
func addObserver(observer: Teacher) {
observers.append(observer)
}
func notifyObservers() {
for i in observers {
let Teacher:Observer = i
Teacher.studentHomeWork()
}
}
func study() {
notifyObservers()
}
}
呼び出し部分
var mySubject = Student()
var myObserver = Teacher()
mySubject.addObserver(observer: myObserver)
mySubject.study()
ソースコード一覧
protocol Observer {
func studentHomeWork()
}
protocol Subject {
func addObserver(observer: Teacher)
func notifyObservers()
func study()
}
class Teacher: Observer {
func studentHomeWork() {
print("生徒が宿題をやってくれました")
}
}
class Student: Subject {
var observers:[Teacher] = []
func addObserver(observer: Teacher) {
observers.append(observer)
}
func notifyObservers() {
for i in observers {
let Teacher:Observer = i
Teacher.studentHomeWork()
}
}
func study() {
notifyObservers()
}
}
var mySubject = Student()
var myObserver = Teacher()
mySubject.addObserver(observer: myObserver)
mySubject.study()