● 옵저버 패턴 (Observer Pattern)

 - 한 객체(Subject)의 상태가 바뀌면 그 객체에 의존하는 모든 객체들(Observers)에 알린 후(Notify) 자동으로 내용이 갱신(Update)되는 방식

 - 일대다(one-to-many) 의존성을 정의함

 - MVC 패턴의 View에 해당하는 부분에서 많이 나타날 수 있음 

 - 한 객체의 상태에 대한 참조를 여러 곳에서 하고 있을 때 주로 사용 될 수 있음

 - 때문에, 한 객체의 상태에 대한 일관성이 보장됨



 UML Diagram - Observer Pattern



아주 간단한 예를 들면, (아래의 스크린 샷은 페인트히어로즈의 히어로 선택창스킬 정보창입니다.)

페인트히어로즈에서 현재 선택된 히어로(Subject)가 무엇인지에 따라


이를 의존하고 있던 스킬 정보창의 UI 요소들(Observers - 스킬 이름, 스킬 설명, 스킬 레벨, 스킬 아이콘 등...)이

자동으로 현재 선택된 히어로에 대한 내용으로 갱신되어 유저에게 보여지는 것도 Observer Pattern이 사용될 수 있습니다.




- Source Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Subject.cs
using System.Collections.Generic;
 
public class Subject 
{
    private List<Observer> observerList = new List<Observer>();
 
    public void Attach (Observer o)
    {
        observerList.Add(o);
    }
 
    public void Notify ()
    {
        foreach (Observer o in observerList)
        {
            o.Update();
        }
    }
}
 
 
// SbjHero.cs
public class SbjHero : Subject
{
    private string _heroName;
    private string _heroSkillName;
 
    public string heroName
    {
        get { return _heroName; }
        set { _heroName = value; }
    }
 
    public string heroSkillName
    {
        get { return _heroSkillName; }
        set { _heroSkillName = value; }
    }
}
 
 
// Observer.cs
public abstract class Observer
{
    public abstract void Update ();
}
 
 
// ObsHeroName.cs
using UnityEngine;
 
public class ObsHeroName : Observer 
{
    private SbjHero sbjHero;
 
    public ObsHeroName (SbjHero sbj)
    {
        sbjHero = sbj;
    }
 
    public override void Update ()
    {
        Debug.Log("current hero name : " + sbjHero.heroName);
    }
}
 
 
// ObsHeroSkill.cs
using UnityEngine;
 
public class ObsHeroSkill : Observer 
{
    private SbjHero sbjHero;
 
    public ObsHeroSkill (SbjHero sbj)
    {
        sbjHero = sbj;
    }
 
    public override void Update ()
    {
        Debug.Log("current hero skill name : " + sbjHero.heroSkillName);
    }
}
 
 
// Game.cs
using UnityEngine;
using System.Collections;
 
public class Game : MonoBehaviour 
{
    void Start ()
    {
        SbjHero h = new SbjHero();
 
        h.Attach(new ObsHeroName(h));
        h.Attach(new ObsHeroSkill(h));
 
        // change subject state and notify observers
        h.heroName = "Lucian";
        h.heroSkillName = "Charging Shot";
        h.Notify();
 
        // result
        // current hero name : Lucian
        // current hero skill name : Charging Shot
    }
}
cs


+ Recent posts