본문 바로가기
iOS/Design Pattern

Design Pattern - Observer Pattern

by HaningYa 2020. 8. 9.
728x90

Observer Pattern

Observer 패턴은 하나의 Object 가 다른 Object의 변화를 관찰 할 수 있는 패턴이다.

Apple 은 이 패턴을 Swift5.1에 언어수준에서 RxSwift 와 비슷한 Publisher 와 Combine 프레임워크를 통해서 공식적으로 지원하는 패턴으로 추가하였다.

출처: Design_pattern_by_tutorials (raywenderlich)

패턴은 세가지 타입을 포함한다.

  • subscriber: 변경된 사항에 대해 업데이트를 받는 관찰자 object
  • publisher: observable(관찰가능한) object, 변경되면 업데이트를 subscriber 에게 알려줌
  • value: 객체의 변경된 값

Observer Pattern - 언제 사용해야 할까

  • 다른 객체의 변경사항을 알고 싶을때
  • MVC 패턴에서 주로 쓰인다. 
    Subscriber: view controller
    Publisher: model
    --> model 에 대한 변경값이 view controller 로 전달되게 해준다. (view controller 타입에 대한 내용 없이)
  • 어떤 view controller 인지 상관없기 때문에 여러 다른 view controller 들이 같은 model 타입에 대한 변경값을 observe 할 수 있다.

Observer Pattern - Behavior Pattern

Observer Pattern 은 다른 객체를 observing 하는 패턴 이므로 행위 패턴이다.


Observer Pattern 예제 (Combine)

import Combine

public class User {
	
    @Published var name: String
    
    public init(name: String) {
    	self.name = name
    }
}
  1. 먼저 Combine 을 import 해준다. (@Published 어노테이션과 Publisher, Subscriber 타입을 가지고 있다.)
  2. 새로운 User 클래스를 만든다. (@Published 프로퍼티는 class 가 아닌 struct 나 다른 타입에는 사용할 수 없다.)
  3. name 변수를 선언하고 @Published 라고 표기한다. 그러면 Xcode가 자동으로 Publisher 를 만들어 준다. (@Published는 let 에 쓸수 없다. --> 당연하지)
  4. initializer 를 만들고 name 의 초기값을 정해준다.

예제를 실행해 보자

let user = User(name: "Ray")

let publisher = user.$name

var subscriber: AnyCancellable? = publisher.sink(){
	print("User's name is \($0)")
 }
 
 user.name = "Vicki"
  1. 먼저 새로운 user 인 Ray 를 만든다.
  2. user 이름에 대한 변경사항을 전달하기 위해 user.$name 을 통해서 publisher 에 접근한다. 
    이것은 Published<String>.Publisher 를 리턴한다.
  3. publisher 에 sink 를 호출 함으로써 subscriber 를 만든다.
    초기값과 값이 변경될 때마다 호출될 클로져가 필요하다.
    defualt 로 sink 는 AnyCancellable 타입을 리턴한다. 하지만 명시적으로 AnyCancellable? 처럼 옵셔널로 처리하여 나중에 nil 처리 할 수 있다.
  4. 마지막으로 user name 을 Vicki 로 바꾼다.
//실행결과 
User's name is Ray

//user 이름을 Vicki 로 바꾼 직후
User's name is Vicki

 


subscriber 를 nil 로 설정하면 더이상 publisher 로 부터 값을 update 받지 않는다.

subscriber = nil
user.name = "change name"
//값을 바꿔도 아무 출력 안됨

Observer Pattern 사용시 주의할 점

  • observer pattern 을 적용하기 전 어떤 조건 (condition) 에서 어떤 변화(change)가 일어나길 바라는지 생각해라
  • object 나 property 가 change 할 이유를 찾지 못할 것 같으면 var 이나 @Publisehd 말고 let으로 선언해라
  • unique identifier을 예로 들자면 definition이 절대 바뀌지 않으므로 published property 로 사용하기 적절치 않다.

[Combine]

 

 

Combine: Asynchronous Programming with Swift

The best book for learning how to manage declarative asynchronous event handling with the Swift Combine framework!

store.raywenderlich.com

 

 

 

728x90

'iOS > Design Pattern' 카테고리의 다른 글

Design Pattern - Model View ViewModel Pattern  (2) 2020.08.24
Design Pattern - Builder Pattern  (0) 2020.08.09
Design Pattern - Memento Pattern  (0) 2020.08.09
Design Pattern - Singleton Pattern  (0) 2020.08.09
Design Pattern - Strategy Pattern  (0) 2020.08.07

댓글