๋””์ž์ธ ํŒจํ„ด/GOF

๐Ÿ’  ํผ์‚ฌ๋“œ(Facade) ํŒจํ„ด - ์™„๋ฒฝ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

์ธํŒŒ_ 2023. 3. 14. 08:55

Facade-Pattern
Facade-Pattern

Facade Pattern

ํผ์‚ฌ๋“œ ํŒจํ„ด(Facade Pattern)์€ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณต์žกํ•œ ํด๋ž˜์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•˜๊ฒŒ ๊ฐ„ํŽธํ•œ ์ธํ„ฐํŽ˜์ด์Šค(API)๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ตฌ์กฐ ํŒจํ„ด ์ด๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฐ ํด๋ž˜์Šค์™€ ๋ฉ”์„œ๋“œ๋“ค์ด ์–ด๋–ค ๋ชฉ์ ์˜ ๋™์ž‘์ธ์ง€ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์›Œ ๋ฐ”๋กœ ๊ฐ€์ ธ๋‹ค ์“ฐ๊ธฐ์—๋Š” ๋‚œ์ด๋„๊ฐ€ ๋†’์„๋•Œ, ์ด์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ๋„ค์ด๋ฐ๊ณผ ์ •๋ฆฌ๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๋กœ ํ•˜์—ฌ๊ธˆ ์‰ฝ๊ฒŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค๋ฃฐ์ˆ˜ ์žˆ๋„๋ก ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ, ์šฐ๋ฆฌ๊ฐ€ ๊ต์ œ๋ฅผ ๋ณด๊ณ  ํ•„๊ธฐ๋…ธํŠธ์— ์žฌ์ •๋ฆฌ๋ฅผ ํ•˜๋“ฏ์ด ํด๋ž˜์Šค๋ฅผ ์žฌ์ •๋ฆฌํ•˜๋Š” ํ–‰์œ„๋กœ ๋ณด๋ฉด ๋œ๋‹ค.

๋ณธ๋ž˜ ํ”„๋กœ๊ทธ๋žจ์ด๋ผ๋Š” ๊ฒƒ์€ ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•ด ์ ์  ์ปค์ง€๊ฒŒ ๋œ๋‹ค. ๋ฒ„์ „์ด ์˜ฌ๋ผ๊ฐˆ์ˆ˜๋ก ๋งŽ์€ ํด๋ž˜์Šค๋“ค์ด ๋งŒ๋“ค์–ด์ ธ ์„œ๋กœ ๊ด€๊ณ„๋ฅผ ๋งบ์œผ๋ฉด์„œ ์ ์  ๋ณต์žกํ•ด์ง€๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ์ปค๋‹ค๋ž€ ์†”๋ฃจ์…˜์„ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ์ƒํ˜ธ ๊ด€๋ จ๋œ ๋งŽ์€ ํด๋ž˜์Šค๋“ค์„ ์ ์ ˆํžˆ ์ œ์–ดํ•ด์•ผ ํ•  ํ•„์š”์„ฑ์ด ์žˆ๋‹ค. ์ด๋•Œ ์ด ์ฒ˜๋ฆฌ๋ฅผ ๊ฐœ๋ณ„์ ์œผ๋กœ ์ œ์–ดํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ผ์ข…์˜ '์ฐฝ๊ตฌ'๋ฅผ ์ค€๋น„ํ•˜์—ฌ ์ค‘๊ณ„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•ด์ค€๋‹ค๋ฉด, ์‚ฌ์šฉ์ž๋Š” ์ฐฝ๊ตฌ๋ฅผ ํ†ตํ•ด์„œ ๊ฐ„๋‹จํ•œ ๋ช…๋ น ์š”๊ตฌ๋งŒ ๋‚ด๋ฆฌ๋ฉด ์š”๊ตฌ์— ๋Œ€ํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ์ง‘์•ฝ์  ํ–‰์œ„๋“ค์„ ์ฐฝ๊ตฌ๊ฐ€ ์•Œ์•„์„œ ์ฒ˜๋ฆฌํ•ด ๊ฒฐ๊ณผ๋ฅผ ๋‚ด์ฃผ๊ฒŒ ๋œ๋‹ค.

