๋ฐ˜์‘ํ˜•

์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ ์˜ต์ €๋ฒ„ ํŒจํ„ด(Observer Pattern)์— ๋Œ€ํ•ด ์„ค๋ช…ํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.
[Design Pattern] ์˜ต์ €๋ฒ„ ํŒจํ„ด(Observer Pattern) ์ด์•ผ๊ธฐ (์˜ˆ์ œ ํฌํ•จ)

 

[Design Pattern] ์˜ต์ €๋ฒ„ ํŒจํ„ด(Observer Pattern) ์ด์•ผ๊ธฐ #1 (์˜ˆ์ œ ํฌํ•จ)

์˜ต์ €๋ฒ„ ํŒจํ„ด(Observer Pattern) ์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ๊ด€์ฐฐ์ž ํŒจํ„ด์ด๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋Œ€๋‹ค ๊ด€๊ณ„๋ฅผ ์ด๋ฃจ๊ณ  ์žˆ์œผ๋ฉฐ, ์ƒํƒœ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋ฉด ๋ชจ๋“  ์˜ต์ €๋ฒ„๋“ค์—๊ฒŒ ์ •๋ณด๋ฅผ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ข€ ๋” ์ดํ•ดํ•˜..

luckygg.tistory.com

๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•˜๋ฉด, ์ฃผ์ œ์ž(Subject)์— ๊ตฌ๋…์ž(Observer)๊ฐ€ ๋“ฑ๋ก(Register)๋˜์–ด ๋ชจ๋“  ๊ตฌ๋…์ž๊ฐ€ ๊ฐ™์€ ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธ(Notify)๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์•„์ฃผ ์‰ฌ์šด ์ฝ˜์†” ๊ธฐ๋ฐ˜์˜ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์†Œ๊ฐœํ–ˆ์—ˆ๋Š”๋ฐ์š”. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ข€ ๋” ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ  ์นœ์ˆ™ํ•œ ์œˆํผ(WinForm) ๊ธฐ๋ฐ˜์˜ ์ƒ˜ํ”Œ ์ฝ”๋“œ๋ฅผ ์†Œ๊ฐœํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

WinForm ๊ธฐ๋ฐ˜์˜ Observer Pattern ์˜ˆ์ œ

์†Œ๊ฐœํ•ด๋“œ๋ฆด ์˜ˆ์ œ ์ฝ”๋“œ์˜ ๊ตฌ์กฐ๋Š” ์•„๋ž˜ UML๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. Subject interface๋ฅผ MainForm class๊ฐ€ ์ƒ์†๋ฐ›์•„ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , Observer interface๋ฅผ SubForm class๊ฐ€ ์ƒ์†๋ฐ›์•„ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  MainForm์˜ Textbox์— ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•˜๊ณ  Enterํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด, ์ด ์ˆซ์ž๊ฐ€ ๋ชจ๋“  SubForm์— ๊ฐฑ์‹ ํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ UML

์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ๋™์ผํ•œ ์ •๋ณด๋ฅผ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉ๋  ๋•Œ ์œ ์šฉํ•œ ๋ฐฉ๋ฒ•๋ก ์ž…๋‹ˆ๋‹ค. ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ๋Š” YouTube๋‚˜ ์‹ ๋ฌธ์‚ฌ์™€ ๊ฐ™์€ ์˜ˆ์‹œ๋ฅผ ๋“ค์—ˆ๋Š”๋ฐ์š”. ์ด๋ฒˆ์—๋Š” ๋น„์ „ ํ”„๋กœ๊ทธ๋ž˜๋ฐ๊ณผ ์—ฐ๊ด€ ์ง€์–ด ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์นด๋ฉ”๋ผ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ Form์—์„œ ์ ‘๊ทผํ•ด์•ผ ํ•  ๋•Œ ์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด, ๋ชจ๋“  Form์—์„œ ํ•ญ์ƒ ํ˜„์žฌ ๊ฐ’์„ ์—…๋ฐ์ดํŠธ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ์ด๋Ÿฌํ•œ ๋””์ž์ธ ํŒจํ„ด์„ ์ ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํŠน์ • ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ•ญ์ƒ ํ™•์ธํ•˜๋„๋ก ๊ตฌํ˜„ํ•ด์•ผ๊ฒ ์ฃ ? (์‚ฌ์‹ค ์œ„ ์˜ˆ์‹œ๋Š” MVC ํŒจํ„ด์ด ๋” ์ ํ•ฉํ•˜๊ธด ํ•ฉ๋‹ˆ๋‹ค. MVC ํŒจํ„ด์€ ์ถ”ํ›„์— ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.)

