해당 글은 Tstory 블로그 Dev inpa에 출처를 두고 있습니다.
이번 패턴은 Observer 패턴이 되겠다.
Observer?
패턴의 이름이 관측자, 관찰자 패턴이다.
패턴의 용도를 굉장히 함축적으로 잘 표현한 이름인 것 같다.
Observer 패턴은 아래와 같이 간단하게 정의할 수 있다.
관찰자들에게 보내는 변경사항 알림을 자동화하기 위한 패턴!
아래로 사용 예시를 보며 좀 더 자세히 알아보도록 하자.
사용 이유
예를 들어 기온, 습도, 기압을 보여주는 날씨 API가 있다고 해보자.
사용자들은 해당 API를 조회하여 현재 날씨를 볼 수가 있다.
이 때 만약 코드가 아래와 같이 구현되어있다면 어떨까?
클래스의 구조가 위와 같이 구현 되어있다면 아래와 같이 사용될 것이다.
이렇게 매번 사용을 해야한다면, 굉장히 불편할 것이다.
유저가 관리되는 users
가 현재 Client 측에서 관리되고 있다.
또한 날씨가 갱신될 때, 사용자가 직접 조회를 해야 날씨가 바뀌게 된다.
Client 측에 계속 코드가 달라 붙게 되고, 변경될 여지가 있게 된다.
이럴 때 우리는 Observer 패턴을 사용할 수 있다!
구현
우리는 Subject
와 Observer
이라는 2개의 인터페이스를 생성한다.
Subject
는 Publisher, 즉 발행인의 역할을 담당하게 된다.
Observer
는 Subscriber, 구독자의 역할을 담당하게 된다.
이제 위에서 생성했던 WeatherApi
를 통해 interface를 구현해보자.
이제 구독자들은 Client가 아닌 Subject
에서 관리하게 된다.
또한 notify
동작을 통해서 구독자들에게 알림을 보내도록 할 수 있다.
위와 같이 구독 및 구독 취소 함수 또한 Override 해준다.
이제 우리는 구독자에 대한 관리를 전적으로 발행인 객체가 담당하도록 했다.
이렇게 구현되면 실제로는 아래와 같이 사용할 수 있을 것이다.
더 이상 Client에서 구독자를 관리하지 않음을 볼 수 있다.
또한 날씨가 갱신이 되었을 때 구독자들이 직접 조회를 할 필요가 없다.
weatherChange
가 작동하는 순간 notify
도 작동하기 때문에,
구독자들은 Subject
로 부터 알림을 받아 자동으로 조회가 가능해진다.
Client 코드가 굉장히 간결해졌다!
장단점
아래는 Observer 패턴의 장점이다.
- Subject의 상태 변경을 Observer가 자동으로 감지한다.
- Subject의 코드를 변경하지 않아도 새 Observer 클래스 도입이 가능하다.
- Subject와 Observer은 서로 느슨한 관계를 유지할 수 있다.
- 위의 모든 장점은 유지보수가 용이하게 돕는다!
아래는 Observer 패턴의 단점이다.
- 우리가 직접 알림을 받는 순서를 제어할 수 없다.
- 코드 복잡도가 증가한다.
- 다수의 Observer 객체에 의해 메모리 누수가 발생할 수도 있다.
- 더 이상 필요하지 않다면, 반드시 MemoryPool에서 해제해야 한다.
다른 예시 직접 구현
위의 날씨 예제를 보면서, 문득 떠오른 것이 있다.
유튜브의 구독 기능과 알림 설정 기능이 굉장히 유사하다는 것이다!
따라서 간이 유튜브를 직접 한 번 구현해 보았다.
Subject
클래스, 즉 유튜버의 입장에서는 이런 기능들이 있을 것이다.
구독자를 직접 관리하고, 영상이 업로드 되었을 떄 사용자에게 알림이 가도록한다.
구독자들은 아래와 같은 기능을 가질 수 있을 것이다.
알림을 끄고 켜는 설정이 가능하며, 값에 따라 알림을 수신할 수 있다.
또한 구독한 유튜버가 영상을 업로드하면 자동으로 알림이 수신된다.
그 결과 아래와 같이 메인 함수에서 사용해보았다.
원하는 대로 잘 동작하는 것 같다.
아마 실제 유튜브는 이것보다 훨씬 더 복잡한 형태로 구현되었을 것이다.
사실 내가 구현한 부분이 틀렸을 수도 있다.
하지만 이렇게 하나씩 직접 구현해보는 것도 중요하다고 생각한다.