TIL : 2024-09-02(월) :: 옵저버패턴 , C#(Unity) Delegate,Event 예제
https://luckygg.tistory.com/181
[Design Pattern] 옵저버 패턴(Observer Pattern) 이야기 #1 (예제 포함)
옵저버 패턴(Observer Pattern) 옵저버 패턴은 관찰자 패턴이라고도 합니다. 일대다 관계를 이루고 있으며, 상태가 업데이트되면 모든 옵저버들에게 정보를 갱신할 수 있도록 하는 것을 의미합니다.
luckygg.tistory.com
해당 블로그 글을 보며 정리하였습니다.
Observer Pattern(옵저버패턴)
- 디자인패턴 중 하나
- 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들에게 정보가 자동으로 갱신되는 방식으로, 일대다(one-to-many) 의존성을 정의합니다
- Subject(관찰대상,주제자)가 업데이트 되면 Observer(관찰자)들에게 정보를 갱신 할 수 있도록 함
- ex)Subject(유튜브채널,신문사) / Observer(구독자들)
Observer(관찰자) 특징
- 언제든지 새로 추가 되거나 제거 될수 있어야 함
- 추가 / 삭제가 되더라도 Subject에 영향을 주지 않음 :: 해당 관계를 느슨한 결합(Loose coupling)이라고 함
- C++ 에서 구현시 Observer는 특정 interface를 구현해야만 함
- 해당 interface에서는 Observer는 Update() 기능을 구현함
Subject(주제자) 특징
- Observer에 대한 정보가 없음 : Observer가 무슨 동작을 하는지 모름
- C++ 에서 구현시 Subject는 특정 interface를 구현해야만 함
- 해당 interface에서는 상속받는 Subject Class의 등록,해제,갱신을 구현 및 기타 함수를 구현함.
C#에서는 따로 옵저버 패턴을 구현할 필요가 없다.
이 기능을 Deligate 와 Event 함수가 대신하기 떄문이다.
해당 출처를 참고하면 더욱 도움이 된다.
https://unity.com/kr/how-to/create-modular-and-maintainable-code-observer-pattern
옵저버 패턴으로 유지 관리가 가능한 모듈식 코드 만들기
이 페이지에서는 관찰자 패턴과 이 패턴이 서로 상호작용하는 객체 간의 느슨한 결합 원리를 지원하는 데 어떻게 도움이 되는지 설명합니다.
unity.com
나는 옵저버패턴을 이런식으로 구현해서 사용했지만 , 실제로는 이렇게 구현하면 안된다.
일대다관계로 구성이 되야하지만 현재 일대일 관계로 2개를 구현하였다.
다음에는 구현 시 주의하면 만들어봐야겠다.
C# - Delegate Vs Envet ?
C++ 의 함수포인터를 C#으로 변환한게 Delegate이다.
Delegate는 멀티캐스팅 기능으로 하나의 델리게이트로 여러 인스턴스(객체)가 여러 메서드(함수)를 호출 할수 있도록 구성이 가능하다.
하지만 이렇게되면 객체지향의 4대원칙 중 보안성이 지양되기 때문에 Delegate가 아닌 Event 함수가 주로 사용됩니다.
Event함수는 Delegate기반으로 되있지만 엑세스 제한으로 외부에서 이벤트를 추가(+=)/ 제거(-=)만 가능하며 이벤트 핸들러에 등록된 함수가 호출되지 않는다.
즉, Event함수의 함수호출은 내부클래스에서만 호출이 된다.
특징 | Delegate | Event |
역할 | 함수포인터로 사용 | 델리게이트에 대한 접근을 제한하고 이벤트 모델 제공 |
엑세스 제어 | 어디서든 호출 가능 | 선언된 클래스 외부에서는 호출불가 |
사용 목적 | 일반적인 콜백이나 함수 참조 관리 | 안전한 이벤트 발생 및 처리 |
기본 엑세스 | public | 특별히 제한된 엑세스 (add/Remove만 허용) |
멀티캐스트 지원 | 가능 | 가능 |
<이 부분은 개인적으로 생각한 것을 적은 부분입니다. 틀린 내용이 있으시면 댓글 부탁드립니다 >
왜 하나의 클래스에 Delegate와 Event를 동시에 쓰나요?
Delegate는 함수 포인터라는 자료형의 변수를 선언하는 것과 유사하다.
그리고 Event는 Delegate에서 선언한 변수를 자료형으로 삼고 사용한다.
public delegate void TouchPadMoveHandler(); // delegate 키워드를 사용하여 함수포인터 변수 선언
public static event TouchPadMoveHandler OnTouchLeftPad; //선언한 변수를 자료형으로 event 함수 선언