Facade-Pattern
๊ณ ๊ฐ์€ ๋ณต์žกํ•œ ์ ˆ์ฐจ ์ง€์‹์—†์ด ๊ณ ๊ฐ์„ผํ„ฐ(์ฐฝ๊ตฌ)์— ์š”๊ตฌ๋งŒ ํ•˜๋ฉด ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š”๋‹ค

์ด์ฒ˜๋Ÿผ ํผ์‚ฌ๋“œ(Facade) ํŒจํ„ด์€ ๋ณต์žกํ•˜๊ฒŒ ์–ฝํ˜€ ์žˆ๋Š” ๊ฒƒ์„ ์ •๋ฆฌํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ณ ๊ฐ์—๊ฒŒ ์ œ๊ณตํ•œ๋‹ค๊ณ  ๋ณด๋ฉด๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๊ณ ๊ฐ์€ ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์„ ์•Œ ํ•„์š”์—†์ด ์‹œ์Šคํ…œ์˜ ์™ธ๋ถ€์— ๋Œ€ํ•ด์„œ ๋‹จ์ˆœํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ํผ์‚ฌ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ์ž์นซ ๋™์ž‘์˜ ๋ชฉ์ ๊ณผ ๊ฐ™์€ ์ค‘์š”ํ•œ ์‚ฌํ•ญ์„ ๋†“์น˜๋Š” ์‹ค์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

Facade๋ผ๋Š” ๋‹จ์–ด์˜ ๋œป์€ ๊ฑด์ถ•๋ฌผ์˜ ์ •๋ฉด์„ ์˜๋ฏธํ•œ๋‹ค. ๊ฑด์ถ•๋ฌผ์˜ ์ •๋ฉด์€ ๋ณดํ†ต ๊ฑด์ถ•๋ฌผ์˜ ์ด๋ฏธ์ง€์™€ ๊ฑด์ถ• ์˜๋„๋ฅผ ๋‚˜ํƒ€๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ž˜ ์ „๋ถ€ํ„ฐ ํŠน๋ณ„ํ•œ ๋””์ž์ธ์„ ์ ์šฉํ•˜์—ฌ ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ–ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ๊ฑด์ถ•๋ฌผ ์ •๋ฉด๋งŒ ๋ด๋„ ์ด ๊ฑด๋ฌผ์ด ์–ด๋–ค ๋ชฉ์ ์„ ํ•˜๋Š”์ง€ ๋‹จ๋ฒˆ์— ์•Œ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠน์ง•์„ ์ฐจ์šฉํ•˜์—ฌ ๋ช…๋ช… ์ง€์€ ๊ฒƒ์ด๋‹ค.
Facade-Pattern

ํผ์‚ฌ๋“œ ํŒจํ„ด ๊ตฌ์กฐ

