728x90
옵져버 패턴은 어떤 객체의 상태가 변하면 그 객체의 상태에 의존성을 가진 다른 객체들이 그 변화를 통지 받고 자동으로 업데이트하게 하는 패턴.
쉽게 말하면 (전파자 - 전파를 받는 자들 (일대다))의 관계로 한명이 여러명에게 전달을 하는 거다.
아래는 이해하기 쉽도록 스타크래프트의 마린의 상태를 예로 들어 옵져버 패턴을 적용해본 예시이다.
마린의 상태는 내가 보는 모니터의 메인화면과, 캐릭터의 상태창, 적의화면에 모두 동일하게 체력상태가 보여야 된다는 것이다.
마린의 체력 상태가 변경된다면 메인화면, 상태창, 적의화면이라는 전파를 받는 자들에게 상태를 업데이트하라고 명령을 하는것이다.
001.using
System;
002.
using
System.Collections.Generic;
003.
using
System.Linq;
004.
using
System.Text;
005.
006.
namespace
Observer
007.
{
008.
class
Program
009.
{
010.
static
void
Main(
string
[] args)
011.
{
012.
013.
Marine ourMarine =
new
Marine(
"아군 마린"
, 100);
014.
ourMarine.Attach(
new
MainScreen());
015.
ourMarine.Attach(
new
StatusScreen());
016.
ourMarine.Attach(
new
EnemyScreen());
017.
018.
ourMarine.Health = 60;
019.
ourMarine.Health = 40;
020.
021.
Console.ReadKey();
022.
}
023.
024.
abstract
class
Unit
025.
{
026.
private
string
name;
027.
private
int
health;
028.
private
List<UnitViewer> unitViewers =
new
List<UnitViewer>();
029.
030.
public
Unit(
string
name,
int
health)
031.
{
032.
this
.name = name;
033.
this
.health = health;
034.
}
035.
036.
public
void
Attach(UnitViewer investor)
037.
{
038.
unitViewers.Add(investor);
039.
}
040.
041.
public
void
Detach(UnitViewer investor)
042.
{
043.
unitViewers.Remove(investor);
044.
}
045.
046.
public
void
Notify()
047.
{
048.
foreach
(UnitViewer unitviewr
in
unitViewers)
049.
{
050.
unitviewr.Update(
this
);
051.
}
052.
}
053.
054.
055.
public
int
Health
056.
{
057.
get
{
return
health; }
058.
set
059.
{
060.
health = value;
061.
Notify();
062.
}
063.
}
064.
065.
public
string
Name
066.
{
067.
get
{
return
name; }
068.
}
069.
}
070.
071.
class
Marine : Unit
072.
{
073.
public
Marine(
string
name,
int
health)
074.
:
base
(name, health)
075.
{
076.
}
077.
}
078.
079.
080.
interface
UnitViewer
081.
{
082.
void
Update(Unit unit);
083.
}
084.
085.
086.
class
MainScreen : UnitViewer
087.
{
088.
private
Unit unit;
089.
090.
public
void
Update(Unit _unit)
091.
{
092.
this
.unit = _unit;
093.
Console.WriteLine(
"메인화면 {0} 상태 변경 : 체력 {1}"
,
this
.unit.Name,
this
.unit.Health.ToString());
094.
}
095.
096.
public
Unit Unit
097.
{
098.
get
{
return
unit; }
099.
set
{ unit = value; }
100.
}
101.
}
102.
103.
class
StatusScreen : UnitViewer
104.
{
105.
private
Unit unit;
106.
107.
public
void
Update(Unit _unit)
108.
{
109.
this
.unit = _unit;
110.
Console.WriteLine(
"상태창 {0} 상태 변경 : 체력 {1}"
,
this
.unit.Name,
this
.unit.Health.ToString());
111.
}
112.
113.
public
Unit Unit
114.
{
115.
get
{
return
unit; }
116.
set
{ unit = value; }
117.
}
118.
}
119.
120.
class
EnemyScreen : UnitViewer
121.
{
122.
private
Unit unit;
123.
124.
public
void
Update(Unit _unit)
125.
{
126.
this
.unit = _unit;
127.
Console.WriteLine(
"적 상태창 {0} 상태 변경 : 체력 {1}"
,
this
.unit.Name,
this
.unit.Health.ToString());
128.
}
129.
130.
public
Unit Unit
131.
{
132.
get
{
return
unit; }
133.
set
{ unit = value; }
134.
}
135.
}
136.
}
137.
}
Marine 클래스는 Unit이라는 클래스를 상속받고 있고, Attach 메소드를 통해서 UnitViewer(메인화면), StatusScreen(상태창), EnemyScreen(적 상태창) 이 3개의 클래스들 즉 전파를 받을 자들을 등록한다.
위 3개의 클래스들은 UnitViewer라는 인터페이스를 상속받고 있고 인터페이스 안에 있는 Update 함수를 각 클래스들에 맞게 재정의 해주고 있다.
이제 마린의 체력 상태가 바뀌게 되면 체력 수치를 바꾸고 Notify 메소드를 통해 등록되어있는 전파자들에게 Update 함수를 실행하도록 한다.
728x90
'기타' 카테고리의 다른 글
팩토리 메소드 패턴 (Factory Method Pattern) (0) | 2016.10.13 |
---|---|
심플 팩토리 패턴 (Simple Factory Pattern) (0) | 2016.10.13 |
winsock i/o 모델 종류.. (0) | 2016.10.10 |
학원 과제들 날짜별 모음. (0) | 2014.01.14 |
2013 정보처리기사 실기 2회 가답안 [7월 14일] (0) | 2013.07.14 |