2. 옵저버 패턴
- 정의: 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들에게 연락이 가고, 자동으로 내용이 갱신되는 방식으로, 일대다(one-to-many) 의존성. 느슨함. (이후 등장할 모델-뷰 패턴과 비교해보자)
- Subject(주제) 와 Observer(옵저버. 다수) 간의 연결이며, 퍼블리싱-섭스크라이브 형태이다.
- 서브젝트에 옵저버 리스트가 있고 언제나 리스트에 다른 옵저버를 추가할 수 있고, 옵저버인 객체가 서브젝트를 구독하고, 구독취소를 할 수도 있다.
- 일반적으로는 주제에서 푸쉬방식으로 옵저버들에게 노티를 보내는데, 옵저버에서 주제를 풀 하기도 한다. (이것이 좀 더 좋은 방식이라고 생각한다. 정체를 밝히고 필요 데이터만 받아가니까.)
- 옵저버가 될 가능성이 있으면 옵저버 인터페이스를 구현하고, 옵저버가 서브젝트가 되는 것도 가능하다!
- 서브젝트는 옵저버의 명세만 알면 되고 구체적 내용은 캡슐화 한다. → 느슨한 결합
- 서브젝트는 값이 변경될 때마다 알리지 않고, 내용 변경을 처리하는 함수 내에서 일정 수치를 넘거나 하는 등의 상황에서 notifyObservers()를 호출하는 식으로 처리할 수도 있다.
- 옵저버쪽에서 풀 할 때는 서브젝트에서 노티를 보내는 부분과 옵저버 리스트를 저장하는 부분을 지우고, 옵저버에서 서브젝트의 참조를 통해 서브젝트를 특정, 이후 update에서 서브젝트참조객체.값 으로 받아서 사용하고, 필요 없어지거나 변경할 때 새로 서브젝트의 참조를 변경하면 됨. 단순히 읽기 전용으로 데이터를 받아 오기만 하므로 위험하지는 않음 (아무나 접근해서 위험하다고 한다면 뿌리는 방식도 옵저버이기만 하면 아무한테나 뿌리기 때문에 위험성은 동일함)
- 푸쉬방식의 장점은 모든 데이터를 뿌리기 때문에 간단하다는 점. 단점은 필요 없는 데이터도 모두 뿌리니까 구독자가 늘 수록 느려짐.
- 풀 방식의 장점은 원하는 데이터만을, 필요할 때만 전송한다는 점. 단점은 일반성이 떨어져 재사용성이 악화되고 데이터 타입이 제약조건이 되므로 덜 유연하다는 점.
- + 옵저버에게 연락이 가는 순서에 의존하는 코드를 짜서는 안된다. 순서가 고정되어야 정상작동한다면 유연한 결합도 아니고, 언제나 옵저버를 추가,제거 할 수 있다는 원칙도 사라짐.
장점: 유연,느슨한 객체지향 시스템! 계속 확장할 수 있다! 어디든지 무난하게 연결할 수 있다.(런타임에서!) 주기적인 데이터 전송을 보장한다.
단점: 알림 순서를 보장하지는 않는다. 관계가 잘 정의되지 않았을 때 원하지 않는 동작이 발생할 수 있다. 구독 객체 사이의 레지스터 관리를 잘 해야 메모리누수가 안 일어난다. + 객체가 많아지면 계속 노티를 보내는 것 자체로 부담이 커진다.(노티를 보내는 것 자체에 대한 노티를 관리해서 (플레이어 주변 반경으로 특정한다던가) 업데이트 부담을 줄이면 됨) + 오브젝트를 등록,해지하는 과정이 필요하다.