Facade-Pattern

  • Facade : ์„œ๋ธŒ์‹œ์Šคํ…œ ๊ธฐ๋Šฅ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๋ณต์žกํ•œ ๋กœ์ง์„ ์žฌ์ •๋ฆฌํ•ด์„œ ๋†’์€ ๋ ˆ๋ฒจ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•œ๋‹ค. Facade ์—ญํ• ์€ ์„œ๋ธŒ ์‹œ์Šคํ…œ์˜ ๋งŽ์€ ์—ญํ• ์— ๋Œ€ํ•ด ‘๋‹จ์ˆœํ•œ ์ฐฝ๊ตฌ’๊ฐ€ ๋œ๋‹ค. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ธŒ์‹œ์Šคํ…œ์ด ์„œ๋กœ ๊ธด๋ฐ€ํ•˜๊ฒŒ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
  • Additional Facade : ํผ์‚ฌ๋“œ ํด๋ž˜์Šค๋Š” ๋ฐ˜๋“œ์‹œ ํ•œ๊ฐœ๋งŒ ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ทœ์น™๊ฐ™์€ ๊ฑด ์—†๋‹ค. ์—ฐ๊ด€ ๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค๋ฉด ์–ผ๋งˆ๋“ ์ง€ ํผ์‚ฌ๋“œ 2์„ธ๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค. ์ด ํผ์‚ฌ๋“œ 2์„ธ๋Š” ๋‹ค๋ฅธ ํผ์‚ฌ๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
  • SubSystem(ํ•˜์œ„ ์‹œ์Šคํ…œ) : ์ˆ˜์‹ญ ๊ฐ€์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜น์€ ํด๋ž˜์Šค๋“ค
  • Client : ์„œ๋ธŒ ์‹œ์Šคํ…œ์— ์ง์ ‘ ์ ‘๊ทผํ•˜๋Š” ๋Œ€์‹  Facade๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

ํผ์‚ฌ๋“œ ํŒจํ„ด์€ ์ „๋žต ํŒจํ„ด์ด๋‚˜ ํŒฉํ† ๋ฆฌ ํŒจํ„ด๊ณผ ๊ฐ™์€ ์—ฌํƒ€ ๋‹ค๋ฅธ ๋””์ž์ธ ํŒจํ„ด๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ํด๋ž˜์Šค ๊ตฌ์กฐ๊ฐ€ ์ •ํ˜•ํ™” ๋˜์ง€ ์•Š์€ ํŒจํ„ด์ด๋‹ค. ๋ฐ˜๋“œ์‹œ ํด๋ž˜์Šค ์œ„์น˜๋Š” ์–ด๋–ป๊ณ  ์–ด๋–ค ํ˜•์‹์œผ๋กœ ์œ„์ž„์„ ํ•ด์•ผ๋˜๊ณ  ์ด๋Ÿฐ๊ฒƒ์ด ์—†๋‹ค. ๊ทธ๋ƒฅ ํผ์‚ฌ๋“œ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์ ์ ˆํžˆ ๊ธฐ๋Šฅ ์ง‘์•ฝํ™”๋งŒ ํ•ด์ฃผ๋ฉด ๊ทธ๊ฒŒ ๋””์ž์ธ ํŒจํ„ด์ด ๋˜๋Š” ๊ฒƒ์ด๋‹ค. (ํŒจํ„ด์ด๋ผ๊ธฐ ๋ณด๋‹จ ๋…ผ๋ฆฌ์— ๊ฐ€๊น๋‹ค)

C์–ธ์–ด๋‚˜ ํŒŒ์ด์ฌ์—์„œ ์–ด๋– ํ•œ ๋ณต์žกํ•œ ๋กœ์ง์˜ ์ฝ”๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์ด๊ฑธ main ํ•จ์ˆ˜์—์„œ ๋ชจ๋‘ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•จ์ˆ˜(function) ๋ถ„๋ฆฌ๋ฅผ ํ†ตํ•ด main ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๋ฅผ ์‹ฌํ”Œํ•˜๊ฒŒ ๊ตฌ์„ฑํ•ด๋ณธ ๊ฒฝํ—˜์ด ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€์ ์œผ๋กœ ์น˜ํ™˜ํ•œ ๊ฒƒ์ด ํผ์‚ฌ๋“œ ํŒจํ„ด์ด๋‹ค. ์ฆ‰, ํผ์‚ฌ๋“œ๋Š” ๋ณต์žกํ•œ ๊ฒƒ(๋‚ด๋ถ€์—์„œ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” ๋งŽ์€ ํด๋ž˜์Šค์˜ ๊ด€๊ณ„๋‚˜ ์‚ฌ์šฉ๋ฒ•)์„ ๋‹จ์ˆœํ•˜๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์— ์ดˆ์ ์„ ๋‘”๋‹ค. ํด๋ผ์ด์–ธํŠธ๋กœ ํ•˜์—ฌ๊ธˆ ๋ณต์žกํ•œ ๊ฒƒ์„ ์˜์‹ํ•˜์ง€ ์•Š๋„๋ก ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. 

