ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Observer Pattern (with Swift, Combine)
    Ray Wenderlich/Design Pattern 2020. 2. 2. 16:38

    Ch 8. Oberver Pattern

    1. Observer Pattern의 구성요소

    2. Observer Pattern의 사용 (Combine을 사용하지만, Combine에 대해서 1도 몰라도 이해가능)

    3. 느낀 점



    1. Observer Pattern의 구성요소

    옵저버 패턴은 한 객체가 다른 객체의 변화를 관찰하는 구조를 갖고 있다. 

    Swift5.1에서는 Combine의 Publisher를 통해 이 패턴을 쉽게 구현할 수 있다.



    1. Subscriber는 다른 객체의 변화를 <관찰하는(Observer)> 객체다.

    2. Publisher는 <관찰할 수 있는(Observable)> 객체다.

    3. Value는 변화하는 값이다. Publisher를 통해 전달하고 Subscriber에 전달된다.


    2. Observer Pattern의 사용

    옵저버 패턴은 주로 MVC패턴과 같이 사용된다.

    ViewController는 Subscriber를 갖고 있고, Model은 Publisher를 갖고 있다.


    이렇게 구현하면 Model이 ViewController에 대한 레퍼런스가 전혀 없어도 변화를 전달할 수 있다.

    서로 다른 여러개의 ViewController가 하나의 Model의 변화를 관찰하는 것도 가능하다.



    // 1 

    import Combine 


    // 2 

    public class User { 

    // 3 

    @Published var name: String 


    public init(name: String) { 

    self.name = name 

    }


    1. Combine을 사용한 예제코드다.

    2. @Published 프로퍼티는 클래스에서만 사용가능하다. Struct, enum등은 사용 불가능

    3. String타입의 프로퍼티 name앞에 @Published 을 붙여줬다. 이렇게 선언하면 컴파일러가 name에 해당하는 Publisher를 생성해준다.



    // 1 

    let user = User(name: "Ray") 


    // 2 

    let publisher = user.$name 


    // 3 

    var subscriber: AnyCancellable? = publisher.sink() { 

    print("User's name is \($0)") 


    // 4 

    user.name = "Vicki"


    1. name이 Ray인 객체를 하나 생성

    2. user.$name을 통해 name프로퍼티의 변화를 Broadcast해주는 Publisher에 접근할 수 있다. 리턴타입은 Published<String>.Publisher.

    3. Publisher의 sink메소드를 통해 Subscriber를 생성한다. sink()에 전달하는 클로저는 Value의 최초 값과 앞으로 변화는 값이 전달될 때마다 호출된다.

    4. name의 값을 변경한다.


    User's name is Ray 

    User's name is Vicki



    subscriber = nil 

    user.name = "Ray has left the building"


    Subscirber를 nil로 설정하면 앞으로 이벤트 전달을 받지 않게 된다.

    따라서 user.name을 새로운 값으로 설정해도 콘솔에 print가 수행되지 않는 것을 확인할 수 있다.



    3. 느낀 점

    모델의 변경과 UI변경을 동기화하기에는 이만한 방법이 없다.

    Observer아니면 Delegate를 사용해야 했다.


    UIKit의 대부분에서 Delegate를 사용하기 때문에 Delegate패턴에 익숙해져 있지만, (실제로 둘은 매우 유사한듯..ㅋㅋ)

    Observer패턴 적용을 항상 고려해보고 사용하면 넘나 편리할 것 같다.

    Model이 delegate라는 레퍼런스를 갖고 있지 않아도 되서 좋고 한번에 여러 객체에 Publish할 수 있는것이 보장되어서 좋다.

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

    Strategy Pattern (with iOS, Swift)  (0) 2020.01.02
Designed by Tistory.