๋ฐฉ๋ฌธ์ž ํŒจํ„ด

๋ฐฉ๋ฌธ์ž ํŒจํ„ด (Visitor Pattern)

๊ฐ์ฒด ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ์ƒˆ๋กœ์šด ๋™์ž‘์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ–‰์œ„ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ๋ฐฉ๋ฌธ์ž ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ๊ธฐ์กด ํด๋ž˜์Šค์˜ ์ˆ˜์ • ์—†์ด ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ด€๋ จ ๋™์ž‘์„ ํ•œ ๊ณณ์— ๋ชจ์•„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๋ชฉ์ 

โ€ข
๊ฐ์ฒด ๊ตฌ์กฐ์™€ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์œ ์—ฐ์„ฑ ํ™•๋ณด
โ€ข
๊ธฐ์กด ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด ์ƒˆ๋กœ์šด ๋™์ž‘ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ
โ€ข
๊ด€๋ จ ๋™์ž‘์„ ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ–ฅ์ƒ

ํŠน์ง•

โ€ข
Double Dispatch๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‹คํ–‰ ์‹œ์ ์— ์ ์ ˆํ•œ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
โ€ข
๊ฐ์ฒด ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๋‹จ์ผ ์ฑ…์ž„ ์›์น™ ์ค€์ˆ˜
โ€ข
์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ์‹œ Visitor ํด๋ž˜์Šค๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๋จ

๊ตฌ์„ฑ์š”์†Œ

โ€ข
Visitor: visit() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ ์š”์†Œ์— ๋Œ€ํ•ด ๋ฐฉ๋ฌธํ•  ์ž‘์—…์„ ์ •์˜ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.
โ€ข
ConcreteVisitor: Visitor ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ๊ฐ ๊ฐ์ฒด ํƒ€์ž…์— ๋Œ€ํ•ด ๊ตฌ์ฒด์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
โ€ข
Element: ๋ฐฉ๋ฌธ์„ ๋ฐ›๋Š” ๊ฐ์ฒด๋“ค์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. accept() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ฐฉ๋ฌธ์ž๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.
โ€ข
ConcreteElement: Element ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. accept() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ฐฉ๋ฌธ์ž๋ฅผ ์ˆ˜๋ฝํ•ฉ๋‹ˆ๋‹ค.
โ€ข
ObjectStructure: ์—ฌ๋Ÿฌ ๊ฐœ์˜ Element ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ๊ฐ ๊ฐ์ฒด์— ๋Œ€ํ•ด ๋ฐฉ๋ฌธ์ž๋ฅผ ์ˆœํšŒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

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

// Element ์ธํ„ฐํŽ˜์ด์Šค interface Shape { void accept(ShapeVisitor visitor); } // Concrete Elements class Circle implements Shape { public void accept(ShapeVisitor visitor) { visitor.visit(this); } } class Rectangle implements Shape { public void accept(ShapeVisitor visitor) { visitor.visit(this); } } // Visitor ์ธํ„ฐํŽ˜์ด์Šค interface ShapeVisitor { void visit(Circle circle); void visit(Rectangle rectangle); } // Concrete Visitor class AreaCalculator implements ShapeVisitor { public void visit(Circle circle) { System.out.println("์›์˜ ๋„“์ด ๊ณ„์‚ฐ"); } public void visit(Rectangle rectangle) { System.out.println("์‚ฌ๊ฐํ˜•์˜ ๋„“์ด ๊ณ„์‚ฐ"); } }
Java
๋ณต์‚ฌ

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

์œ„ ์˜ˆ์‹œ ์ฝ”๋“œ๋Š” ๋„ํ˜•์˜ ๋„“์ด๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ๋ฌธ์ž ํŒจํ„ด์„ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
โ€ข
Shape ์ธํ„ฐํŽ˜์ด์Šค (Element): ๋ฐฉ๋ฌธ์ž๋ฅผ ๋ฐ›์•„๋“ค์ด๋Š” accept() ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
โ€ข
Circle, Rectangle ํด๋ž˜์Šค (Concrete Elements): Shape ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ๋„ํ˜• ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ๊ฐ๊ฐ accept() ๋ฉ”์„œ๋“œ์—์„œ ๋ฐฉ๋ฌธ์ž์˜ visit() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
โ€ข
ShapeVisitor ์ธํ„ฐํŽ˜์ด์Šค (Visitor): ๊ฐ ๋„ํ˜• ํƒ€์ž…์— ๋Œ€ํ•œ visit() ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
โ€ข
AreaCalculator ํด๋ž˜์Šค (Concrete Visitor): ShapeVisitor ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ๊ฐ ๋„ํ˜•์˜ ๋„“์ด๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ๋™์ž‘์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
์ด ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๋„ํ˜•์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” Shape๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ , ์ƒˆ๋กœ์šด ๋™์ž‘์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” ShapeVisitor๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ ๋„ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.