Facade-Pattern
Client๋“ค์€ ๋ณต์žกํ•œ Subsystem์„ ์˜์‹ํ•˜์ง€์•Š๊ณ  Facade๋ผ๋Š” ์ฐฝ๊ตฌ๋ฅผ ํ†ตํ•ด ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š”๋‹ค

 

์žฌ๊ท€์ ์ธ Facade ํŒจํ„ด์˜ ์ ์šฉ

์žฌ๊ท€์  ํผ์‚ฌ๋“œ๋ž€ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ Additional Facade ๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ๋‹ค์ˆ˜์˜ ํด๋ž˜์Šค, ๋‹ค์ˆ˜์˜ ํŒจํ‚ค์ง€๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ํฐ ์‹œ์Šคํ…œ์— ์š”์†Œ ์š”์†Œ ๋งˆ๋‹ค Facade ํŒจํ„ด์„ ์—ฌ๊ธฐ ์ €๊ธฐ ์ ์šฉํ•˜๊ณ  ๋‹ค์‹œ ๊ทธ Facade๋ฅผ ํ•ฉ์นœ Facade๋ฅผ ๋งŒ๋“œ๋Š” ์‹์œผ๋กœ, ํผ์‚ฌ๋“œ๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ๊ตฌ์„ฑํ•˜๋ฉด ์‹œ์Šคํ…œ์€ ๋ณด๋‹ค ํŽธ๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค. ์ด์ฒ˜๋Ÿผ ํผ์‚ฌ๋“œ๋Š” ํ•œ๊ฐœ๋งŒ ์žˆ์œผ๋ผ๋Š” ๋ฒ•์€ ์—†์œผ๋ฉฐ ํ•„์š”์— ์˜ํ•˜๋ฉด ์–ผ๋งˆ๋“ ์ง€ ๋Š˜๋ ค ์˜์กดํ•  ์ˆ˜ ์žˆ๋‹ค.

Facade-Pattern


ํผ์‚ฌ๋“œ ํŒจํ„ด ํŠน์ง•

 

ํŒจํ„ด ์‚ฌ์šฉ ์‹œ๊ธฐ

  • ์‹œ์Šคํ…œ์ด ๋„ˆ๋ฌด ๋ณต์žกํ• ๋•Œ
  • ๊ทธ๋ž˜์„œ ๊ฐ„๋‹จํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์„ ์ ‘๊ทผํ•˜๋„๋ก ํ•˜๊ณ  ์‹ถ์„๋•Œ
  • ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์™ธ๋ถ€์™€ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋„ˆ๋ฌด ๋†’์„ ๋•Œ ์˜์กด์„ฑ ๋‚ฎ์ถ”๊ธฐ ์œ„ํ• ๋•Œ

 

ํŒจํ„ด ์žฅ์ 

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

 