์•„๋ž˜ ๊ทธ๋ฆผ์€ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋™์ž‘์‹œํ‚จ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.

์˜ˆ์ œ ๋™์ž‘ ํ™”๋ฉด

์ฝ”๋“œ ์„ค๋ช…

Subject์™€ Observer interface๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

public interface Subject
{
	void registerObserver(Observer o);
	void removeObserver(Observer o);
	void notifyObservers();
}

public interface Observer
{
	void update(int value);
}

Observer interface๋ฅผ ์ƒ์†๋ฐ›๋Š” SubForm1, 2๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž์—์„œ Subject์˜ registerObserver๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ž๊ธฐ ์ž์‹ ์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  update๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด TextBox์— ์ธ์ž๋กœ ๋ฐ›์€ ๊ฐ’์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

public partial class SubForm1 : Form, Observer
{
	Subject _subject;
	public SubForm1(Subject subject)
	{
		_subject = subject;
		subject.registerObserver(this);
		InitializeComponent();
	}
	public SubForm1()
	{
		InitializeComponent();
	}

	public void update(int value)
	{
		textBoxValue.Text = value.ToString();
	}
}

๋งˆ์ง€๋ง‰์œผ๋กœ Subject interface๋ฅผ ์ƒ์†๋ฐ›์€ MainForm์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์˜ต์ €๋ฒ„ ๋ชฉ๋ก์€ ArrayList๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ, Subject interface์— ์ •์˜๋œ ํ•จ์ˆ˜๋“ค์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, TextBox์— KeyDown ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ฐ’์„ ๋ฐ›์•„ ๋ชจ๋“  ์˜ต์ €๋ฒ„๋“ค์—๊ฒŒ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

public partial class MainForm : Form, Subject
{
	SubForm1 _subForm1 = null;
	SubForm2 _subForm2 = null;
	IList _observers = new ArrayList();
	public MainForm()
	{
		InitializeComponent();

		_subForm1 = new SubForm1(this);
		_subForm1.TopLevel = false;
		_subForm1.FormBorderStyle = FormBorderStyle.None;
		_subForm1.Dock = DockStyle.Fill;
		panelTab1.Controls.Add(_subForm1);
		_subForm1.Show();

		_subForm2 = new SubForm2(this);
		_subForm2.TopLevel = false;
		_subForm2.FormBorderStyle = FormBorderStyle.None;
		_subForm2.Dock = DockStyle.Fill;
		panelTab2.Controls.Add(_subForm2);
		_subForm2.Show();
	}

	public void notifyObservers()
	{
		foreach (Observer o in _observers)
			o.update(Convert.ToInt32(textBoxValue.Text));
	}

	public void registerObserver(Observer o)
	{
		_observers.Add(o);
	}

	public void removeObserver(Observer o)
	{
		_observers.Remove(o);
	}

	private void TextBoxValue_KeyDown(object sender, KeyEventArgs e)
	{
		if(e.KeyCode == Keys.Enter)
		{
			int value = Convert.ToInt32(textBoxValue.Text);
			notifyObservers();
		}
	}
}

์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ์ฒจ๋ถ€๋œ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”.

ExamObserverPattern2.zip
0.20MB

๋ฐ˜์‘ํ˜•