Chapter 4. Observer Pattern

개발하는 운동인·2024년 11월 7일

⭐ 이 내용은 State Pattern 내용과 연결되니 State Pattern 게시글 참고

⭐ Observer Pattern

  • 어떤 업무를 누군가에게 줬을 때 그 누군가가 그 업무를 기억한 뒤, 업무를 마치고 나서 되돌려준다.

⭐ 이 패턴에서 이해를 돕기 위해 유튜버와 해당 유튜버를 유료로 구독하는 구독자를 예로 들어 설명할 것이다.

⭐ Observer Pattern 생성 방법

    1. 기존 StateMachine 클래스에서 아래 코드를 작성한다.
  • event를 붙이게 되면 action이 구독한 함수들을 stateChanged 변수에 저장. 단, 함수들을 받을 때 파라미터 IState를 넘겨줄 것

  • event 키워드 추가시 stateChanged 에 구독한 이벤트(함수)들이 쌓인다.

  • stateChanged 객체(변수)는 유튜버를 의미한다.

  • 이 유튜버는 원하는 구독자가 있다. 원하는 것은 IState 타입이여야 한다.

    1. StateDisplayer 클래스를 생성한 다음 TextMeshPro 객체와 PlayerController 객체를 선언한다.
    1. Awake문에서 PlayerController 클래스를 접근할 수 있게 GetComponent를 사용한다.
    1. OnEnable() 메서드에서 유튜버를 구독하고, OnDisable() 메서드에서 유튜버를 구독 취소하는 코드를 작성한다.
  • OnStateChanged 는 구독자를 의미한다.

  • player.stateMachine.stateChanged += OnStateChanged; 유튜버인 stateChanged 를 유료로 구독 하는 OnStateChanged 구독자이다.

  • player.stateMachine.stateChanged -= OnStateChanged; 유튜버인 stateChanged 를 유로로 구독했던 것을 취소하는 OnStateChanged 구독자이다.

    1. OnStateChanged 메서드를 작성한다.
  • IState의 객체인 state을 이용하여 GetType().Name;을 해서 각 상태에 이름을 text에 저장한다.

  • 1번에서 유튜버는 IState 타입을 갖고 있는 구독자를 원하므로, OnStateChanged(구독자)는 IState 타입의 매개변수를 갖고 있어야 한다.

    1. 유튜버를 유료로 구독하는 구독자에게 이벤트를 뿌린다.
  • stateChanged? : stateChanged에 구독된 것들이 null인지 아닌지 판별. null이 아니라면 이벤트 뿌린다.

  • 이벤트를 뿌릴 때 유튜버는 IState을 갖고있는 구독자를 원하기 때문에 뿌릴 때도 IState타입을 갖고 있는 구독자에게 뿌린다. CurrentState는 IState 타입이다.

  • 이벤트를 뿌릴 때는 Invoke()을 사용한다.

    1. TMP를 할당한다.
  • 실행 결과

🤔 번외 - 오류 해결 부분 <- 중요

    1. 플레이어 컨트롤러에 Awake 와 Start 가 있다.
    1. StatePlayer에 Awake와 OnEnable, OnDisable 이 있다.

위 패턴을 다 만들었지만 실행 시, OnEnable 부분에서 오류가 발생한다.

정확하게는 OnEnable 메서드에서 player.stateMachine 부분에서 오류가 발생했다.

  • 두 클래스 모두 Awake를 갖고 있고, 어떤 클래스가 먼저 Awake를 실행할지 정확히 해야한다.
  • 현재 StateDisPlayer 클래스가 Awake가 먼저 실행되고, 그리고 나서, StateDisPlayer 클래스의 OnEnable 메서드가 실행되기 때문에 PlayerController의 Awake는 실행되지 않았으므로, stateMachine에서 오류가 발생한 것이다.
  • 즉, StateDisPlayer 클래스의 OnEnable 메서드가 PlayerController의 Awake보다 먼저 실행 하므로 PlayerController의 Awake메서드에서 stateMachine의 생성자 호출하는 부분이 실행 되지 않은 것이다.

⭐ 해결 방법

  • 프로젝트 설정 창에서 우선순위를 설정한다. 플레이어 컨트롤러가 먼저 실행할 수 있게 한다.

0개의 댓글