ํŒจํ„ด ๋‹จ์ 

  • ํผ์‚ฌ๋“œ๊ฐ€ ์•ฑ์˜ ๋ชจ๋“  ํด๋ž˜์Šค์— ๊ฒฐํ•ฉ๋œ God ๊ฐ์ฒด๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค
  • ํผ์‚ฌ๋“œ ํด๋ž˜์Šค ์ž์ฒด๊ฐ€ ์„œ๋ธŒ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ๊ฐ€์ง€๊ฒŒ ๋˜์–ด ์˜์กด์„ฑ์„ ์™„์ „ํžˆ๋Š” ํ”ผํ•  ์ˆ˜๋Š” ์—†๋‹ค.
  • ์–ด์ฐŒ๋˜์—ˆ๊ฑด ์ถ”๊ฐ€์ ์ธ ์ฝ”๋“œ๊ฐ€ ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ ๊ณต์ˆ˜๊ฐ€ ๋” ๋งŽ์ด ๋“ค๊ฒŒ ๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ถ”์ƒํ™” ํ•˜๊ณ ์žํ•˜๋Š” ์‹œ์Šคํ…œ์ด ์–ผ๋งˆ๋‚˜ ๋ณต์žกํ•œ์ง€ ํผ์‚ฌ๋“œ ํŒจํ„ด์„ ํ†ตํ•ด์„œ ์–ป๊ฒŒ ๋˜๋Š” ์ด์ ๊ณผ ์ถ”๊ฐ€์ ์ธ ์œ ์ง€๋ณด์ˆ˜ ๋น„์šฉ์„ ๋น„๊ตํ•ด๋ณด๋ฉฐ ๊ฒฐ์ •ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์•Œ์•„๋ณด๋Š” Facade ํŒจํ„ด

 

๋ณต์žกํ•œ DBMS ์‹œ์Šคํ…œ ๊ฐ„ํŽธํ•˜๊ฒŒ ์žฌ๊ตฌ์„ฑ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด์„œ ์ถœ๋ ฅํ•ด์ฃผ๋Š” JDBC ๋น„์Šค๋ฌด๋ฆฌํ•œ ์ž๋ฐ” ํŒจํ‚ค์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž. ์šฐ๋ฆฌ๋Š” ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ์–ป์–ด์˜ค๊ณ  ํ™”๋ฉด์— ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์‹ฑํ•ด์„œ ์˜ˆ์˜๊ฒŒ ์ถœ๋ ฅํ•˜๋ ค๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค๋ ค๊ณ  ํ•œ๋‹ค.

ํŒจํ‚ค์ง€์—๋Š” ์ด 4๊ฐœ์˜ Cache, DBMS, Row, Message ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜ ๊ทธ๋ฆผ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ๊ฐ ํ–‰์œ„์— ๋Œ€ํ•ด ๊ฐ ํด๋ž˜์Šค๋“ค์˜ ์—ญํ• ์ด ์ •ํ•ด์ ธ ์žˆ๋‹ค.

Facade-Pattern
๊ฐ ํด๋ž˜์Šค๋“ค์˜ ์—ญํ•  (์ ์„ )

๊ทธ๋Ÿฐ๋ฐ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•˜๋Š”๋ฐ ์žˆ์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์กฐํšŒํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ธฐ ๊นŒ์ง€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทœ์น™์ด ์กด์žฌํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

  1. dbms๋ฅผ ๋ฐ”๋กœ ์กฐํšŒํ•˜๊ธฐ์ „์—
  2. ๊ณผ๊ฑฐ์— ์กฐํšŒ๋œ ๋ฐ์ดํ„ฐ์ธ์ง€๋ฅผ ์บ์‹œ์—์„œ ๋จผ์ € ์กฐ์‚ฌ๋ฅผ ํ•˜๊ณ 
  3. ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด ์ด ์บ์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ณ  ์ถœ๋ ฅ
  4. ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋ฉด DBMS๋ฅผ ํ†ตํ•ด์„œ ์กฐํšŒ๋ฅผ ํ•˜๊ณ 
  5. ์กฐํšŒ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ณ  ์ถœ๋ ฅํ•จ๊ณผ ๋™์‹œ์— ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.

