소프트웨어 아키텍처 전공 수업을 듣다가 조교님께서 옵저버 패턴에 대해 설명해주셨는데,
과거에 공부했던 내용을 복습할겸 다시 정리하기로 하였다.
'관찰자'라는 의미에서 스타크래프트의 '옵저버'와 동일한 의미를 갖는다고 볼 수 있다.
📚 책 '헤드퍼스트 디자인패턴'에서 (많이) 참고하였다.
시작하기에 앞서, 관리가 용이한 객체지향 시스템을 설계하기 위해서는
"나중에 어떻게 바뀔 것인지"에 대해 생각하면서
추상화나 상속, 다형성 같은 개념을 적용하여 유연한 디자인을 만들어야 한다고 생각한다.
이 말을 새겨듣고 들어가보자.
옵저버 패턴은 마치 구독자와 유튜버로 이루어지는 유튜브 구독 시스템이라고 보면 됩니다.
하지만 정확한 정의를 보자면 다음과 같습니다.
옵저버 패턴은 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체에게 연락이 가고
자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의합니다.
사실 옵저버 패턴을 여러 가지 방법으로 구현할 수 있지만, 전공 수업 시간에서는
subject 인터페이스와 observer 인터페이스가 들어있는 클래스 디자인으로 설명하였기 때문에
이를 바탕으로 정리해 보겠습니다.
우선 StarUML을 사용하여 옵저버 패턴의 클래스 다이어그램을 간략하게 그려보았습니다.
Subject
주제를 나타내는 Subject 인터페이스입니다.
객체에서 옵저버로 등록하거나 옵저버 목록에서 탈퇴하고 싶을 때는
이 인터페이스에 있는 메소드를 사용합니다.
Observer
옵저버가 될 가능성이 있는 객체는
반드시 Observer 인터페이스를 구현해야 합니다.
이 인터페이스에는 주제의 상태가 바뀌었을 때 호출되는
update() 메소드밖에 없습니다.
ConcreteSubject
주제 역할을 하는 구상 클래스에는 항상 Subject 인터페이스를 구현해야 합니다.
주제 클래스에는 등록 및 해지용 메소드와
상태가 바뀔 때마다 모든 옵저버에게 연락하는
notifyObservers() 메소드도 구현해야 합니다.
또한 주제 클래스에는 상태를 설정하고 알아내는
세터/게터 메소드가 들어있을 수도 있습니다.
ConcreteObserver
Observer 인터페이스만 구현한다면
무엇이든 옵저버 클래스가 될 수 있습니다.
각 옵저버는 특정 주제에 등록해서
연락받을 수 있습니다.
데이터의 주인은 주제(Subject)입니다.
옵저버(Observer)는 데이터가 변경되었을 때
주제에서 갱신해 주기를 기다리는 입장이기에 의존성을 가진다고 할 수 있습니다.
⭐️ 여기서 잠깐!
느슨한 결합 (Loose Coupling)은 객체들이 상호작용할 수는 있지만 서로를 잘 모르는 관계를 의미합니다.
이러한 느슨한 결합을 활용하면 유연성이 아주 좋아집니다.
옵저버 패턴은 느슨한 결합을 보여주는 훌륭한 예입니다.
옵저버 패턴에서 어떤 식으로 느슨한 결합을 만드는지 알아봅시다.
주제(Subject)는 특정 인터페이스(Observer Interface)를 구현한다는 사실만 압니다.
옵저버는 언제든지 새로 추가할 수 있습니다.
새로운 형식의 옵저버를 추가할 때도 주제를 변경할 필요가 전혀 없습니다.
주제와 옵저버는 서로 독립적으로 재사용할 수 있습니다.
주제나 옵저버가 달라져도 서로에게 영향을 미치지는 않습니다.