DBMS์— ์กฐํšŒ๋œ ๋ฐ์ดํ„ฐ๋Š” ์„ฑ๋Šฅ์„ ์œ„ํ•ด ๋ฐ˜๋“œ์‹œ ์บ์‹œ์— ์ €์žฅํ•ด์•ผ ๋˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋ง์•„์•ผํ•˜๊ณ , ๋˜ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Message ํด๋ž˜์Šค๋ฅผ ์จ์•ผ ํ•œ๋‹ค. ์ด ์ˆ˜์น™์„ ๋”ฐ๋ฅด์ง€ ์•Š์œผ๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•„ ๊ฐœ๋ฐœ์ž๋Š” ์œ„์˜ ์‚ฌํ•ญ์„ ์ œ๋Œ€๋กœ ์ˆ™์ง€ํ•œ ์ƒํƒœ์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

์šฐ์„  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฐ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์€์œ ์ ์ธ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค๊ณ  ํ•œ๋‹ค.

// DBMS์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค
class Row  {
    private String name;
    private String birthday;
    private String email;

    public Row(String name, String birthday, String email) {
        this.name = name;
        this.birthday = birthday;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public String getBirthday() {
        return birthday;
    }

    public String getEmail() {
        return email;
    }
}

// ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ญํ• ์„ ํ•˜๋Š” ํด๋ž˜์Šค
class DBMS {
    private HashMap<String, Row> db = new HashMap<>();

    public void put(String name, Row row) {
        db.put(name, row);
    }

    // ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ ค ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋ฉ”์†Œ๋“œ
    public Row query(String name) {
        try {
            Thread.sleep(500); // DB ์กฐํšŒ ์‹œ๊ฐ„์„ ๋น„์œ ํ•˜์—ฌ 0.5์ดˆ๋Œ€๊ธฐ๋กœ ๊ตฌํ˜„
        } catch(InterruptedException e) {}

        return db.get(name.toLowerCase());
    }
}

// DBMS์—์„œ ์กฐํšŒ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž„์‹œ๋กœ ๋‹ด์•„๋‘๋Š” ํด๋ž˜์Šค (์†๋„ ํ–ฅ์ƒ)
class Cache {
    private HashMap<String, Row> cache = new HashMap<>();

    public void put(Row row) {
        cache.put(row.getName(), row);
    }

    public Row get(String name) {
        return cache.get(name);
    }
}

// Row ํด๋ž˜์Šค๋ฅผ ๋ณด๊ธฐ์ข‹๊ฒŒ ์ถœ๋ ฅํ•˜๋Š” ํด๋ž˜์Šค
class Message {
    private Row row;

    public Message(Row row) {
        this.row = row;
    }

    public String makeName() {
        return "Name : \"" + row.getName() + "\"";
    }

    public String makeBirthday() {
        return "Birthday : " + row.getBirthday();
    }

    public String makeEmail() {
        return "Email : " + row.getEmail();
    }
}

 

ํด๋ฆฐํ•˜์ง€ ์•Š์€ ๋ฌธ์ œ์˜ ์ฝ”๋“œ โŒ

๋ฌธ์ œ์˜ ์ฝ”๋“œ๋Š” ๋‹น์—ฐํžˆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฉ”์ธ ๋กœ์ง์— ์ž‘์„ฑํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ์ถœ๋ ฅ๋˜๊ธฐ ๊นŒ์ง€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ์ฒด๊ฐ€ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.

๋ฌผ๋ก  ๋‹น์žฅ์€ ํ”„๋กœ๊ทธ๋žจ์ด ์ •์ƒ์ ์œผ๋กœ ๋Œ์•„๊ฐ€ ์„œ๋น„์Šค์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์„์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ, ๋‚˜์ค‘์— ์ˆ˜์ •๊ณผ ํ™•์žฅํ•จ์— ์žˆ์–ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์œ„์˜ ์ˆ˜์น™๋“ค์„ ๊นŒ๋จน๊ณ  ์‹ค์ˆ˜๋ฅผ ํ•˜์—ฌ ์„œ๋น„์Šค์— ๋ฒ„๊ทธ๊ฐ€ ์ƒ๊ธธ์ˆ˜ ์žˆ๋‹ค.

class Client {
    public static void main(String[] args) {
        // 1. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒ์„ฑ & ๋“ฑ๋ก
        DBMS dbms = new DBMS();
        dbms.put("ํ™๊ธธ๋™", new Row("ํ™๊ธธ๋™", "1890-02-14", "honggildong@naver.com"));
        dbms.put("์ž„๊บฝ์ •", new Row("์ž„๊บฝ์ •", "1820-11-02", "imgguckjong@naver.com"));
        dbms.put("์ฃผ๋ชฝ", new Row("์ฃผ๋ชฝ", "710-08-27", "jumong@naver.com"));

        // 2. ์บ์‹œ ์ƒ์„ฑ
        Cache cache = new Cache();

        // 3. ํŠธ๋žœ์žญ์…˜์— ์•ž์„œ ๋จผ์ € ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ์กฐํšŒ
        String name = "ํ™๊ธธ๋™";
        Row row = cache.get(name);

        // 4. ๋งŒ์•ฝ ์บ์‹œ์— ์—†๋‹ค๋ฉด
        if (row == null){
            row = dbms.query(name); // DB์— ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด์„œ row์— ์ €์žฅํ•˜๊ณ 
            if(row != null) {
                cache.put(row); // ์บ์‹œ์— ์ €์žฅ
            }
        }

        // 5. dbms.query(name)์—์„œ ์กฐํšŒ๋œ ๊ฐ’์ด ์žˆ์œผ๋ฉด
        if(row != null) {
            Message message = new Message(row);

            System.out.println(message.makeName());
            System.out.println(message.makeBirthday());
            System.out.println(message.makeEmail());
        }
        // 6. ์กฐํšŒ๋œ ๊ฐ’์ด ์—†์œผ๋ฉด
        else {
            System.out.println(name + " ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
        }
    }
}

Facade-Pattern

 

ํผ์‚ฌ๋“œ ํŒจํ„ด์„ ์ ์šฉํ•œ ์ฝ”๋“œ โœ”๏ธ

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

Facade-Pattern

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํผ์‚ฌ๋“œ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด ์ฃผ๊ณ  ๋ฉ”์ธ ๋ฉ”์†Œ๋“œ์˜ ๋กœ์ง์„ ํผ์‚ฌ๋“œ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์— ํ†ต์งœ๋กœ ๋„ฃ๋Š”๋‹ค. (๋ถ„๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋ฉด ๋ฉ”์„œ๋“œ๋ฅผ ๋” ๋Š˜๋ฆฐ๋‹ค)

class Facade {
    private DBMS dbms = new DBMS();
    private Cache cache = new Cache();

    public void insert() {
        dbms.put("ํ™๊ธธ๋™", new Row("ํ™๊ธธ๋™", "1890-02-14", "honggildong@naver.com"));
        dbms.put("์ž„๊บฝ์ •", new Row("์ž„๊บฝ์ •", "1820-11-02", "imgguckjong@naver.com"));
        dbms.put("์ฃผ๋ชฝ", new Row("์ฃผ๋ชฝ", "710-08-27", "jumong@naver.com"));
    }

    public void run(String name) {
        Row row = cache.get(name);

        // 1. ๋งŒ์•ฝ ์บ์‹œ์— ์—†๋‹ค๋ฉด
        if (row == null){
            row = dbms.query(name); // DB์— ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด์„œ row์— ์ €์žฅํ•˜๊ณ 
            if(row != null) {
                cache.put(row); // ์บ์‹œ์— ์ €์žฅ
            }
        }

        // 2. dbms.query(name)์—์„œ ์กฐํšŒ๋œ ๊ฐ’์ด ์žˆ์œผ๋ฉด
        if(row != null) {
            Message message = new Message(row);

            System.out.println(message.makeName());
            System.out.println(message.makeBirthday());
            System.out.println(message.makeEmail());
        }
        // 3. ์กฐํšŒ๋œ ๊ฐ’์ด ์—†์œผ๋ฉด
        else {
            System.out.println(name + " ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
        }
    }
}
class Client {
    public static void main(String[] args) {

        // 1. ํผ์‚ฌ๋“œ ๊ฐ์ฒด ์ƒ์„ฑ
        Facade facade = new Facade();

        // 2. db ๊ฐ’ insert
        facade.insert();

        // 3. ํผ์‚ฌ๋“œ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค & ์บ์‹ฑ & ๋ฉ”์„ธ์ง• ๋กœ์ง์„ ํ•œ๋ฒˆ์— ์กฐํšŒ
        String name = "ํ™๊ธธ๋™";
        facade.run(name);
    }
}

ํผ์‚ฌ๋“œ ํŒจํ„ด์„ ์ ์šฉํ•˜๋‹ˆ ๋ฉ”์ธ ๋กœ์ง์ด ์—„์ฒญ ์‹ฌํ”Œํ•ด์กŒ๋‹ค. ์ด์ฒ˜๋Ÿผ ํผ์‚ฌ๋“œ์˜ ํ•ต์‹ฌ์€ ์ธํ„ฐํŽ˜์ด์Šค(API)๋ฅผ ์ ๊ฒŒ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค๋‚˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋งŽ์ด ๋ณด์ด๋ฉด, ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๋ฌด์—‡์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„์ง€ ๋ง์„ค์ด๊ฒŒ ๋˜๊ณ  ํ˜ธ์ถœํ•˜๋Š” ์ˆœ์„œ๋„ doc์„ ์‚ดํŽด๋ณด๋ฉฐ ์ฃผ์˜ํ•ด์•ผ๋งŒ ํ•œ๋‹ค. ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋ง์€ ๋‹ค๋ฅด๊ฒŒ ๋งํ•˜๋ฉด ํ‹€๋ฆฌ๊ธฐ ์‰ฝ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ํผ์‚ฌ๋“œ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€๋Šฅํ•œ ์ ๊ฒŒ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

์˜คํ•ดํ•˜์ง€ ๋ง์•„์•ผ ํ•  ์ ์€ ํผ์‚ฌ๋“œ๋Š” ํ•˜์œ„ ์‹œ์Šคํ…œ ํด๋ž˜์Šค๋“ค์„ ์บก์Šํ™” ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ ์„œ๋ธŒ ์‹œ์Šคํ…œ๋“ค์„ ์‚ฌ์šฉํ•  ๊ฐ„๋‹จํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•  ๋ฟ ์ด๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์„œ๋ธŒ ์‹œ์Šคํ…œ ๋‚ด๋ถ€์˜ ํด๋ž˜์Šค๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ œํ•œํ•  ์ˆ˜๋Š” ์—†๋‹ค. ๊ทธ๋ž˜์„œ ์˜คํžˆ๋ ค ์ถ”์ƒํ™”์— ๊ฐ€๊น๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํผ์‚ฌ๋“œ ๊ฐ์ฒด๋Š” ํ•˜๋‚˜๋งŒ ์žˆ์–ด๋„ ์ถฉ๋ถ„ํ•˜๋ฏ€๋กœ, ํผ์‚ฌ๋“œ ํด๋ž˜์Šค๋ฅผ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ตฌ์„ฑํ•ด์ฃผ๋ฉด ์ข‹๋‹ค.

# ์ฐธ๊ณ ์ž๋ฃŒ

์ฝ”๋”ฉ์œผ๋กœ ํ•™์Šตํ•˜๋Š” GoF์˜ ๋””์ž์ธ ํŒจํ„ด - ๋ฐฑ๊ธฐ์„ 

https://youtu.be/mQlOqyFE3oI

https://refactoring.guru/design-patterns/facade

http://best-practice-software-engineering.ifs.tuwien.ac.at/patterns/facade.html