๐Ÿ’ป Programming (358)

AJAX๊ฐ€ ๋ญ˜๊นŒ์š”? 


AJAX๋Š” Asynchronous Javascript And Xml์˜ ์•ฝ์ž์ž…๋‹ˆ๋‹ค.


์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ๋น„๋™๊ธฐ์‹ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ XML์„ ๋งํ•ฉ๋‹ˆ๋‹ค. 


์ด๋ฆ„์— XML์ด ๋‚˜์˜ค๊ธฐ๋Š” ํ•˜์ง€๋งŒ XML์„ ์•Œ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.  


AJAX๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ HTML๊ณผ Javascript๋ฅผ ์•Œ๊ณ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


๊ทธ๋Ÿผ ๊ฐ€์žฅ๋จผ์ € AJAX๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ• ๊นŒ์š”?


AJAX๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ˆœ์„œ๋ฅผ ๊ฑฐ์นฉ๋‹ˆ๋‹ค.


1. ํด๋ผ์ด์–ธํŠธ(IE 7+, ํฌ๋กฌ, ์‚ฌํŒŒ๋ฆฌ, ํŒŒ์ด์–ดํญ์Šค, etc. )์—์„œ XMLHttpRequest๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ด์•„ ์„œ๋ฒ„๋กœ ๋ณด๋‚ธ๋‹ค.

2. ์„œ๋ฒ„์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์œผ๋ฉด ๋ฉ”์‹œ์ง€์— ํ•ด๋‹นํ•˜๋Š” ์ •๋ณด๋ฅผ ์ฝ์–ด์„œ ๋‹ค์‹œ ๋ธŒ๋ผ์šฐ์ €ํ•œํ…Œ ์‘๋‹ตํ•ด์ค€๋‹ค.

3. ํด๋ผ์ด์–ธํŠธ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์„ ๋ฐ›์œผ๋ฉด ํ•ด๋‹น ์ •๋ณด๋ฅผ ํŠน์ • ์˜์—ญ์— refreshํ•ด์ค€๋‹ค.


AJAX๋ฅผ ์‚ฌ์šฉํ•จ์— ์žˆ์–ด์„œ ๊ฐ€์žฅ ๊ธฐ๋ณธ์€ XMLHttpRequest ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก๋ฐ›์„ ๋•Œ ์‚ฌ์šฉ์ด ๋ฉ๋‹ˆ๋‹ค. ( IE 5, 6 ๋ฒ„์ „์—์„œ๋Š” ActiveXObject ๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. )


๊ทธ๋Ÿผ ์ด ๊ฐ์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋Š”์ง€ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด์„œ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ1 - XMLHttpRequest ๊ฐ์ฒด ์ƒ์„ฑํ•˜๊ธฐ

var xhttp;
if (window.XMLHttpRequest) {
    xhttp = new XMLHttpRequest();
    } else {
    // code for IE6, IE5
    xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
์—ฐ์Šตํ•˜๊ธฐ ยป


์ž, ์ด์ œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ–ˆ์œผ๋‹ˆ๊นŒ ์ด ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•ด์•ผ๊ฒ ์ฃ ?


๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ์„œ๋ฒ„๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.



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


์ด ์—๋Ÿฌ๋Š” ์„œ๋ธ”๋ฆฟ ํด๋ž˜์Šค๊ฐ€ ํด๋ž˜์Šค ๋นŒ๋“œํŒจ์Šค์— ์žกํ˜€์žˆ์ง€ ์•Š์•„์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.


์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด๊ฒฐํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.


Project Properties-> Java Build Path-> Add Library -> Select "Server Runtime" from the list-> Next->Select "Apache Tomcat"-> Finish

๐Ÿ’ป Programming/CSS

[CSS] 1. CSS๋ž€ ?

์•ˆ๋…•ํ•˜์„ธ์š”~ ์ด๋ฒˆ์—๋Š” CSS์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผํ…๋ฐ์š”~

 

CSS๊ฐ€ ๋ญ”์ง€๋ฅผ ์•Œ๋ ค๋ฉด ๋ญ์˜ ์•ฝ์ž์ธ์ง€๋ถ€ํ„ฐ ์•Œ์•„๋ด์•ผ ๊ฒ ์ฃ ?

 

CSS๋Š” Cascading Style Sheets์˜ ์•ฝ์ž์ž…๋‹ˆ๋‹ค. ์บ์Šค์ผ€์ด๋”ฉ ์Šคํƒ€์ผ ์‹œํŠธ. ์Šคํƒ€์ผ์ด๋ผ๋Š” ๋‹จ์–ด๋ผ ๋“ค์–ด๊ฐ”์œผ๋‹ˆ ๋ญ”๊ฐ€ ์Šคํƒ€์ผ๋งํ•˜๊ธฐ์œ„ํ•œ ์–ด๋–ค๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ์œผ๋ ค๋‚˜์š”?  

 

CSS๋Š” htmlํƒœ๊ทธ๋‚ด์˜ ์†์„ฑ๊ฐ’๋“ค์„ ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•ด์„œ ์ €์žฅํ•ด๋†“๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ์ด ๋ฉ๋‹ˆ๋‹ค.

 

์™œ ๋”ฐ๋กœ ์ €์žฅํ•ด๋†“์„๊นŒ์š”??

 

์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์—์„œ ์ ์šฉ์ด ๋˜์•ผํ•˜๋Š” ์Šคํƒ€์ผ๊ฐ’๋“ค์„ ๋ถ„๋ฆฌํ•ด์„œ ์ €์žฅํ•ด๋†“๊ณ  ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์—์„œ ๊ทธ๋ƒฅ ํ˜ธ์ถœํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์•„์ง€๊ณ  ๋˜‘๊ฐ™์€ ์†์„ฑ์„ ํƒ€์ดํ•‘ํ•ด์•ผํ•˜๋Š” ์ˆ˜๊ณ ๋„ ๋œ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‹œ๊ฐ„๋„ ๋‹จ์ถ•๋  ๊ฒƒ์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜๋„ ์‰ฌ์›Œ์ง€๊ฒ ์ฃ ?

 

๊ทธ๋ž˜์„œ ์ ์  html๋‚ด์˜ ์†์„ฑ๋“ค์ด ์‚ฌ๋ผ์ง€๊ณ  ๋Œ€์‹  CSS๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ํ‘œ์ค€์ด ๋ ๊ฑฐ๋ผ๋Š” ๋ง๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

(2020๋…„ ํ˜„์žฌ ์ด๋ฏธ ๊ทธ๋ ‡๊ฒŒ ๋˜์–ด๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค. html ๋‚ด์— inline style์„ ์ •์˜ํ•ด์„œ ์“ฐ๋Š” ์ผ์€ ๊ฑฐ์˜ ์—†์ฃ )

 

 

๊ทธ๋Ÿฌ๋ฉด ๊ธฐ๋ณธ์ ์ธ ๋ฌธ๋ฒ•์„ ์—ฌ๊ธฐ์„œ ํ•œ๋ฒˆ ์งš๊ณ  ๋„˜์–ด๊ฐ€๋ณผ๊นŒ์š”??

 

์—์ด ๊ทธ๋ƒฅ ๋‹ค์Œ์— ์•Œ์•„๋ณด๊ธฐ๋กœ ํ•˜์ฃ  ใ…‹ใ…‹

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


๋”ฐ๋ผ์„œ insert into table1 values ( 'a & b'); ๋ผ๋Š” ๋ฌธ์žฅ์„ ์‹คํ–‰ํ•˜๋ฉด SQLDeveloper์—์„œ๋Š” ๋Œ€์ฒด๋ฌธ์ž๋ฅผ ์„ค์ •ํ•˜๋ผ๊ณ  ํŒ์—…์ฐฝ์ด ๋œฌ๋‹ค.


์ฒ˜์Œ์—๋Š” ์ด๊ฒŒ ๋ญ์ง€? ํ•˜๊ณ ์„œ ๊ทธ๋ƒฅ ์—”ํ„ฐ๋ฅผ ์ณค์—ˆ๋Š”๋ฐ ๋‚˜์ค‘์— ๋ณด๋‹ˆ ๊ทธ๋ ‡๊ฒŒ ์—”ํ„ฐ์ณค๋˜ ๊ฒƒ ๋•Œ๋ฌธ์— insertํ•  ๋•Œ &๊ฐ€ ๊ณต๋ฐฑ์œผ๋กœ ๋ฐ”๋€Œ์–ด์ ธ์„œ ๋‚ด์šฉ์ด ๋“ค์–ด๊ฐ€์žˆ์—ˆ๋‹ค.


๊ทธ๋Ÿฐ๋ฐ ์ด๋ ‡๊ฒŒ ํŠน์ˆ˜๊ธฐํ˜ธ๊ฐ€ ๋“ค์–ด๊ฐ„ ๋ฌธ์žฅ์„ ์ˆ˜ ๋ฐฑ๊ฐœ insertํ•ด์•ผ ํ•œ๋‹ค๋ฉด....???


์ผ์ผํžˆ ๋‹ค ๋Œ€์ฒด๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜๊ฐ€ ์—†๋‹ค!!!


์ด๋Ÿด ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋Š”๊ฒŒ


SQL> set define off;


์ด๋‹ค.


์œ„ ๋ช…๋ น์–ด๋Š” ํ˜„์žฌ ์„ธ์…˜์— ๋Œ€ํ•ด์„œ "ํŠน์ˆ˜๊ธฐํ˜ธ ๋Œ€์ฒด ๊ฒ€์‚ฌ"๋ฅผ ํ•˜์ง€ ์•Š๋„๋ก ํ•ด์ค€๋‹ค. 

How to increase the number of processes at database level in Oracle?

 


1.  Log on to the database as system administrator

  •  In SQL Plus enter: "connect / as sysdba"

2. Set the number of processes to be desired value <num_processes>

  • In SQL Plus "alter system set processes=<num_processes> scope=spfile"

3. Shutdown the database

  • In SQL Plus "shutdown immediate"


4. Startup the database 

  • In SQL Plus "startup"


5. Check the changes have taken effect.

  • In SQL Plus "show parameter sessions" and "show parameter processes"






โ€‹์ถœ์ฒ˜ : http://knowledgebase.progress.com/articles/Article/P164971

 

CentOS 6์— ์˜ค๋ผํด 11g ์„ค์น˜์‹œ์— ์„ค์ •ํ•ด์ฃผ๋Š” ์ปค๋„ ํŒŒ๋ผ๋ฏธํ„ฐ ์˜๋ฏธ


ใ…‡ ์ปค๋„ ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค์ •

/etc/sysctl.conf ํŒŒ์ผ

fs.aio-max-nr = 1048576
fs.file-max = 6815744
#kernel.shmall = 2097152
#kernel.shmmax = 536870912
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576

์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ์กฐํ•˜์‹œ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.


https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/5/html-single/Tuning_and_Optimizing_Red_Hat_Enterprise_Linux_for_Oracle_9i_and_10g_Databases/#sect-Oracle_9i_and_10g_Tuning_Guide-Setting_Semaphores-Setting_Semaphore_Parameters


https://docs.oracle.com/cd/E11882_01/install.112/e24326/toc.htm#BHCCADGD



select 

owner, segment_name, segment_type, sum(bytes)/1024/1024 as MB

from 

dba_segments

where

owner='{username in uppercase}' 

group by owner, segment_name, segment_type order by MB

MS-DOS 6 ์ปค๋งจ๋“œ ๋ผ์ธ

์š”์ƒˆ๋Š” ๊ฑฐ์˜ ์“ฐ์ด์ง€ ์•Š๊ณ ์žˆ๋Š” Dos ๋ช…๋ น์–ด๋ฅผ ์“ธ ์ผ์ด ์žˆ์–ด์„œ ๊ตฌ๊ธ€๋งํ•ด์„œ ์ผ๋Š”๋ฐ ๊ธฐ๋ก์œผ๋กœ ๋‚จ๊ฒจ๋ด…๋‹ˆ๋‹ค.

 

์•„๋ž˜ ๋ช…๋ น์–ด๋Š”

  1. dir๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•ด์„œ C: ๋“œ๋ผ์ด๋ธŒ ํ•˜์œ„์— ์žˆ๋Š” ๋””๋ ‰ํ† ๋ฆฌ ๋ชฉ๋ก์„ ๋ฝ‘์€ ๋’ค

  2. findstr์„ ์ด์šฉํ•ด์„œ \bin\ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ชฉ๋ก๋งŒ ์ถ”์ถœํ•œ ๋’ค์—

  3. .svn ์œผ๋กœ ๋””๋ ‰ํ† ๋ฆฌ๋ช…์ด ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ๋“ค์€ ์ œ์™ธ์‹œํ‚ค๊ณ 

  4. ๊ทธ๋ ‡๊ฒŒ ๋ฝ‘์€ ๋ช…๋ น์–ด๋ฅผ auxclasspath.txtํŒŒ์ผ๋กœ ์ €์žฅ

์„ ํ•˜๋Š” ๋ช…๋ น์–ด์ž…๋‹ˆ๋‹ค. 

 

์กฐ๊ธˆ๋งŒ ๋ฐ”๊พธ๋ฉด ์—ฌ๋Ÿฌ๋ถ„๋“ค์ด ์›ํ•˜๋Š” ํŒŒ์ผ๋งŒ ์ถ”์ถœ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

C:\> dir /a:d /s/b | findstr "\\bin\\" | findstr /v /i "\.svn" > auxclasspath.txt

 

ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณผ๊นŒ์š”?

 

1) dir /a:d /s/b

- ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ ํ•˜์œ„์˜ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

 

2) findstr "\\bin\\"

- ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ ์ค‘์— bin ์ด๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ํฌํ•จํ•˜๊ณ ์žˆ๋Š” ๊ฒฝ๋กœ๋งŒ ๋ฝ‘์•„๋ƒ…๋‹ˆ๋‹ค.

( ์ด ๋ช…๋ น์–ด๊ฐ€ ์‹ค์ œ๋กœ ํ•˜๋Š” ์ผ์€ ํŠน์ • ์ŠคํŠธ๋ง์„ ์ฐพ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. )

 

3) findstr /v /i "\.svn"  

- ์œ„ ๋””๋ ‰ํ† ๋ฆฌ ์ค‘ .svn ์œผ๋กœ ๋””๋ ‰ํ† ๋ฆฌ๋ช…์ด ์‹œ์ž‘ํ•˜๋Š” ๋ชฉ๋ก์€ ์ œ์™ธ์‹œํ‚ค๊ณ  ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

 

4) > auxclasspath.txt

- ์ง€๊ธˆ๊นŒ์ง€ ๋‚˜์˜จ ๋ชฉ๋ก์„ auxclasspath.txt ํŒŒ์ผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

 

 

 

dir ๋ช…๋ น์–ด ๋ฌธ๋ฒ• ๋ฐ ์˜ต์…˜ ๋ณด๊ธฐ

 

findStr ๋ช…๋ น์–ด ๋ฌธ๋ฒ• ๋ฐ ์˜ต์…˜ ๋ณด๊ธฐ

 

Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Memento ํŒจํ„ด์€ Behavioral ํŒจํ„ด์— ์†ํ•ฉ๋‹ˆ๋‹ค. 

 

Memento Pattern Structure

 




  

ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) :  

Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

    ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ทธ๋ฆฌ๋Š” ํˆด์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‚ฌ๊ฐํ˜• ๋‘๊ฐœ๋ฅผ ๊ทธ๋ฆฌ๊ณ  ๋‘ ์‚ฌ๊ฐํ˜•์„ ์„ ์œผ๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ž ์ด์ œ ์•„๋ž˜์ชฝ ์‚ฌ๊ฐํ˜•์„ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋‘ ์‚ฌ๊ฐํ˜•์„ ์ด์€ ์„ ๋„ ๋”ฐ๋ผ์„œ ์ด๋™ํ•˜๋ฉด์„œ ๋‘ ์‚ฌ๊ฐํ˜•์„ ๊ณ„์† ์ด์–ด์ค๋‹ˆ๋‹ค.  


์ด๋ ‡๊ฒŒ ๋‘ ๊ฐ์ฒด ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ ๊ด€๊ณ„๋ฅผ ์œ ์ง€์‹œํ‚ค๋Š” ์ž˜ ์•Œ๋ ค์ง„ ๋ฐฉ๋ฒ•์ค‘ ํ•˜๋‚˜๋Š” ์ œ์•ฝ-ํ•ด๊ฒฐ ์‹œ์Šคํ…œ(constraint-solving system)์ž…๋‹ˆ๋‹ค. ์ด ์‹œ์Šคํ…œ์€ ConstraintSolver ์— ์บก์Šํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ConstraintSolver๋Š” ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ์„ ๊ธฐ๋กํ•˜๊ณ  ์ด ์—ฐ๊ฒฐ์„ ์„ค๋ช…ํ•˜๋Š” ์ˆ˜ํ•™์‹์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ์ฒด์˜ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ์ด ๋˜๋ฉด ์ด ์ˆ˜ํ•™์‹์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์—ฌ ์„ ์„ ์–ด๋–ป๊ฒŒ ๊ทธ๋ ค์•ผ ํ•˜๋Š”์ง€๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

ํ•˜ ์ง€๋งŒ ๋˜๋Œ๋ฆฌ๊ธฐ ๊ธฐ๋Šฅ์€ ์ƒ๊ฐ์ฒ˜๋Ÿผ ์‰ฝ์ง€๊ฐ€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์‚ฌ๊ฐํ˜•์ด ์›€์ง์ธ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ๊ทธ๋งŒํผ ๋‹ค์‹œ ๋˜๋Œ๋ฆฐ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ ๊ณผ์—ฐ ๋‘ ์‚ฌ๊ฐํ˜•์„ ์—ฐ๊ฒฐํ•˜๋Š” ์„ ์€ ์–ด๋–ป๊ฒŒ ์›€์ง์—ฌ์•ผ ํ•˜๋Š”๊ฐ€๋ฅผ ์ƒ๊ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋ถˆ์™„์ „ํ•œ ๋˜๋Œ๋ฆฌ๊ธฐ๊ฐ€ ๋˜์–ด๋ฒ„๋ฆด ํ…Œ๋‹ˆ๊นŒ์š”.

 

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

 

The following sequence of events characterizes theundo process:

      1. The editor requests a memento from the ConstraintSolver as aside-effect of the move operation.

      2. The ConstraintSolver creates and returns a memento, an instance of a class SolverState in this case. A SolverState memento contains data structures that describe the current state of the ConstraintSolver's internal equations and variables.

      3. Later when the user undoes the move operation, the editor gives the SolverState back to the ConstraintSolver.

      4. Based on the information in the SolverState, the ConstraintSolver changes its internal structures to return its equations and variables to their exact previous state.

This arrangement lets the ConstraintSolver entrust other objects with the information it needs to revert to a previous state without exposing its internal structure and representations.



์œ ์šฉ์„ฑ ( Applicability ) :

 

Use the Memento pattern when

    • a snapshot of (some portion of) an object's state must be saved so that it can be restored to that state later, and

    • a direct interface to obtaining the state would expose implementation details and break the object's encapsulation.



๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :


โ€ข Memento (SolverState)

o stores internal state of the Originator object. The memento may store as much or as little of the originator's internal state as necessary at its originator's discretion.
o protects against access by objects other than the originator. Mementos have effectively two interfaces. Caretaker sees a narrow interface to the Mementoโ€”it can only pass the memento to other objects. Originator, in contrast, sees a wide interface, one that lets it access all the data necessary to restore itself to its previous state. Ideally, only the originator that produced the memento would be permitted to access the memento's internal state.

โ€ข Originator (ConstraintSolver)

o creates a memento containing a snapshot of its current internal state.
o uses the memento to restore its internal state.

โ€ข Caretaker (undo mechanism)

o is responsible for the memento's safekeeping.
o never operates on or examines the contents of a memento.

 

 

์›๋ฆฌ ( Collaborations ) :  

โ€ข A caretaker requests a memento from an originator, holds it for a time, and passes it back to the originator, as the following interaction diagram illustrates:   



 

 

Sometimes the caretaker won't pass the memento back to the originator, because the originator might never need to revert to an earlier state.

โ€ข Mementos are passive. Only the originator that created a memento will assign or retrieve its state.

 


ํŒจํ„ด ์‚ฌ์šฉ๋ฒ•

    1. Identify the roles of โ€œcaretakerโ€ and โ€œoriginatorโ€.
    2. Create a Memento class and declare the originator a friend.
    3. Caretaker knows when to "check point" the originator.
    4. Originator creates a Memento and copies its state to that Memento.
    5. Caretaker holds on to (but cannot peek into) the Memento.
    6. Caretaker knows when to "roll back" the originator.
    7. Originator reinstates itself using the saved state in the Memento.

ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

The Memento pattern has several consequences:

 

    1. Preserving encapsulation boundaries. Memento avoids exposing information that only an originator should manage but that must be stored nevertheless outside the originator. The pattern shields other objects from potentially complex Originator internals, thereby preserving encapsulation boundaries.

    2. It simplifies Originator. In other encapsulation-preserving designs, Originator keeps the versions of internal state that clients have requested. That puts all the storage management burden on Originator. Having clients manage the state they ask for simplifies Originator and keeps clients from having to notify originators when they're done.

    3. Using mementos might be expensive. Mementos might incur considerable overhead if Originator must copy large amounts of information to store in the memento or if clients create and return mementos to the originator often enough. Unless encapsulating and restoring Originator state is cheap, the pattern might not be appropriate.

    4. Defining narrow and wide interfaces. It may be difficult in some languages to ensure that only the originator can access the memento's state.

    5. Hidden costs incaring for mementos. A caretaker is responsible for deleting the mementos it cares for. However, the caretaker has no idea how much state is in the memento. Hence an otherwise lightweight caretaker might incur large storagecosts when it stores mementos.


๊ด€๋ จ ํŒจํ„ด๋“ค :  

 

Command : Commands can use mementos to maintain state for undoable operations.  

Iterator : Mementos can be used for iteration as described earlier.



์ถ”๊ฐ€ ์ •๋ณด :       

    • Command and Memento act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.
    • Command can use Memento to maintain the state required for an undo operation.
    • Memento is often used in conjunction with Iterator. An Iterator can use a Memento to capture the state of an iteration. The Iterator stores the Memento internally.

 

 


 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/memento

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )   

 


Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Interpreter ํŒจํ„ด์€ Behavioral ํŒจํ„ด์— ์†ํ•ฉ๋‹ˆ๋‹ค. 

 

Interpreter Pattern Structure

 



  

ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) :  

Given a language, define a represention for its grammar along with an interpreter that uses the representation to interpret sentences in the language.


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

   
A class of problems occurs repeatedly in a well-defined and well-understood domain. If the domain were characterized with a "language", then problems could be easily solved with an interpretation "engine".

 

GoF์˜ ๋””์ž์ธ ํŒจํ„ด์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ˆ์ œ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 

์•„๋ž˜ ๋ฌธ๋ฒ•์ด ์ •๊ทœ์‹์„ ํ‘œํ˜„ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

expression ::= literal | alternation | sequence | repetition |
                   '(' expression ')'

alternation ::= expression '|' expression
sequence ::= expression '&' expression
repetition ::= expression '*'
literal ::= 'a' | 'b' | 'c' | ... { 'a' | 'b' | 'c' | ... }*  


์—ฌ๊ธฐ์„œ expression์€ ์‹œ์ž‘ symbol์ด๊ณ  literal์€ ์ข…๋ฃŒ symbol์ž…๋‹ˆ๋‹ค. 

์ธํ„ฐํ”„๋ฆฌํ„ฐ ํŒจํ„ด์€ ๊ฐ ๋ฌธ๋ฒ•์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์šฐ์ธก์˜ ์‹ฌ๋ณผ๋“ค์€ ์ด ํด๋ž˜์Šค๋“ค์˜ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค. ์œ„ ๋ฌธ๋ฒ•์€ ๋‹ค์„ฏ๊ฐœ์˜ ํด๋ž˜์Šค๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”์ƒํด๋ž˜์Šค RegularExpression ๊ณผ ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค๋“ค์ธ LiteralExpression, AlternationExpression, SequenceExpression, ๊ทธ๋ฆฌ๊ณ  RepetitionExpression์ž…๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์˜ ์„ธ ํด๋ž˜์Šค๋“ค์€ ํ•˜์œ„ํ‘œํ˜„์‹์„ ๊ฐ–๋Š” ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.


 

์ด ๋ฌธ๋ฒ•์œผ๋กœ ์ •์˜๋œ ๋ชจ๋“  ์ •๊ทœ ํ‘œํ˜„์‹์€ ์œ„์™€๊ฐ™์€ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋กœ ์ด๋ฃจ์–ด์ง„ ์ถ”์ƒ ๋ฌธ๋ฒ• ํŠธ๋ฆฌ๋กœ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด, ์ถ”์ƒ ๋ฌธ๋ฒ• ํŠธ๋ฆฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.


 

represents the regular expression  

raining & (dogs | cats) *

We can create an interpreter for these regular expressions by definingthe Interpret operation on each subclass of RegularExpression.Interpret takes as an argument the context in which to interpret theexpression. The context contains the input string and information onhow much of it has been matched so far. Each subclass ofRegularExpression implements Interpret to match the next part of theinput string based on the current context. For example,

  • LiteralExpression will check if the input matches the literal it defines,

  • AlternationExpression will check if the input matches any of its alternatives,

  • RepetitionExpression will check if the input has multiple copies of expression it repeats, and so on.

 

์œ ์šฉ์„ฑ ( Applicability ) :

 

Use the Interpreter pattern when there is a language to interpret, and you can represent statements in the language as abstract syntax trees.The Interpreter pattern works best when

 

  • the grammar is simple. For complex grammars, the class hierarchy forthe grammar becomes large and unmanageable. Tools such as parsergenerators are a better alternative in such cases. They can interpret expressions without building abstract syntax trees, which can savespace and possibly time.

  • efficiency is not a critical concern. The most efficient interpreters are usually not implemented by interpreting parse trees directly but by first translating them into another form. For example, regular expressions are often transformed into state machines. But even then,the translator can be implemented by the Interpreter pattern, so the pattern is still applicable.

๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

  • AbstractExpression (RegularExpression)
    o
    declaresanabstractInterpretoperationthatiscommontoallnodes in the abstract syntax tree.
  • TerminalExpression (LiteralExpression)
    o
    implements an Interpret operation associated with terminal symbols in the grammar.
    o
    an instance is required for every terminal symbol in a sentence.

  • NonterminalExpression (AlternationExpression,RepetitionExpression, SequenceExpressions)
    o
    one such class is required for every rule R ::= R1 R2 ... Rn in the grammar.
    o
    maintains instance variables of type AbstractExpression for each of the symbols R1 through Rn.
    o
    implements an Interpret operation for nonterminal symbols in the grammar. Interpret typically calls itself recursively on the variables representing R1 through Rn.

  • Context
    o
    contains information that's global to the interpreter.

  • Client
    o
    builds (or is given) an abstract syntax tree representing a particular sentence in the language that the grammar defines. The abstract syntax tree is assembled from instances of the NonterminalExpression and TerminalExpression classes.
    o
    invokes the Interpret operation.


์›๋ฆฌ ( Collaborations ) :  

  • The client builds (or is given) the sentence as an abstract syntax tree of NonterminalExpression and TerminalExpression instances. Then the client initializes the context and invokes the Interpret operation.

  • Each NonterminalExpression node defines Interpret in terms ofInterpret on each subexpression. The Interpret operation of eachTerminalExpression defines the base case in the recursion.

  • The Interpret operations at each node use the context to store and access the state of the interpreter.

ํŒจํ„ด ์‚ฌ์šฉ๋ฒ•

  1. Decide if a "little language" offers a justifiable return on investment.
  2. Define a grammar for the language.
  3. Map each production in the grammar to a class.
  4. Organize the suite of classes into the structure of the Composite pattern.
  5. Define an interpret(Context) method in the Composite hierarchy.
  6. The Context object encapsulates the current state of the input and output as the former is parsed and the latter is accumulated. It is manipulated by each grammar class as the "interpreting" process transforms the input into the output.
ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

  1. The Interpreter pattern has the following benefits and liabilities:  


  2. 1. It's easy to change and extend the grammar. Because the pattern uses classes to represent grammar rules, you canuse inheritance to change or extend the grammar. Existing expressions can be modified incrementally, and new expressions can be defined as variations on old ones.  


  3. 2. Implementing the grammar is easy,too. Classes defining nodes in the abstract syntax tree have similar implementations. These classes are easy to write, and often their generation can be automated with a compiler or parser generator.  


  4. 3. Complex grammars are hard to maintain. The Interpreter pattern defines at least one class for every rule in the grammar (grammar rules defined using BNF may require multiple classes). Hence grammars containing many rules can be hard to manage and maintain. Other design patterns can be applied to mitigate the problem (see Implementation).But when the grammar is very complex, other techniques such as parser or compiler generators are more appropriate.  


  5. 4. Adding new ways to interpret expressions. The Interpreter pattern makes it easier to evaluate an expression in a new way. For example, you can support pretty printing ortype-checking an expression by defining a new operation on the expression classes. If you keep creating new ways of interpreting an expression, then consider using the Visitor pattern to avoid changing the grammar classes.

 

๊ด€๋ จ ํŒจํ„ด๋“ค :  

 

Composite :The abstract syntax tree is an instance of the Composite pattern.

Flyweight shows how to share terminal symbols within the abstract syntax tree.

Iterator :The interpreter can use an Iterator to traverse the structure.

Visitor can be used to maintain the behavior in each node in the abstract syntax tree in one class.

 

์ถ”๊ฐ€ ์ •๋ณด :    
  • Considered in its most general form (i.e. an operation distributed over a class hierarchy based on the Composite pattern), nearly every use of the Composite pattern will also contain the Interpreter pattern. But the Interpreter pattern should be reserved for those cases in which you want to think of this class hierarchy as defining a language.
  • Interpreter can use State to define parsing contexts.
  • The abstract syntax tree of Interpreter is a Composite (therefore Iterator and Visitor are also applicable).
  • Terminal symbols within Interpreter's abstract syntax tree can be shared with Flyweight.
  • The pattern doesn't address parsing. When the grammar is very complex, other techniques (such as a parser) are more appropriate.
 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/interpreter

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  


Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Observer ํŒจํ„ด์€ Behavioral ํŒจํ„ด์— ์†ํ•ฉ๋‹ˆ๋‹ค. 

์˜ต์ €๋ฒ„๋ผ๊ณ  ํ•˜๋‹ˆ๊นŒ 10๋…„์ „์— ์Šคํƒ€ํฌ๋ž˜ํ”„ํŠธ์—์„œ ๋‚˜์™”๋˜ ์˜ต์ €๋ฒ„๊ฐ€ ์ƒ๊ฐ์ด ๋‚˜๋„ค์š”. cloaking์ƒํƒœ๋กœ ์—ฌ๊ธฐ์ €๊ธฐ ๋งต์„ ๋’ค์ง€๊ณ  ๋‹ค๋…”๋˜ ๋…€์„์ด์ฃ . HP๋Š” ์–ด์ฐŒ๋‚˜ ์ ์€์ง€ ํ•œ๋ฐฉ์— ๊ทธ๋ƒฅ ํŽ‘ ํ„ฐ์ ธ์„œ ์ฃฝ์–ด๋ฒ„๋ฆฌ๋˜ ๋…€์„์ด์—ˆ์ฃ  ใ…Žใ…Ž.

์ด ์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ํ•œ ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ์ง€์ผœ๋ณด๊ณ  ์žˆ๋‹ค๊ฐ€ ์ด ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ์ด ๋˜๋ฉด ์ด ๊ฐ์ฒด์˜ ์ƒํƒœ์— ์˜์กด์ ์ธ ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค์˜ ์ƒํƒœ๋ฅผ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•ด์ฃผ๋Š” ํŒจํ„ด์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.  

์•„๋ž˜์—์„œ ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


Observer Pattern Structure

 




  

ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) :  

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

์˜ต ์ €๋ฒ„ ํŒจํ„ด์˜ ๋ชฉ์ ์€ ํ•˜๋‚˜์˜ ๊ฐ์ฒด์— ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ์ฒด๊ฐ€ ์˜์กด์ ์ธ ๊ฒฝ์šฐ์—, ๊ทธ ํ•œ ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ์ด ๋˜๋ฉด ์ด ๊ฐ์ฒด์— ์˜์กด์ ์ธ ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ์ฒด๋“ค์ด notification์„ ๋ฐ›๊ณ  ์ž๋™์œผ๋กœ ์ž์‹ ๋“ค์˜ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

     

Both a spreadsheet object and bar chart object can depict information in the same application data object using different presentations. The spreadsheet and the bar chart don't know about each other, thereby letting you reuse only the one you need. But they behave as though they do. When the user changes the information in the spreadsheet, the bar chart reflects the changes immediately, and vice versa.





This behavior implies that the spreadsheet and bar chart are dependent on the data object and therefore should be notified of any change in its state. And there's no reason to limit the number of dependent objects to two; there may be any number of different user interfaces to the same data.  


The Observer pattern describes how to establish these relationships. The key objects in this pattern are subject and observer. A subject may have any number of dependent observers. All observers are notified whenever the subject undergoes a change in state. In response, each observer will query the subject to synchronize its state with the subject's state.  


This kind of interaction is also known as publish-subscribe. The subject is the publisher of notifications. It sends out these notifications without having to know who its observers are. Any number of observers can subscribe to receive notifications.  

 


์œ ์šฉ์„ฑ ( Applicability ) :

 

Use the Observer pattern in any of the following situations:  

 

    • When an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently.
    • When a change to one object requires changing others, and you don't know how many objects need to be changed.
    • When an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don't want these objects tightly coupled.

 



๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :


Subject

o knows its observers. Any number of Observer objects may observe a subject.

o provides an interface for attaching and detaching Observer objects.

Observer

o defines an updating interface for objects that should be notified of changes in a subject. 

ConcreteSubject ( ์ดํ•˜ CS ) 

o stores state of interest to ConcreteObserver objects. 

o sends a notification to its observers when its state changes.

ConcreteObserver ( ์ดํ•˜ CO ) 

o maintains a reference to a ConcreteSubject object.

o stores state that should stay consistent with the subject's.  

o implements the Observer updating interface to keep its state consistent with the subject's.

 

 

์›๋ฆฌ ( Collaborations ) :  

  • ConcreteSubject notifies its observers whenever a change occurs that could make its observers' state inconsistent with its own.
    ConcreteSubject( ์ดํ•˜ CS )๊ฐ์ฒด๊ฐ€ ์ด ๊ฐ์ฒด๋ฅผ ์ง€์ผœ๋ณด๋Š” ์˜ต์ €๋ฒ„๋“ค์—๊ฒŒ ์ž์‹ ์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์˜ต์ €๋ฒ„๋“ค์€ ์ด ์ƒํƒœ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. CS๊ฐ์ฒด๊ฐ€ ์ž์‹ ์˜ ์ƒํƒœ๋ณ€ํ™”๋ฅผ ์•Œ๋ ค์ค„ ๋•Œ๋งˆ๋‹ค ์˜ต์ €๋ฒ„๋“ค ๋˜ํ•œ ์ƒํƒœ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๊ฒŒ ๋˜๋Š” ๊ฑฐ์ฃ .
  • After being informed of a change in the concrete subject, a ConcreteObserver object may query the subject for information. ConcreteObserver uses this information to reconcile its state with that of the subject.
    CS ๊ฐ€ ๋ณด๋‚ธ ์ƒํƒœ์ •๋ณด๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๋Š” ์•Œ๋ฆผ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์€ ConcreteObserver( ์ดํ•˜ CO )๋Š” CS์˜ ์ƒํƒœ์ •๋ณด๋ฅผ ์–ป๊ธฐ์œ„ํ•ด getState()๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CO๋Š” ์ด๋ ‡๊ฒŒ ์–ป์€ ์ •๋ณด๋ฅผ ์ด์šฉํ•ด์„œ CS ์ƒํƒœ์™€ ์ž์‹ ์ด ๊ฐ–๊ณ  ์žˆ๋Š” ์ƒํƒœ์ •๋ณด๋ฅผ ๋™์ผํ•˜๊ฒŒ ๋™๊ธฐํ™”์‹œํ‚ต๋‹ˆ๋‹ค.

    The following interaction diagram illustrates the collaborations between a subject and two observers:

 


Note how the Observer object that initiates the change request postpones its update until it gets a notification from the subject. Notify is not always called by the subject. It can be called by an observer or by another kind of object entirely. ์˜ต์ €๋ฒ„๊ฐ€ ๊ด€์ฐฐ์ค‘์ธ ๊ฐ์ฒด์˜ ์ƒํƒœ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์ž์‹ ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ƒํƒœ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์€ notify๊ฐ€ ์ด๋ฃจ์–ด์ง„ ๋’ค์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด notify๋Š” CS, CO, ๋˜๋Š” ์ „ํ˜€ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ๊ฐ์ฒด๊ฐ€ ํ˜ธ์ถœ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 


ํŒจํ„ด ์‚ฌ์šฉ๋ฒ•

    1. Differentiate between the core (or independent) functionality and the optional (or dependent) functionality.
    2. Model the independent functionality with a "subject" abstraction.
    3. Model the dependent functionality with an "observer" hierarchy.
    4. The Subject is coupled only to the Observer base class.
    5. The client configures the number and type of Observers.
    6. Observers register themselves with the Subject.
    7. The Subject broadcasts events to all registered Observers.
    8. The Subject may "push" information at the Observers, or, the Observers may "pull" the information they need from the Subject.

 


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ):  


The Observer pattern lets you vary subjects and observers independently. You can reuse subjects without reusing their observers, and vice versa. It lets you add observers without modifying the subject or other observers.

Further benefits and liabilities of the Observer pattern include thefollowing:  


1. Abstract coupling between Subject and Observer. All a subject knows is that it has a list of observers, each conforming to the simple interface of the abstract Observer class.The subject doesn't know the concrete class of any observer. Thus the coupling between subjects and observers is abstract and minimal.

Because Subject and Observer aren't tightly coupled, they can belong to different layers of abstraction in a system. A lower-level subject can communicate and inform a higher-level observer, thereby keeping the system's layering intact. If Subject and Observer are lumped together, then the resulting object must either span two layers (and violate the layering), or it must be forced to live in one layer or the other (which might compromise the layering abstraction).  


2. Support for broadcast communication. Unlike an ordinary request, the notification that a subject sends needn't specify its receiver. The notification is broadcast automatically to all interested objects that subscribed to it. The subject doesn't care how many interested objects exist; its only responsibility is to notify its observers. This gives you the freedom to add and remove observers at any time. It's up to the observer to handle or ignore a notification.  


3. Unexpected updates. Because observers have no knowledge of each other's presence, they can be blind to the ultimate cost of changing the subject. A seemingly innocuous operation on the subject may cause a cascade of updates to observers and their dependent objects. Moreover, dependency criteria that aren't well-defined or maintained usually lead to spurious updates, which can be hard to track down.

This problem is aggravated by the fact that the simple update protocol provides no details on what changed in the subject. Without additional protocol to help observers discover what changed, they maybe forced to work hard to deduce the changes.




๊ด€๋ จ ํŒจํ„ด๋“ค :  

    • Mediator : Byencapsulating complex update semantics, the ChangeManager acts asmediator between subjects and observers.
    • Singleton :The ChangeManager may use the Singleton pattern to make it uniqueand globally accessible.


์ถ”๊ฐ€ ์ •๋ณด :       

    • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time.
    • Mediator and Observer are competing patterns. The difference between them is that Observer distributes communication by introducing "observer" and "subject" objects, whereas a Mediator object encapsulates the communication between other objects. We've found it easier to make reusable Observers and Subjects than to make reusable Mediators.
    • On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them.


 

 


 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/observer

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )    


Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Mediator ํŒจํ„ด์€ Behavioral ํŒจํ„ด์— ์†ํ•ฉ๋‹ˆ๋‹ค. 

 

Mediator Pattern Structure

 



์ „ํ˜•์ ์ธ ๊ฐ์ฒด ๊ตฌ์กฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.




  

ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) :  

Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

    We want to design reusable components, but dependencies between the potentially reusable pieces demonstrates the "spaghetti code" phenomenon. ๊ฐœ๋ฐœ์ž๋“ค์€ ๋ณดํ†ต ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๋งŒ๋“ค๊ณ  ์‹ถ์–ดํ•˜์ง€๋งŒ ์ž ์žฌ์ ์œผ๋กœ ์žฌ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ๋“ค์˜ ์˜์กด์„ฑ์ด ์ผ๋ช… "์ŠคํŒŒ๊ฒŒํ‹ฐ ์ฝ”๋“œ"๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ŠคํŒŒ๊ฒŒํ‹ฐ ์ฝ”๋“œ๋ผ๋Š” ๊ฒƒ์€ ๊ฑฐ๋ฏธ์ค„์ฒ˜๋Ÿผ ๋’ค์ฃฝ๋ฐ•์ฃฝ ์˜์กด์„ฑ์ด ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

 

์œ ๋‹‰์Šค๋‚˜ ๋ฆฌ๋ˆ…์Šค ์‹œ์Šคํ…œ์— ์žˆ๋Š” ์‚ฌ์šฉ์ž ํผ๋ฏธ์…˜ ์‹œ์Šคํ…œ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•œ ์‚ฌ์šฉ์ž๋Š” ์—ฌ๋Ÿฌ ๊ทธ๋ฃน์— ์†ํ•ด์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ•œ ๊ทธ๋ฃน์€ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ ์ฒ˜๋Ÿผ ๋ง์ด์ฃ . 


์œ„ ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž๊ตฌ์š”. ๊ทธ๋Ÿผ User ๊ฐ์ฒด๋“ค๊ณผ Group๊ฐ์ฒด๋“ค ์‚ฌ์ด์— ์—ฐ๊ฒฐ๊ณ ๋ฆฌ๊ฐ€ ์žˆ๊ฒ ์ฃ ? ๊ทธ ์—ฐ๊ฒฐ๊ณ ๋ฆฌ ๋•Œ๋ฌธ์— User๊ฐ์ฒด๋‚˜ Group๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์„œ๋กœ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ฒŒ ๋ ๊ฒ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋‘˜ ์‚ฌ์ด์˜ ๊ด€๊ณ„๋งŒ์„ ์ •์˜ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค๋ฉด ์–ด๋–จ ๊นŒ์š”? User๊ฐ์ฒด๋‚˜ Group๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์„œ๋กœ์—๊ฒŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ฒŒ ๋  ์ผ์ด ์‚ฌ๋ผ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ˆ˜๋งŽ์€ ๊ด€๊ณ„๋“ค์„ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋  ๋ฟ์•„๋‹ˆ๋ผ ์ˆ˜์ •ํ•˜๋Š” ์ผ๋„ ์‰ฌ์›Œ์งˆ ๊ฒ๋‹ˆ๋‹ค. 

 

์—ฌ๊ธฐ์„œ ๊ด€๊ณ„๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ค‘์žฌ์ž ๊ฐ์ฒด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ค‘์žฌ์ž ๊ฐ์ฒด๋Š” ๋‹ค์Œ ์—ญํ• ๋“ค์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. 

  1. encapsulates all interconnections
  2. acts as the hub of communication
  3. is responsible for controlling and coordinating the interactions of its clients
  4. promotes loose coupling by keeping objects from referring to each other explicitly


์œ ์šฉ์„ฑ ( Applicability ) :

 

Use the Mediator pattern when

  • a set of objects communicate in well-defined but complex ways. The resulting inter dependencies are unstructured and difficult to understand.

  • reusing an object is difficult because it refers to and communicates with many other objects.

  • a behavior that's distributed between several classes should be customizable without a lot of subclassing.


๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

  • Mediator
    o
    defines an interface for communicating with Colleague objects.
  • ConcreteMediator
    o
    implements cooperative behavior by coordinating Colleague objects.
    o
    knows and maintains its colleagues.
  • Colleague classes
    o
    each Colleague class knows its Mediator object.
    o
    each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague.


์›๋ฆฌ ( Collaborations ) :  

  • Colleagues send and receive requests from a Mediator object. The mediator implements the cooperative behavior by routing requests between the appropriate colleague(s).


ํŒจํ„ด ์‚ฌ์šฉ๋ฒ•

  1. Identify a collection of interacting objects that would benefit from mutual decoupling.
  2. Encapsulate those interactions in the abstraction of a new class.
  3. Create an instance of that new class and rework all "peer" objects to interact with the Mediator only.
  4. Balance the principle of decoupling with the principle of distributing responsibility evenly.
  5. Be careful not to create a "controller" or "god" object.


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

The Mediator pattern has the following benefits and drawbacks:

  1. It limits subclassing. A mediator localizes behavior that otherwise would be distributed amongseveral objects. Changing this behavior requires subclassing Mediatoronly; Colleague classes can be reused as is.

  2. It decouples colleagues. A mediator promotes loose coupling between colleagues. You can vary and reuse Colleague and Mediator classes independently.

  3. It simplifies object protocols. A mediator replaces many-to-many interactions with one-to-many interactions between the mediator and its colleagues. One-to-many relationships are easier to understand, maintain, and extend.

  4. It abstracts how objects cooperate. Making mediation an independent concept and encapsulating it in an object lets you focus on how objects interact apart from their individual behavior. That can help clarify how objects interact in a system.

  5. It centralizes control. The Mediator pattern trades complexity of interaction for complexity in the mediator. Because a mediator encapsulates protocols, it can become more complex than any individual colleague. This can make the mediator itself a monolith that's hard to maintain.

๊ด€๋ จ ํŒจํ„ด๋“ค :  

 

Facade differsfrom Mediator in that it abstracts a subsystem of objects to providea more convenient interface. Its protocol is uni-directional; thatis, Facade objects make requests of the subsystem classes but notvice versa. In contrast, Mediator enables cooperative behavior that colleague objects don't or can't provide, and the protocol is multi-directional.

Colleagues can communicate with the mediator using the Observer pattern.


์ถ”๊ฐ€ ์ •๋ณด :      

  • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time.
  • Mediator and Observer are competing patterns. The difference between them is that Observer distributes communication by introducing "observer" and "subject" objects, whereas a Mediator object encapsulates the communication between other objects. We've found it easier to make reusable Observers and Subjects than to make reusable Mediators.
  • On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them.
  • Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediator abstracts/centralizes arbitrary communication between colleague objects, it routinely "adds value", and it is known/referenced by the colleague objects (i.e. it defines a multidirectional protocol). In contrast, Facade defines a simpler interface to a subsystem, it doesn't add new functionality, and it is not known by the subsystem classes (i.e. it defines a unidirectional protocol where it makes requests of the subsystem classes but not vice versa).

 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/mediator

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )   

 


๋””์ž์ธ ํŒจํ„ด์— ๋Œ€ํ•ด์„œ ํ•œ๋ฒˆ ํ›‘์–ด๋ณด๊ธด ํ–ˆ์—ˆ๋Š”๋ฐ ๋‹ค์‹œํ•œ๋ฒˆ ๋ณต์Šตํ•˜๋Š” ์ฐจ์›์—์„œ ํ•˜๋‚˜ํ•˜๋‚˜ ์ •๋ฆฌํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ–๊ณ  ์‹ถ์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์˜ค๋Š˜์€ ๊ทธ ์ฒซ์งธ ๋‚ .

 

์˜ค ๋Š˜ ํ•จ๊ป˜ ๋ณผ ๋””์ž์ธํŒจํ„ด์€ Iterator ํŒจํ„ด์ด๋‹ค. ๋‚ด์šฉ์˜ ๋Œ€๋ถ€๋ถ„์€ GoF์˜ ๋””์ž์ธํŒจํ„ด ์ฑ…์—์„œ ๋ฐœ์ทŒ๋ฅผ ํ•˜๊ฒŒ๋  ๊ฒƒ์ž„์„ ๋ฐํžŒ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์˜๋ฌธ์„ ํ•œ๊ธ€๋กœ ๋ฒˆ์—ญ์„ ํ•˜๊ฒŒ ๋ ํ…๋ฐ ์ „๋ฌธ๋ฒˆ์—ญ๊ฐ€๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ ํ•œ๊ธ€ ๋ฒˆ์—ญ๋ณธ์ด ์ดํ•ด๊ฐ€ ์•ˆ๊ฐ„๋‹ค๊ณ  ๋Š๋ผ๋ฉด ์˜๋ฌธ ์›๋ณธ์„ ์ฝ์–ด๋ณด์‹œ๊ธธ ๊ถŒ์œ ํ•œ๋‹ค.

 

๊ทธ๋Ÿผ ์‹œ์ž‘ํ•ด ๋ณผ๊นŒ?

 

์šฐ์„  GoF์˜ ๋””์ž์ธ ํŒจํ„ด์€ ์•„๋ž˜์™€ ๊ฐ™์ด ํฌ๊ฒŒ 3๊ฐ€์ง€ ์ข…๋ฅ˜๋กœ ๋ถ„๋ฅ˜๋œ๋‹ค.

 Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์ด์ œ ์‚ดํŽด๋ณผ Iterator ํŒจํ„ด์€ Behavioral ํŒจํ„ด์— ์†ํ•œ๋‹ค. 

Iterator๋Š” ์ž๋ฐ”์˜ Iterator์™€ ๊ฐ™์€ ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์‚ฌ์ „์  ์˜๋ฏธ๋กœ "๋ฐ˜๋ณต์ž"๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” iterator๋Š” ์ž๋ฐ”์˜ ๊ฒฝ์šฐ collection๊ฐ์ฒด์—์„œ ์‚ฌ์šฉ์ด ๋œ๋‹ค. ์˜ค๋ผํด์—์„œ ์ œ๊ณตํ•˜๋Š” Iterator์— ๋Œ€ํ•œ ์ •๋ณด๋Š” ์ด๊ณณ์—์„œ ํ™•์ธํ•˜๋ฉด๋œ๋‹ค. ์ด์ฒ˜๋Ÿผ ์•ž์œผ๋กœ ์‚ดํŽด๋ณผ ๋ชจ๋“  ํŒจํ„ด๋“ค์€ ๊ทธ ์ด๋ฆ„์—์„œ ์ด ํŒจํ„ด์ด ์–ด๋–ค ํŒจํ„ด์ธ์ง€ ํŒŒ์•…ํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

 

Iterator Pattern Structure

 

 


ํŒจํ„ด์˜ ๋ชฉ์  :
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

 

Iterator ํŒจํ„ด์˜ ๋ชฉ์ ์€ aggregate object ( ex. List )๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋ฌผ๋ก  ์ด ๊ณผ์ •์—์„œ ๊ฐœ๋ฐœ์ž๋Š” object๊ฐ€ ์–ด๋–ค์‹์œผ๋กœ ๊ตฌํ˜„์ด ๋˜์–ด์žˆ๋Š”์ง€๋Š” ์•Œ ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ object์˜ ๊ตฌํ˜„๋ถ€๋ฅผ ๋…ธ์ถœ์‹œํ‚ค์ง€ ์•Š๋Š”๋‹ค.

 

์œ ์šฉ์„ฑ ( Applicability ) :

ยท to access an aggregate object's contents without exposing its internal representation.

๋‚ด๋ถ€ ๊ตฌํ˜„์„ ๋…ธ์ถœ์‹œํ‚ค์ง€ ์•Š์œผ๋ฉด์„œ ์ง‘์•ฝ ๊ฐ์ฒด์˜ ๋‚ด์šฉ๋ฌผ์— ์ ‘๊ทผํ•˜๊ณ ์ž ํ•  ๋•Œ
ยท to support multiple traversals of aggregate objects.

์ง‘์•ฝ(์ง‘ํ•ฉ) ๊ฐ์ฒด๋“ค์— ๋Œ€ํ•ด ๋‹ค์–‘ํ•œ ํƒ์ƒ‰๊ฒฝ๋กœ(?)๋ฅผ ์ง€์›ํ•˜๊ณ ์ž ํ•  ๋•Œ
ยท to provide a uniform interface for traversing different aggregate structures (that is, to support polymorphic iteration).

๋‹ค๋ฅธ ์ง‘์•ฝ(์ง‘ํ•ฉ)๊ตฌ์กฐ๋“ค์„ ํƒ์ƒ‰ํ•˜๊ธฐ์œ„ํ•œ ํ†ต์ผ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๊ณ ์ž ํ•  ๋•Œ (์ฆ‰, ๋‹คํ˜•์  iteration์„ ์ง€์›ํ•˜๊ณ ์ž ํ•  ๋•Œ )

 

๋“ฑ์žฅ ์ธ๋ฌผ :
ยท Iterator
o defines an interface for accessing and traversing elements.
ยท ConcreteIterator
o implements the Iterator interface.
o keeps track of the current position in the traversal of the aggregate.
ยท Aggregate
o defines an interface for creating an Iterator object.
ยท ConcreteAggregate
o implements the Iterator creation interface to return an instance of the proper ConcreteIterator.

 

์žฅ๋‹จ์  :
1. It supports variations in the traversal of an aggregate.Complex aggregates
may be traversed in many ways. For example, code generation and semantic checking involve traversing parse trees. Code generation may traverse the parse tree inorder or preorder.Iterators make it easy to change the traversal algorithm: Just replace the iterator instance with a different
one. You can also define Iterator subclasses to support new traversals.
2. Iterators simplify the Aggregate interface.Iterator's traversal interface obviates the need for a similar interface in Aggregate, thereby simplifying the aggregate's interface.
3. More than one traversal can be pending on an aggregate.An iterator keeps track of its own traversal state. Therefore you can have more than one traversal in progress at once.


๊ด€๋ จ ํŒจํ„ด๋“ค : 

Composite : Iterators are often applied to recursive structures such as Composites.
Factory Method : Polymorphic iterators rely on factory methods to instantiate theappropriate Iterator subclass.
Memento is often used in conjunction with the Iterator pattern. An iterator can use a memento to capture the state of an iteration. The iterator stores the memento internally. 

 

 

 


์ถœ์ฒ˜ : Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )

Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Command ( ๋ช…๋ น, ์ปค๋งจ๋“œ )ํŒจํ„ด์€ Behavioral ํŒจํ„ด์— ์†ํ•œ๋‹ค.   

๋ช…๋ น ํŒจํ„ด์ด๋ผ~ ๋ช…๋ น์„ ๋‚ด๋ฆฌ๋Š” ํŒจํ„ด์ด๋ผ๋Š” ๊ฑฐ๊ฒ ์ฃ ??

์ž์„ธํžˆ ์•Œ์•„๋ด…์‹œ๋‹ค.

 

Command Pattern Structure

 


 


  

ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) :  

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.  

๋ช…๋ น ํŒจํ„ด, ์ปค๋งจ๋“œ ํŒจํ„ด์€ ํ•˜๋‚˜์˜ ์š”์ฒญ์„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ์บก์Šํ™”ํ•˜์—ฌ ์š”์ฒญ์„ ํŒŒ๋ผ๋ฏธํ„ฐ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•ด์ฃผ๋ฉฐ ๋˜๋Œ๋ฆฌ๊ธฐ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•œ๋‹ค. 


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

   Need to issue requests to objects without knowing anything about the operation being requested or the receiver of the request.

์ด ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ๋ผ ํ•˜๋ฉด ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ ์š”์ฒญ์„ ๋‚ ๋ฆด ๋•Œ ์–ด๋–ค ์š”์ฒญ์ด ๋‚ ์•„๊ฐ€๋Š”์ง€ ๋ฆฌ์‹œ๋ฒ„๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€์— ๋Œ€ํ•ด์„œ ๋ชฐ๋ผ๋„ ๋˜๊ฒŒ๋” ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ž…๋‹ˆ๋‹ค.  

 

GoF์˜ ๋””์ž์ธ ํŒจํ„ด์—์„œ๋Š” ์‘์šฉํ”„๋กœ๊ทธ๋žจ์˜ ๋ฉ”๋‰ด๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ์–ด๋–ค ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์˜ˆ๋กœ ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.


 ์œ„ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์€ ์‘์šฉํ”„๋žจ์—์„œ ๋ฉ”๋‰ด๋ฅผ ์„ ํƒํ•ด์„œ ๋“ค์–ด๊ฐ€๊ณ  ํ•˜์œ„๋ฉ”๋‰ด๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ํŠน์ • ๋ช…๋ น์ด ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.๋ฉ”๋‰ด์•„์ดํ…œ์€ ์ปค๋งจ๋“œ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  ์ด ์ปค๋งจ๋“œ ๊ฐ์ฒด๋Š” ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์–ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฉ”๋‰ด์•„์ดํ…œ๊ฐ์ฒด๋Š” ์ด ์ปค๋งจ๋“œ๊ฐ์ฒด๊ฐ€ ๋ฌด์Šจ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ์ง€๋Š” ๋ชจ๋ฅด๊ณ  ๊ทธ๋ƒฅ ์‹คํ–‰๋งŒ ์‹œํ‚ค๋Š” ๊ฒ๋‹ˆ๋‹ค. 

 

์œ ์šฉ์„ฑ ( Applicability ) :

Use the Command pattern when you want to

๋ช…๋ น ํŒจํ„ด์€ ์ด๋Ÿด ๋•Œ ์“ฐ์„ธ์š”. 

โ€ข parameterize objects by an action to perform, as MenuItem objects did above. You can express such parameterization in a procedural language with a callback function, that is, a function that's registered somewhere to be called at a later point. Commands are an object-oriented replacement for callbacks.  

 

โ€ข specify, queue, and execute requests at different times. A Command object can have a lifetime independent of the original request. If the receiver of a request can be represented in an address space-independent way, then you can transfer a command object for the request to a different process and fulfill the request there.

 

โ€ข support undo. The Command's Execute operation can store state for reversing its effects in the command itself. The Command interface must have an added Unexecute operation that reverses the effects of a previous call to Execute. Executed commands are stored in a history list. Unlimited-level undo and redo is achieved by traversing this list backwards and forwards calling Unexecute and Execute, respectively.

 

โ€ข support logging changes so that they can be reapplied in case of a system crash. By augmenting the Command interface with load and store operations, you can keep a persistent log of changes. Recovering from a crash involves reloading logged commands from disk and reexecuting them with the Execute operation.

 

โ€ข structure a system around high-level operations built on primitives operations. Such a structure is common in information systems that support transactions. A transaction encapsulates a set of changes to data. The Command pattern offers a way to model transactions. Commands have a common interface, letting you invoke all transactions the same way. The pattern also makes it easy to extend the system with new transactions.



๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :


โ€ข Command

o declares an interface for executing an operation.  

โ€ข ConcreteCommand

o defines a binding between a Receiver object and an action.

o implements Execute by invoking the corresponding operation(s) on Receiver.

โ€ข Client 

           o creates a ConcreteCommand object and sets its receiver.
โ€ข Invoker

           o asks the command to carry out the request.
โ€ข Receiver

           o
knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver.


์›๋ฆฌ ( Collaborations ) :

  • The client creates a ConcreteCommand object and specifies its receiver.
  • An Invoker object stores the ConcreteCommand object.
  • The invoker issues a request by calling Execute on the command. When commands are undoable, ConcreteCommand stores state for undoing thecommand prior to invoking Execute.

  • The ConcreteCommand object invokes operations on its receiver to carryout the request.

 

The following diagram shows the interactions between these objects.It illustrates how Command decouples the invoker from the receiver(and the request it carries out).

 

 


ํŒจํ„ด ์‚ฌ์šฉ๋ฒ•

  1. Define a Command interface with a method signature like execute().
  2. Create one or more derived classes that encapsulate some subset of the following: a "receiver" object, the method to invoke, the arguments to pass.
  3. Instantiate a Command object for each deferred execution request.
  4. Pass the Command object from the creator (aka sender) to the invoker (aka receiver).
  5. The invoker decides when to execute().

ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

The Command pattern has the following consequences:  

  1. Command decouples the object that invokes the operation from the one that knows how to perform it.
  2. Commands are first-class objects.They can be manipulated and extended like any other object.
  3. You can assemble commands into a composite command. In general, composite commands are an instance of the Composite pattern.
  4. It's easy to add new Commands, because you don't have to change existing classes.

๊ด€๋ จ ํŒจํ„ด๋“ค :  

A Composite can be used to implement MacroCommands.
A Memento can keep state the command requires to undo its effect.

A command that must be copied before being placed on the historylist acts as a Prototype.


์ถ”๊ฐ€ ์ •๋ณด :     

  • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Command normally specifies a sender-receiver connection with a subclass.
  • Chain of Responsibility can use Command to represent requests as objects.
  • Command and Memento act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.
  • Command can use Memento to maintain the state required for an undo operation.
  • MacroCommands can be implemented with Composite.
  • A Command that must be copied before being placed on a history list acts as a Prototype.
  • Two important aspects of the Command pattern: interface separation (the invoker is isolated from the receiver), time separation (stores a ready-to-go processing request that's to be stated later).

 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/command

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  

 


Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Composite ํŒจํ„ด์€ Structural ํŒจํ„ด์— ์†ํ•œ๋‹ค.  

 

Composite Pattern Structure

 

A typical Composite object structure might look like this:



ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) : 

 

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

์ปด ํฌ์ง€ํŠธ ํŒจํ„ด์€ ๊ฐ์ฒด๋“ค์˜ ๊ด€๊ณ„๋ฅผ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑํ•˜์—ฌ ๋ถ€๋ถ„-์ „์ฒด ๊ณ„์ธต์„ ํ‘œํ˜„ํ•˜๋Š” ํŒจํ„ด์œผ๋กœ, ์‚ฌ์šฉ์ž๊ฐ€ ๋‹จ์ผ ๊ฐ์ฒด์™€ ๋ณตํ•ฉ ๊ฐ์ฒด ๋ชจ๋‘ ๋™์ผํ•˜๊ฒŒ ๋‹ค๋ฃจ๋„๋ก ํ•˜๋Š” ํŒจํ„ด์ด๋‹ค. ๋”ฐ๋ผ์„œ, {๊ฐ์ฒด์˜ ๊ทธ๋ฃน}๊ณผ {ํ•˜๋‚˜์˜ ๊ฐ์ฒด}๊ฐ€ ๋™์ผํ•œ ํ–‰์œ„๋ฅผ ํ•  ๋•Œ ์ ์šฉ๋˜์•ผ ํ•˜๋ฉฐ, ๋˜ํ•œ ํŠธ๋ฆฌ๊ตฌ์กฐ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. 

 

ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :


๊ทธ ๋ž˜ํ”ฝ ํˆด์€ ์‚ฌ์šฉ์ž๋“ค๋กœ ํ•˜์—ฌ๊ธˆ ๊ฐ„๋‹จํ•œ ์ปดํฌ๋„ŒํŠธ ( ex. ์„ , ์‚ฌ๊ฐํ˜•, ๋ฌธ์ž, ๊ทธ๋ฆผ ๋“ฑ๋“ฑ )๋ถ€ํ„ฐ ๋ณต์žกํ•œ ์ปดํฌ๋„ŒํŠธ ( ex. ๊ธ€์”จ๊ฐ€ ๋“ค์–ด๊ฐ„ ์‚ฌ๊ฐํ˜• )์— ์ด๋ฅด๊ธฐ๊นŒ์ง€ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. ์ด๋ฅผ ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„ํ•˜์ž๋ฉด ๊ฐ๊ฐ์˜ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. Lineํด๋ž˜์Šค, Rectangle ํด๋ž˜์Šค๋ฅผ ๊ฐ๊ฐ ์ •์˜ํ•ด์„œ ๊ฐ€์ ธ๋‹ค๊ฐ€ ์“ฐ๋ฉด ๋˜๋Š”๋ฐ ๋‹จ์ˆœํžˆ ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„์„ ํ•˜๋ฉด ๋‚˜์ค‘์— ํฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ ๊ฐ์ฒด์™€ ์ปจํ…Œ์ด๋„ˆ ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฅด๊ฒŒ ๋‹ค๋ฃจ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๊ฒŒ ๋ฌด์Šจ ์†Œ๋ฆฌ๋ƒ ํ•˜๋ฉด, ๊ทธ๋ฆผํŒ์—์„œ ํ•˜๋‚˜์˜ ์ง์„ ์„ ๊ทธ์—ˆ๋‹ค๊ณ  ํ•˜์ž. ์ด ์ง์„ ์€ ์‹œ์ž‘์ ๊ณผ ๋์  ์ขŒํ‘œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ•˜๋‚˜์˜ ๊ฐ์ฒด๊ฒ ์ง€? ๊ทธ๋Ÿฐ๋ฐ ๋˜๋‹ค๋ฅธ ์ง์„ ์„ ๊ทธ์—ˆ๋‹ค. ๋‘๋ฒˆ์งธ ์ง์„  ์—ญ์‹œ ์‹œ์ž‘์ ๊ณผ ๋์  ์ขŒํ‘œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ฒ ์ง€. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋‘๊ฐœ๋ฅผ ํ•œ๊บผ๋ฒˆ์— ์ €์žฅํ•˜๋ ค๋ฉด ๋‘๊ฐœ์˜ ์ง์„  ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ ์žˆ๋Š” ๋˜๋‹ค๋ฅธ wrapper ํด๋ž˜์Šค๊ฐ€ ์žˆ์–ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ง์„ ์ด ๋ช‡๊ฐœ๊ฐ€ ๋ ์ง€ ๋ˆ„๊ฐ€ ์•„๋ƒ? ๊ทธ๋ฆฌ๋Š” ์‚ฌ๋žŒ์ด ๋ช‡๊ฐœ๋ฅผ ๊ทธ๋ฆด์ง€๋Š” ์•„๋ฌด๋„ ๋ชจ๋ฅด์ž–์•„? ๊ทธ๋ž˜์„œ ์ด๋Ÿฐ ์‹์œผ๋กœ ์ ‘๊ทผํ•˜๋‹ค๊ฐ€๋Š” ํ‰์ƒํ•ด๋„ ์ œ๋Œ€๋กœ๋œ ๊ทธ๋ž˜ํ”ฝ ํˆด์„ ๋ชป ๋งŒ๋“ค ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜์˜จ ๊ฒƒ์ด ๋ฐ”๋กœ ์ด ์ปดํฌ์ง€ํŠธ ํŒจํ„ด์ธ ๊ฒƒ์ด๋‹ค. ์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๋ณด์ž.


 

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

๋‚ด ๊ฐ€ ์–ด์ œ ํ•˜๋‚˜์˜ ๊ทธ๋ฆผ์„ ๊ทธ๋ ธ๋‹ค. ์ด ๊ทธ๋ฆผ์€ ์‚ฌ๊ฐํ˜•๊ณผ ์ง์„  ๊ทธ๋ฆฌ๊ณ  ๋ฌธ์ž๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์˜ค๋Š˜ ๋‚˜๋Š” ๋‘๋ฒˆ์งธ ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๋ฉด์„œ ์–ด์ œ ๊ทธ๋ฆฐ ๊ทธ๋ฆผ๊ณผ ๋˜ ๋‹ค๋ฅธ ์„ , ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ ค๋„ฃ์—ˆ๋‹ค. ์ด๊ฒƒ์„ ๋‹ค์ด์–ด๊ทธ๋žจ์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฒƒ์ด ์•„๋ž˜ ๊ทธ๋ฆผ์ด๋‹ค.

aPicture, aTest, aLine, aRectangle์€ ๋ชจ๋‘ ๊ทธ๋ž˜ํ”ฝ ๊ฐ์ฒด์ด๋‹ค. ์ด ๊ทธ๋ž˜ํ”ฝ ๊ฐ์ฒด๋“ค์€ ๋˜ ๋‹ค๋ฅธ ๊ทธ๋ž˜ํ”ฝ ๊ฐ์ฒด๋“ค์„ ์ž์‹์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ด์ œ ์ดํ•ด๊ฐ€ ๋˜๋Š”๊ฐ€?


์œ ์šฉ์„ฑ ( Applicability ) :

 Use the Composite pattern when
ยท you want to represent part-whole hierarchies of objects.
ยท you want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly.



๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

ยท Component (Graphic)
o declares the interface for objects in the composition.
o implements default behavior for the interface common to all classes, as appropriate.
o declares an interface for accessing and managing its child components.
o (optional) defines an interface for accessing a component's parent in the recursive structure, and implements it if that's appropriate.
ยท Leaf (Rectangle, Line, Text, etc.)
o represents leaf objects in the composition. A leaf has no children.
o defines behavior for primitive objects in the composition.
ยท Composite (Picture) 

o defines behavior for components having children.
o stores child components.
o implements child-related operations in the Component interface.
ยท Client
o manipulates objects in the composition through the Component interface.

 


์›๋ฆฌ ( Collaborations ) :

ยท Clients use the Component class interface to interact with objects in the composite structure. If the recipient is a Leaf, then the request is handled directly. If the recipient is a Composite, then it usually forwards requests to its child components, possibly performing additional operations before and/or after forwarding.


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

The Composite pattern


ยท defines class hierarchies consisting of primitive objects and composite objects. Primitive objects can be composed into more complex objects, which in turn can be composed, and so on recursively. Wherever client code expects a primitive object, it can also take a composite object.  

ยท makes the client simple. Clients can treat composite structures and individual objects uniformly. Clients normally don't know (and shouldn't care) whether they're dealing with a leaf or a composite component. This simplifies client code, because it avoids having to write tag-and-case-statement-style functions over the classes that define the composition.
ยท makes it easier to add new kinds of components. Newly defined Composite or Leaf subclasses work automatically with existing structures and client code. Clients don't have to be changed for new Component classes.
ยท can make your design overly general. The disadvantage of making it easy to add new components is that it makes it harder to restrict the components of a composite. Sometimes you want a composite to have only certain components. With Composite, you can't rely on the type system to enforce those constraints for you. You'll have to use run-time checks instead.

 

๊ด€๋ จ ํŒจํ„ด๋“ค : 

 Often the component-parent link is used for a Chain of Responsibility.
Decorator is often used with Composite. When decorators and composites are used together, they will usually have a common parent class. So decorators will have to support the Component interface with operations like Add, Remove, and GetChild.
Flyweight lets you share components, but they can no longer refer to their parents.
Iterator can be used to traverse composites.
Visitor localizes operations and behavior that would otherwise be distributed across Composite and Leaf classes.

 

์ถ”๊ฐ€ ์ •๋ณด :

  • Composite and Decorator have similar structure diagrams, reflecting the fact that both rely on recursive composition to organize an open-ended number of objects.
  • Composite can be traversed with Iterator. Visitor can apply an operation over a Composite. Composite could use Chain of Responsibility to let components access global properties through their parent. It could also use Decorator to override these properties on parts of the composition. It could use Observer to tie one object structure to another and State to let a component change its behavior as its state changes.
  • Composite can let you compose a Mediator out of smaller pieces through recursive composition.
  • Decorator is designed to let you add responsibilities to objects without subclassing. Composite's focus is not on embellishment but on representation. These intents are distinct but complementary. Consequently, Composite and Decorator are often used in concert.
  • Flyweight is often combined with Composite to implement shared leaf nodes.

 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/composite

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  

http://www.journaldev.com/1535/composite-design-pattern-in-java-example-tutorial 


Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Facade ํŒจํ„ด์€ Structural ํŒจํ„ด์— ์†ํ•œ๋‹ค.  ์ด ํŒจํ„ด์€ ์ปดํฌ์ง€ํŠธ ํŒจํ„ด๊ณผ ๋น„์Šทํ•œ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. 

Facade๋Š” ํผ์‚ฌ๋“œ๋ผ๊ณ  ์ฝ๋Š”๋‹ค. ํผ์ผ€์ด๋“œ, ํŒจ์ผ€์ด๋“œ ์ด๋”ด์‹์œผ๋กœ ์ฝ๋Š”๊ฒŒ ์•„๋‹ˆ๋‹ค.

 

Facade Pattern Structure


ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) : 

 Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.  

ํผ์‚ฌ๋“œ ํŒจํ„ด์€ ์„œ๋ธŒ์‹œ์Šคํ…œ ๋‚ด๋ถ€์— ์žˆ๋Š” ํด๋ž˜์Šค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ํ•˜๋‚˜์˜ ํ†ตํ•ฉ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒจํ„ด์ด๋‹ค. 


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

 

ํฐ ์‹œ์Šคํ…œ์„ ์ž‘์€ ์‹œ์Šคํ…œ์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์€ ์‹œ์Šคํ…œ์˜ ๋ณต์žก๋„๋ฅผ ๋‚ฎ์ถฐ์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋””์ž์ธ์˜ ๊ณตํ†ต ๋ชฉํ‘œ๋Š” ์„œ๋ธŒ์‹œ์Šคํ…œ๋“ค ์‚ฌ์ด์˜ ์˜์กด์„ฑ์„ ์ค„์ด๊ณ  ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ํšŸ์ˆ˜๋ฅผ ์ค„์ด๋Š” ๊ฒƒ์ธ๋ฐ ํผ์‚ฌ๋“œ ํŒจํ„ด์ด ์ด๋ฅผ ์œ„ํ•œ ๋ฐฉ๋ฒ•์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์—์„œ ์ปค๋‹ค๋ž€ ์‚ฌ๊ฐํ˜•์ด ์„œ๋ธŒ์‹œ์Šคํ…œ์ด๊ณ  ๊ทธ ์•ˆ์— ์ž‘์€ ์‚ฌ๊ฐํ˜•๋“ค์€ ์„œ๋ธŒ์‹œ์Šคํ…œ์˜ ํด๋ž˜์Šค๋“ค์„ ์˜๋ฏธํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์„œ๋ธŒ์‹œ์Šคํ…œ ๋ฐ–์—๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ธŒ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํด๋ž˜์Šค๋“ค์ด ์žˆ๋‹ค. 


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

 

์ด ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๊ฐ€ ์ปดํŒŒ์ผ๋Ÿฌ์ด๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„๋œ๋‹ค.



์œ ์šฉ์„ฑ ( Applicability ) :

Use the Facade pattern when


ยท you want to provide a simple interface to a complex subsystem. Subsystems often get more complex as they evolve. Most patterns, when applied, result in more and smaller classes. This makes the subsystem more reusable and easier to customize, but it also becomes harder to use for clients that don't need to customize it. A facade can provide a simple default view of the subsystem that is good enough for most clients. Only clients needing more customizability will need to look beyond the facade.

๋ณต์žกํ•œ ์„œ๋ธŒ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ„๋‹จํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ


ยท there are many dependencies between clients and the implementation classes of an abstraction. Introduce a facade to decouple the subsystem from clients and other subsystems, thereby promoting subsystem independence and portability.

์„œ๋ธŒ์‹œ์Šคํ…œ์„ ํด๋ผ์ด์–ธํŠธ ๋˜๋Š” ๋‹ค๋ฅธ ์„œ๋ธŒ์‹œ์Šคํ…œ์œผ๋กœ๋ถ€ํ„ฐ ๋””์ปคํ”Œ์‹œํ‚ด์œผ๋กœ์จ ๋…๋ฆฝ์„ฑ๊ณผ ํœด๋Œ€์„ฑ(์ด์‹์„ฑ)์„ ๋†’์ด๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ 


ยท you want to layer your subsystems. Use a facade to define an entry point to each subsystem level. If subsystems are dependent, then you can simplify the dependencies between them by making them communicate with each other solely through their facades.


๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

ยท Facade (Compiler)
o knows which subsystem classes are responsible for a request.
o delegates client requests to appropriate subsystem objects.
ยท subsystem classes (Scanner, Parser, ProgramNode, etc.)
o implement subsystem functionality.
o handle work assigned by the Facade object.
o have no knowledge of the facade; that is, they keep no references to it.


์›๋ฆฌ ( Collaborations ) :

ยท Clients communicate with the subsystem by sending requests to Facade, which forwards them to the appropriate subsystem object(s). Although the subsystem objects perform the actual work, the facade may have to do work of its own to translate its interface to subsystem interfaces.

ํด๋ผ์ด์–ธํŠธ๋Š” ํผ์‚ฌ๋“œ์— ์š”์ฒญ์„ ํ•จ์œผ๋กœ์จ ๋ณต์žกํ•œ ์„œ๋ธŒ์‹œ์Šคํ…œ์— ์ ‘๊ทผํ•œ๋‹ค.
ยท Clients that use the facade don't have to access its subsystem objects directly.

ํด๋ผ์ด์–ธํŠธ๋Š” ๋ณต์žกํ•œ ์„œ๋ธŒ์‹œ์Šคํ…œ์˜ ๊ฐ์ฒด์— ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. 


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

 The Facade pattern offers the following benefits:


1. It shields clients from subsystem components, thereby reducing the number of objects that clients deal with and making the subsystem easier to use. ์‚ฌ์šฉ์ž๊ฐ€ ์•Œ์•„์•ผ ํ•˜๋Š” ์„œ๋ธŒ์‹œ์Šคํ…œ์˜ ๋ฒ”์œ„๋ฅผ ์ค„์—ฌ์ค€๋‹ค. 


2. It promotes weak coupling between the subsystem and its clients. 1๋ฒˆ์˜ ์ด์œ ๋กœ ์‚ฌ์šฉ์ž์™€ ์„œ๋ธŒ์‹œ์Šคํ…œ ์‚ฌ์ด์˜ ์ปคํ”Œ๋ง ๊ด€๊ณ„๋ฅผ ์•ฝํ™”์‹œ์ผœ์ค€๋‹ค. Often the components in a subsystem are strongly coupled. Weak coupling lets you vary the components of the subsystem without affecting its clients. Facades help layer a system and the dependencies between objects. They can eliminate complex or circular dependencies. This can be an important consequence when the client and the subsystem are implemented independently. Reducing compilation dependencies is vital in large software systems. You want to save time by minimizing recompilation when subsystem classes change. Reducing compilation dependencies with facades can limit the recompilation needed for a small change in an important subsystem. A facade can also simplify porting systems to other platforms, because it's less likely that building one subsystem requires building all others.


3. It doesn't prevent applications from using subsystem classes if they need to. ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•  ๋•Œ์—๋Š” ์„œ๋ธŒ์‹œ์Šคํ…œ์— ์ง์ ‘ ์ ‘๊ทผํ•˜์—ฌ ๋‚ด๋ถ€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.Thus you can choose between ease of use and generality.

 

๊ด€๋ จ ํŒจํ„ด๋“ค : 

Abstract Factory can be used with Facade to provide an interface for creating subsystem objects in a subsystem-independent way. Abstract Factory can also be used as an alternative to Facade to hide platform-specific classes.
Mediator is similar to Facade in that it abstracts functionality of existing classes. However, Mediator's purpose is to abstract arbitrary communication between colleague objects, often centralizing functionality that doesn't belong in any one of them. A mediator's colleagues are aware of and communicate with the mediator instead of communicating with each other directly. In contrast, a facade merely abstracts the interface to subsystem objects to make them easier to use; it doesn't define new functionality, and subsystem classes don't know about it.
Usually only one Facade object is required. Thus Facade objects are often Singletons.


์ถ”๊ฐ€ ์ •๋ณด :  

  • Facade defines a new interface, whereas Adapter uses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one.
  • Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.
  • Mediator is similar to Facade in that it abstracts functionality of existing classes. Mediator abstracts/centralizes arbitrary communications between colleague objects. It routinely "adds value", and it is known/referenced by the colleague objects. In contrast, Facade defines a simpler interface to a subsystem, it doesn't add new functionality, and it is not known by the subsystem classes.
  • Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.
  • Facade objects are often Singletons because only one Facade object is required.
  • Adapter and Facade are both wrappers; but they are different kinds of wrappers. The intent of Facade is to produce a simpler interface, and the intent of Adapter is to design to an existing interface. While Facade routinely wraps multiple objects and Adapter wraps a single object; Facade could front-end a single complex object and Adapter could wrap several legacy objects.
  • Facade pattern is more like a helper for client applications, it doesnโ€™t hide subsystem interfaces from the client. Whether to use Facade or not is completely dependent on client code.
  • Facade pattern can be applied at any point of development, usually when the number of interfaces grow and system gets complex.
  • Subsystem interfaces are not aware of Facade and they shouldnโ€™t have any reference of the Facade interface.
  • Facade pattern should be applied for similar kind of interfaces, its purpose is to provide a single interface rather than multiple interfaces that does the similar kind of jobs.
  • We can use Factory Pattern with Facade to provide better interface to client systems.

์–ด๋Œ‘ํ„ฐ ํŒจํ„ด๊ณผ ํผ์‚ฌ๋“œ ํŒจํ„ด์˜ ์ฐจ์ด์ ์€ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ํด๋ž˜์Šค๋ฅผ wrapํ•˜๋Š๋ƒ๊ฐ€ ์•„๋‹ˆ๋‹ค. Adapter ํŒจํ„ด์€ ํ•˜๋‚˜ ์ด์ƒ์˜ ํด๋ž˜์Šค๋ฅผ ๋ฌถ์–ด์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›ํ•˜๋Š” ์ถœ๋ ฅ์ด ๋‚˜์˜ค๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๊ณ  Facade ํŒจํ„ด์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‚ฌ์šฉํ•˜๊ธฐ์—๋Š” ๋ณต์žกํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ๊ณ  ๊ฐ„๋‹จํ•œ ์ ‘๊ทผ๊ฒฝ๋กœ๋ฅผ ์ œ๊ณตํ•จ์œผ๋กœ์จ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์†์‰ฝ๊ฒŒ ๋ณต์žกํ•œ ์ธํ„ฐํŽ˜์ด์Šค ๋‚ด๋ถ€์˜ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

 

 

 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/facade

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  

http://www.journaldev.com/1557/facade-pattern-in-java-example-tutorial

 


 Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Bridge ํŒจํ„ด์€ Structural ํŒจํ„ด์— ์†ํ•œ๋‹ค.  

 

๋ง๊ทธ๋Œ€๋กœ A์™€ B๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋‹ค๋ฆฌ์—ญํ• ์„ ํ•˜๋Š” ํŒจํ„ด์ด๋‹ค. 

 

Bridge Pattern Structure



 


ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) : 

Decouple an abstraction from its implementation so that the two can vary independently.

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

 

 

ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

When an abstraction can have one of several possible implementations, the usual way to accommodate them is to use inheritance. An abstract class defines the interface to the abstraction, and concrete subclasses implement it in different ways. But this approach isn't always flexible enough. Inheritance binds an implementation to the abstraction permanently, which makes it difficult to modify, extend, and reuse abstractions and implementations independently.
Consider the implementation of a portable Window abstraction in a user interface toolkit. This abstraction should enable us to write applications that work on both the X Window System and IBM's Presentation Manager (PM), for example. Using inheritance, we could define an abstract class Window and subclasses XWindow and PMWindow that implement the Window interface for the different platforms. But this approach has two drawbacks:


1. It's inconvenient to extend the Window abstraction to cover different kinds
of windows or new platforms. Imagine an IconWindow subclass of Window that
specializes the Window abstraction for icons. To support IconWindows for
both platforms, we have to implement two new classes, XIconWindow and
PMIconWindow. Worse, we'll have to define two classes for every kind of
window. Supporting a third platform requires yet another new Window subclass
for every kind of window.

 


2. It makes client code platform-dependent. Whenever a client creates a window, it instantiates a concrete class that has a specific implementation. For example, creating an XWindow object binds the Window abstraction to the X Window implementation, which makes the client code dependent on the X Window implementation. This, in turn, makes it harder to port the client code to other platforms.


Clients should be able to create a window without committing to a concrete implementation. Only the window implementation should depend on the platform on which the application runs.  Therefore client code should instantiate windows without mentioning specific platforms. 

 

The Bridge pattern addresses these problems by putting the Window abstraction and its implementation in separate class hierarchies. There is one class hierarchy for window interfaces (Window, IconWindow, TransientWindow) and a separate hierarchy for platform-specific window implementations, with WindowImp as its root. The XWindowImp subclass, for example, provides an implementation based on the X Window System. 

 



์œ ์šฉ์„ฑ ( Applicability ) :

Use the Bridge pattern when
ยท you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at  run-time.
ยท both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently.
ยท changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled.
ยท (C++) you want to hide the implementation of an abstraction completely from clients. In C++ the representation of a class is visible in the class interface.
ยท you have a proliferation of classes as shown earlier in the first Motivation diagram. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations"  to refer to such class hierarchies.
ยท you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class , in which multiple objects can share the same string representation (StringRep).

 

๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

ยท Abstraction (Window)
o defines the abstraction's interface.
o maintains a reference to an object of type Implementor.

ยท RefinedAbstraction (IconWindow)
o Extends the interface defined by Abstraction.
ยท Implementor (WindowImp)
o defines the interface for implementation classes. This interface doesn't have to correspond exactly to Abstraction's interface; in fact the two interfaces can be quite different. Typically the
Implementor interface provides only primitive operations, and Abstraction defines higher-level operations based on these primitives.

ยท ConcreteImplementor (XWindowImp, PMWindowImp)
o implements the Implementor interface and defines its concrete implementation.


 

 All operations on Window subclasses are implemented in terms of abstract operations from the WindowImp interface. This decouples the window abstractions from the various platform-specific implementations. We refer to the relationship between Window and WindowImp as a bridge,  because it bridges the abstraction and its implementation, letting them vary independently.


์›๋ฆฌ ( Collaborations ) :

ยท Abstraction forwards client requests to its Implementor object.


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

The Bridge pattern has the following consequences:


1. Decoupling interface and implementation. An implementation is not bound permanently to an interface. The implementation of an abstraction can be configured at run-time. It's even possible for an object to change its implementation at run-time.
Decoupling Abstraction and Implementor also eliminates compile-time dependencies on the implementation. Changing an implementation class doesn't require recompiling the Abstraction class and its clients. This property is essential when you must ensure binary compatibility between different versions of a class library.
Furthermore, this decoupling encourages layering that can lead to a better-structured system. The high-level part of a system only has to know about Abstraction and Implementor. 

 

2. Improved extensibility. You can extend the Abstraction and Implementor hierarchies independently.


3. Hiding implementation details from clients. You can shield clients from implementation details, like the sharing of implementor objects and the accompanying reference count mechanism (if any).


๊ด€๋ จ ํŒจํ„ด๋“ค : 

An Abstract Factory can create and configure a particular Bridge.
The Adapter pattern
is geared toward making unrelated classes work together. It is usually applied to systems after they're designed. Bridge, on the other hand, is used up-front in a design to let abstractions and implementations vary independently.

 

์ถ”๊ฐ€ ์ •๋ณด :     

  • Adapter makes things work after they're designed; Bridge makes them work before they are.
  • Bridge is designed up-front to let the abstraction and the implementation vary independently. Adapter is retrofitted to make unrelated classes work together.
  • State, Strategy, Bridge (and to some degree Adapter) have similar solution structures. They all share elements of the "handle/body" idiom. They differ in intent - that is, they solve different problems.
  • The structure of State and Bridge are identical (except that Bridge admits hierarchies of envelope classes, whereas State allows only one). The two patterns use the same structure to solve different problems: State allows an object's behavior to change along with its state, while Bridge's intent is to decouple an abstraction from its implementation so that the two can vary independently.
  • If interface classes delegate the creation of their implementation classes (instead of creating/coupling themselves directly), then the design usually uses the Abstract Factory pattern to create the implementation objects.

 

 

 

์ถœ์ฒ˜ : http://sourcemaking.com/design_patterns/bridge

         Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )

 


Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Proxy ํŒจํ„ด์€ Structural ํŒจํ„ด์— ์†ํ•œ๋‹ค.  

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

์ดํ•ด๊ฐ€ ์ž˜ ์•ˆ๊ฐ„๋‹ค๋ฉด ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž. 

 

Proxy Pattern Structure

 


์šฐ์„  ์ด ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ๋ถ€ํ„ฐ ์ดํ•ด๋ฅผ ํ•ด๋ณด๋„๋ก ํ•˜์ž. ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฒƒ์€ RealSubject์™€ Proxy ๊ทธ๋ฆฌ๊ณ  Subject์‚ฌ์ด์˜ ๊ด€๊ณ„์ด๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” Subject๊ฐ์ฒด์˜ Request()๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  Subject๊ฐ์ฒด๋ฅผ ๋ฐ›๋Š”๋‹ค. RealSubject์™€  Proxy๋Š” Subject๋ฅผ ์ƒ์†ํ•˜๋Š” ํด๋ž˜์Šค๋“ค์ธ๋ฐ Proxyํด๋ž˜์Šค์˜ Request()๋Š” ๊ฒฝ์šฐ์— ๋”ฐ๋ผ RealSubject์˜ Request()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. RealSubject์˜ Request()์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›ํ•˜๋Š” Subject๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.  

๋”ฐ๋ผ์„œ runtime์—๋Š” ํ˜ธ์ถœ ์ˆœ์„œ๊ฐ€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. Proxy๋Š” RealSubject๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ ์ด๊ฒƒ์ด null์ด ์•„๋‹Œ ๊ฒฝ์šฐ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•˜๊ณ  null์ธ๊ฒฝ์šฐ RealSubject์˜ Request()๋ฅผ ์š”์ฒญํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ทธ๊ฒƒ์„ Proxy ๋‚ด๋ถ€์— ๊ฐ€์ง€๊ณ  ์žˆ๊ฒŒ ๋œ๋‹ค.



ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) :  


Provide a surrogate or placeholder for another object to control access to it.
ํ”„๋ก์‹œ ํŒจํ„ด์˜ ๋ชฉ์ ์€ ๋˜๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ ‘๊ทผ์„ ์ปจํŠธ๋กคํ•˜๊ธฐ ์œ„ํ•ด์„œ ๊ทธ ๊ฐ์ฒด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ๊ทธ๋ฆ‡์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

 

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

 

์œ„์—์„œ ๋ดค๋˜ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์— ๋ฌธ์„œํ”„๋กœ๊ทธ๋žจ์˜ ์˜ˆ๋ฅผ ์ ์šฉ์‹œ์ผœ ๋ณธ ๊ฒƒ์ด๋‹ค. ImageProxy์˜ ์šฐ์ธก์„ ๋ณด๋ฉด image๊ฐ€ 0์ธ์ง€๋ฅผ ํŒ๋ณ„ํ•˜๊ณ  0์ผ๊ฒฝ์šฐ Image๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ณด์—ฌ์ค€๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ฃผ๋Š” ๊ฐ„๋žตํ•œ ์†Œ์Šค๊ฐ€ ๋ณด์ธ๋‹ค.

 

 

์œ ์šฉ์„ฑ ( Applicability ) :

 

Proxy is applicable whenever there is a need for a more versatile or sophisticated reference to an object than a simple pointer. Here are several common situations in which the Proxy pattern is applicable:  

ํ”„๋ก์‹œ ํŒจํ„ด์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.


1. A remote proxy provides a local representative for an object in a different address space. NEXTSTEP [Add94] uses the class NXProxy for this purpose. Coplien [Cop92] calls this kind of proxy an "Ambassador."


2. A virtual proxy creates expensive objects on demand. The ImageProxy described in the Motivation is an example of such a proxy.


3. A protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights. For example, KernelProxies in the Choices operating system [CIRM93] provide protected access to operating system objects.


4. A smart reference is a replacement for a bare pointer that performs additional actions when an object is accessed. Typical uses include

o counting the number of references to the realobject so that it can be freed automatically when there are no more references (also called smart pointers [Ede92]).

o loading a persistent object into memory when it's first referenced.  

o checking that the realobject is locked before it's accessed to ensure that no other object can change it.

 


๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

โ€ข Proxy (ImageProxy) 

o maintainsareferencethatletstheproxyaccesstherealsubject.

Proxy may refer to a Subject if the RealSubject and Subject interfaces are the same.

o provides an interface identical to Subject's so that a proxy can by substituted for the real subject.

o controls access to the real subject and may be responsible for creating and deleting it.

o other responsibilities depend on the kind of proxy:

รŸ remote proxies are responsible for encoding a request and its arguments and for sending the encoded request to the real

subject in a different address space.
รŸ virtual proxies may cache additional information about the real subject so that they can postpone accessing it. For example, the ImageProxy from the Motivation caches the real image's extent.

รŸ protection proxies check that the caller has the access permissions required to perform a request.

โ€ข Subject (Graphic)

o defines the common interface for RealSubject and Proxy so that a Proxy can be used anywhere a RealSubject is expected.

โ€ข RealSubject (Image)

o defines the real object that the proxy represents.


์›๋ฆฌ ( Collaborations ) :

โ€ข Proxy forwards requests to RealSubject when appropriate, depending on the kind of proxy.


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

 

The Proxy pattern introduces a level of indirection when accessing an object. The additional indirection has many uses, depending on the kind of proxy:

  1. A remote proxy can hide the fact that an object resides in a different address space.

  2. A virtual proxy can perform optimizations such as creating an object on demand.

  3. Both protection proxies and smart references allow additional house keeping tasks when an object is accessed.

There's another optimization that the Proxy pattern can hide from the client. It's called copy-on-write, and it's related to creation on demand. Copying a large and complicated object can be an expensive operation. If the copy is never modified, then there's no need to incur this cost. By using a proxy to postpone the copying process, we ensure that we pay the price of copying the object only if it's modified.

 

To make copy-on-write work, the subject must be reference counted. Copying the proxy will do nothing more than increment this reference count. Only when the client requests an operation that modifies the subject does the proxy actually copy it. In that case the proxy must also decrement the subject's reference count. When the reference count goes to zero, the subject gets deleted.

Copy-on-write can reduce the cost of copying heavyweight subjects significantly.

 

๊ด€๋ จ ํŒจํ„ด๋“ค : 

 

Adapter : An adapter provides a different interface to the object it adapts. In contrast, a proxy provides the same interface as its subject. However, a proxy used for access protection might refuse to perform an operation that the subject will perform, so its interface may be effectively a subset of the subject's.

Decorator : Although decorators can have similar implementations as proxies, decorators have a different purpose. A decorator adds one or more responsibilities to an object, whereas a proxy controls access to an object.

 

Proxies vary in the degree to which they are implemented like a decorator. A protection proxy might be implemented exactly like a decorator. On the other hand, a remote proxy will not contain a direct reference to its real subject but only an indirect reference, such as "host ID and local address on host." A virtual proxy will start off with an indirect reference such as a file name but will eventually obtain and use a direct reference.

 

 

์ถ”๊ฐ€ ์ •๋ณด :   

  • Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface.
  • Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests.

 

 

ํ”„๋ก์‹œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

 

interface Image { public void displayImage(); } //on System A class RealImage implements Image { private String filename; public RealImage(String filename) { this.filename = filename; loadImageFromDisk(); } private void loadImageFromDisk() { System.out.println("Loading " + filename); } public void displayImage() { System.out.println("Displaying " + filename); } } //on System B class ProxyImage implements Image { private String filename; private Image image; public ProxyImage(String filename) { this.filename = filename; } public void displayImage() { if (image == null) { image = new RealImage(filename); } image.displayImage(); } } class ProxyExample { public static void main(String[] args) { Image image1 = new ProxyImage("HiRes_10MB_Photo1"); Image image2 = new ProxyImage("HiRes_10MB_Photo2"); image1.displayImage(); // loading necessary image2.displayImage(); // loading necessary
image1.displayImage(); // loading unnecessary image2.displayImage(); // loading unnecessary } }

๋˜ ๋‹ค๋ฅธ ๋ชฉ์ ( ๋ฆฌ๋ˆ…์Šค์—์„œ ๊ถŒํ•œ์— ๋”ฐ๋ผ ๋ช…๋ น์–ด ์‹คํ–‰์„ ๋ง‰๊ฑฐ๋‚˜ ํ†ต๊ณผ์‹œํ‚ค๋Š”)์œผ๋กœ ์‚ฌ์šฉ๋œ ํ”„๋ก์‹œ ํŒจํ„ด์˜ ์˜ˆ์ œ๋Š” ์•„๋ž˜ ๋งํฌ์—์„œ ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

http://www.journaldev.com/1572/proxy-design-pattern-in-java-example-tutorial

 



์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/proxy

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  

 http://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9D%EC%8B%9C_%ED%8C%A8%ED%84%B4


Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Decorator ํŒจํ„ด์€ Structural ํŒจํ„ด์— ์†ํ•œ๋‹ค.  ์ด ํŒจํ„ด์€ ์ปดํฌ์ง€ํŠธ ํŒจํ„ด๊ณผ ๋น„์Šทํ•œ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. 

 

Decorator Pattern Structure


ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) : 

 Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

 ๋™์ ์œผ๋กœ ๊ฐ์ฒด์— ์ฑ…์ž„(๊พธ๋ฐˆ)์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ธฐ ์œ„ํ•œ subclassing์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์œ ๋™์ ์ธ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. 


ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ„๋‹จํ•œ ํ”„๋กœ์ ํŠธ๊ฐ€ ์•„๋‹Œ ์ด์ƒ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค ๋‚ด์—์„œ ๋ชจ๋“  ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๋Š” ์ผ์€ ๊ฑฐ์˜ ์—†๋‹ค. ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์œ„ํ•ด์„œ๋ผ๋„ ๊ธฐ๋Šฅ๋ณ„๋กœ ํด๋ž˜์Šค๋ฅผ ๋‚˜๋ˆ„๊ฒŒ ๋˜๋Š”๋ฐ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด๋„ ์ด๋Ÿฐ ์‹์˜ ์ƒ๊ฐ์—์„œ ๋‚˜์˜ค๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์ƒ์†์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๊ธฐ๋„ ํ•˜๋Š”๋ฐ ์ด๋Š” ๋งค์šฐ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ•์ด๋ฉฐ flexibleํ•˜์ง€ ์•Š๊ณ  ์ •์ ์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋™์ ์œผ๋กœ ๊ธฐ๋Šฅํ™•์žฅ์ด ์šฉ์ดํ•˜๋„๋ก ํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ ์ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์ด๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์€ TextView์— ScrollDecorator์™€ BorderDecorator๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฑ…์ž„(๊พธ๋ฐˆ)์„ ์ถ”๊ฐ€ํ•œ ๊ฒฐ๊ณผ์ด๋‹ค.

 

์œ ์šฉ์„ฑ ( Applicability ) :

Use Decorator

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•˜๋‹ค.


ยท to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects.

๋‹ค๋ฅธ ๊ฐ์ฒด์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ณ  ๋™์ ์œผ๋กœ ํˆฌ๋ช…ํ•˜๊ฒŒ ๋…๋ฆฝ์ ์ธ ๊ฐ์ฒด๋“ค์„ ์ถ”๊ฐ€ํ•  ๋•Œ
ยท for responsibilities that can be withdrawn.

์ฒ ํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ฑ…์ž„(๊พธ๋ฐˆ)์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ
ยท when extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing. 

์„œ๋ธŒํด๋ž˜์‹ฑ์œผ๋กœ ๊ธฐ๋Šฅํ™•์žฅํ•˜๋Š” ๊ฒƒ์ด ๋น„์‹ค์šฉ์ ์ผ ๋•Œ


๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

ยท Component (VisualComponent)
o defines the interface for objects that can have responsibilities added to them dynamically.

๋™์ ์œผ๋กœ ์ถ”๊ฐ€๋˜๋Š” ์ฑ…์ž„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค.
ยท ConcreteComponent (TextView)
o defines an object to which additional responsibilities can be attached.

์ถ”๊ฐ€์ ์ธ ์ฑ…์ž„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•œ๋‹ค.
ยท Decorator
o maintains a reference to a Component object and defines an interface that conforms to Component's interface.

์ด ํŒจํ„ด์˜ ๋ฉ”์ธ์ด๋‹ค. ์ปดํฌ๋„ŒํŠธ ๊ฐ์ฒด์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ์ปดํฌ๋„ŒํŠธ์™€ ์กฐํ™”๋ฅผ ์ด๋ฃจ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค.
ยท ConcreteDecorator (BorderDecorator, ScrollDecorator)
o adds responsibilities to the component.

์ปดํฌ๋„ŒํŠธ์— ์ฑ…์ž„์„ ๋ถ€๊ณผํ•œ๋‹ค. 


์›๋ฆฌ ( Collaborations ) :

ยท Decorator forwards requests to its Component object. It may optionally perform additional operations before and after forwarding the request.


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 

The Decorator pattern has at least two key benefits and two liabilities:

 

1. More flexibility than static inheritance. ์ •์ ์ธ ์ƒ์†๋ณด๋‹ค ํ›จ์”ฌ ์œ ๋™์ ์ด๋‹ค. The Decorator pattern provides a more flexible way to add responsibilities to objects than can be had with static (multiple) inheritance. With decorators, responsibilities can be added and removed at run-time simply by attaching and detaching them. In contrast, inheritance requires creating a new class for each additional responsibility (e.g., BorderedScrollableTextView, BorderedTextView). This gives rise to many classes and increases the complexity of a system.
Furthermore, providing different Decorator classes for a specific Component class lets you mix and match responsibilities.
Decorators also make it easy to add a property twice. For example, to give a TextView a double border, simply attach two BorderDecorators. Inheriting from a Border class twice is error-prone at best.


2. Avoids feature-laden classes high up in the hierarchy. Decorator offers a pay-as-you-go approach to adding responsibilities. Instead of trying to support all foreseeable features in a complex, customizable class, you can define a simple class and add functionality incrementally with Decorator objects. Functionality can be composed from simple pieces. As a result, an application needn't pay for features it doesn't use. It's also easy to define new kinds of Decorators independently from the classes of objects
they extend, even for unforeseen extensions. Extending a complex class tends to expose details unrelated to the responsibilities you're adding.


3. A decorator and its component aren't identical. A decorator acts as a transparent enclosure. But from an object identity point of view, a decorated component is not identical to the component itself. Hence you shouldn't rely on object identity when you use decorators.


4. Lots of little objects. A design that uses Decorator often results in systems composed of lots of little objects that all look alike. The objects differ only in the way they are interconnected, not in their class or in the value of their variables. Although these systems are easy to customize by those who understand them, they can be hard to learn and debug. 

 

๊ด€๋ จ ํŒจํ„ด๋“ค : 

Adapter : A decorator is different from an adapter in that a decorator only changes an object's responsibilities, not its interface; an adapter will give an object a completely new interface. 

 Composite : A decorator can be viewed as a degenerate composite with only one component. However, a decorator adds additional responsibilitiesโ€”it isn't intended for object aggregation.
Strategy : A decorator lets you change the skin of an object; a strategy lets you change the guts. These are two alternative ways of changing an object.


์ถ”๊ฐ€ ์ •๋ณด :  

  • Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface.
  • Adapter changes an object's interface, Decorator enhances an object's responsibilities. Decorator is thus more transparent to the client. As a consequence, Decorator supports recursive composition, which isn't possible with pure Adapters.
  • Composite and Decorator have similar structure diagrams, reflecting the fact that both rely on recursive composition to organize an open-ended number of objects.
  • A Decorator can be viewed as a degenerate Composite with only one component. However, a Decorator adds additional responsibilities - it isn't intended for object aggregation.
  • Decorator is designed to let you add responsibilities to objects without subclassing. Composite's focus is not on embellishment but on representation. These intents are distinct but complementary. Consequently, Composite and Decorator are often used in concert.
  • Composite could use Chain of Responsibility to let components access global properties through their parent. It could also use Decorator to override these properties on parts of the composition.
  • Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests.
  • Decorator lets you change the skin of an object. Strategy lets you change the guts.
  • Decorator pattern is helpful in providing runtime modification abilities and hence more flexible. Its easy to maintain and extend when the number of choices are more.
  • The disadvantage of decorator pattern is that it uses a lot of similar kind of objects (decorators).
    ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์˜ ๋‹จ์ ์€ ์œ ์‚ฌํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๊ฐ€ ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.
  • Decorator pattern is used a lot in Java IO classes, such as FileReader, BufferedReader etc.
    ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒจํ„ด์€ FileReader๋‚˜ BufferedReader์™€ ๊ฐ™์€ Java IO ํด๋ž˜์Šค๋“ค์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.

 

์ถœ์ฒ˜ :  http://sourcemaking.com/design_patterns/decorator

Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )  

http://www.journaldev.com/1540/decorator-pattern-in-java-example-tutorial

 

 

 

์‹ค์ƒํ™œ์„ ์˜ˆ๋กœ ๋“  ์ข‹์€ ์˜ˆ์ œ๋Š” ์•„๋ž˜์—์„œ ํ™•์ธํ•˜๊ธฐ ๋ฐ”๋ž€๋‹ค.

http://warmz.tistory.com/757


 Creational Patterns ( ์ƒ์„ฑ ํŒจํ„ด )

These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. 

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


 Structural Patterns ( ๊ตฌ์กฐ์  ํŒจํ„ด )

These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. 

๊ตฌ์กฐ์  ํŒจํ„ด๋“ค์€ ํด๋ž˜์Šค์™€ ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ๊ด€์—ฌํ•œ๋‹ค.

 

 Behavioral Patterns ( ํ–‰์œ„์  ํŒจํ„ด )

These design patterns are specifically concerned with communication between objects.

์ด ํŒจํ„ด๋“ค์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ๊ด€์‹ฌ์„ ๊ฐ€์ง„๋‹ค.

 

์˜ค๋Š˜ ์‚ดํŽด๋ณผ  Adapter ํŒจํ„ด์€ Structural ํŒจํ„ด์— ์†ํ•œ๋‹ค.  

 

์–ด ๋Œ‘ํ„ฐ๊ฐ€ ๋ญ๋ƒ? ์šฐ๋ฆฌ๊ฐ€ ๋งจ๋‚  ์“ฐ๋Š” ๊ทธ ์–ด๋Œ‘ํ„ฐ๊ฐ€ ๋ฐ”๋กœ ์ง€๊ธˆ ๋งํ•˜๊ณ ์žํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ์ด๋‹ค. ์–ด๋Œ‘ํ„ฐ์˜ ์—ญํ• ์ด ๋ญ๋ƒ? ์„œ๋กœ ๋งž๋ฌผ๋ฆฌ์ง€ ์•Š๋Š” ๋‘๊ฐœ์˜ ๊ฐ์ฒด๋ฅผ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๋Š” ์ผ์„ ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋Œ‘ํ„ฐ์˜ ์—ญํ• ์ด๋‹ค. ์ด ์ƒ๊ฐ์„ ๊ฐ€์ง€๊ณ  ์•„๋ž˜ ๋‚ด์šฉ์„ ํ›‘์–ด๋ณด๊ธฐ ๋ฐ”๋ž€๋‹ค.

 

Adapter Pattern Structure

 A class adapter uses multiple inheritance to adapt one interface to another:

ํด๋ž˜์Šค ์–ด๋Œ‘ํ„ฐ๋Š” ํ•˜๋‚˜์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋‹ค๋ฅธ ์ธํ„ฐํŽ˜์ด์Šค์™€ ์—ฐ๊ฒฐ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์ค‘์ƒ์†์„ ์ด์šฉํ•œ๋‹ค.

 

 

An object adapter relies on object composition:

๊ฐ์ฒด ์–ด๋Œ‘ํ„ฐ๋Š” ๊ฐ์ฒด์˜ ๊ตฌ์„ฑ์— ์˜์กดํ•œ๋‹ค. ( ๋ญ” ๋ง์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค ์ผ๋‹จ ๋„˜์–ด๊ฐ€์ž )



 

ํŒจํ„ด์˜ ๋ชฉ์  ( Intent ) : 

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

์–ด๋Œ‘ํ„ฐ ํŒจํ„ด์˜ ๋ชฉ์ ์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์›ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ ํด๋ž˜์Šค์˜ ํ˜•ํƒœ๋ฅผ ๋ณ€ํ˜•ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.(์ด๋Š” ์„œ๋กœ ์—ฐ๊ฒฐ์„ ์‹œ์ผœ์คŒ์œผ๋กœ์จ ์•„์›ƒํ’‹์„ ๋ณ€ํ˜•ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด์ง€ ์‹ค์ œ๋กœ ๋ณ€ํ˜•ํ•œ๋‹ค๋Š” ์˜๋ฏธ๊ฐ€ ์•„๋‹ˆ๋‹ค) ์–ด๋Œ‘ํ„ฐ๋Š” ์„œ๋กœ ๋งž๋ฌผ๋ฆฌ์ง€ ์•Š๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋“ค์„ ์„œ๋กœ ์—ฐ๊ฒฐ์‹œ์ผœ์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

 

 

ํŒจํ„ด์ด ๋‚˜์˜ค๊ฒŒ ๋œ ๋™๊ธฐ ( Motivation ) :

์˜ˆ ๋ฅผ ๋“ค์–ด ์ด๋Ÿฐ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ๊ณ ๊ฐ์ด ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„์„ ํ–ˆ๋‹ค๊ณ  ํ•˜์ž. ์ด ๊ธฐ๋Šฅ์€ ์ธํ’‹์œผ๋กœ A๊ฐ์ฒด๋ฅผ ๋ฐ›์•„๋“ค์ด๊ณ  ์•„์›ƒํ’‹์œผ๋กœ X๊ฐ์ฒด๋ฅผ ๋˜์ง€๋ฉฐ ๊ณ ๊ฐ์ด ๋งŒ๋“  API์™€ ์—ฐ๊ฒฐ์ด ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์–ผ๋งˆ๊ฐ€ ์ง€๋‚˜์„œ ๊ณ ๊ฐ์ด ์ธํ’‹์œผ๋กœ Y๊ฐ์ฒด๋ฅผ ๋‹ฌ๋ผ๊ณ  ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ „์— ๋งŒ๋“ค์–ด ์คฌ๋˜ ๊ธฐ๋Šฅ์˜ ์ผ๋ถ€๋ถ„๋งŒ Y๊ฐ์ฒด๋ฅผ ์•„์›ƒํ’‹์œผ๋กœ ๋‚ด๋ณด๋‚ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๋‹น์‹ ์ด๋ผ๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ๊ฒƒ์ธ๊ฐ€? ๋ฌผ๋ก  ์ƒ๊ฐํ•ด์•ผํ•  ์ธ์ž๋“ค์ด ๋ฌด์ˆ˜ํžˆ ๋งŽ์„ ๊ฒƒ์ด๊ณ  ๊ทธ๊ฒƒ๋“ค์— ๋”ฐ๋ผ ํ•ด๊ฒฐ์ฑ…๋„ ๋‹ค๋ฅผ ๊ฒƒ์ด๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๊ทธ ์ค‘ ํ•˜๋‚˜์˜ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด์„ ๋งํ•˜๊ณ ์ž ํ•œ๋‹ค. A -> DoSomething -> X ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์—ฌ์ „ํžˆ ์กด์žฌํ•ด์•ผ๋งŒ ํ•˜๋ฉฐ DoSomething -> Y ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋‘๊ฐ€์ง€๋Š” ์—„์—ฐํžˆ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค. ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด์„ ์ด์šฉํ•ด์•ผํ•˜๋‹ˆ๊นŒ. ๊ทธ๋Ÿฌ๋ฉด ์šฐ๋ฆฌ๋Š” A -> DoSomething -> X -> Y ๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ฒŒ๋” X -> Y ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

 

์‰ฝ๊ฒŒ๋งํ•˜์ž๋ฉด์†Œ์ผ“์— ๋งž๋Š” ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋ง์ด๋‹ค.


 

 


์œ ์šฉ์„ฑ ( Applicability ) :

Use the Adapter pattern when
ยท you want to use an existing class, and its interface does not match the one you need.

๊ธฐ์กด์˜ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€๋งŒ ๋‚ด๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ํ˜•ํƒœ๊ฐ€ ์•„๋‹๋•Œ
ยท you want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces.

ํŠน์ • ํ˜ธํ™˜์„ฑ์„ ๊ฐ€์ง„ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ๊ด‘๋ฒ”์œ„ํ•œ ํ˜ธํ™˜์„ฑ์„ ๊ฐ€์ง„ ์žฌ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์„๋•Œ
ยท (object adapter only) you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class.

 

๋“ฑ์žฅ ์ธ๋ฌผ ( Participants ) :

ยท Target (Shape)o defines the domain-specific interface that Client uses.
ยท Client (DrawingEditor)
o collaborates with objects conforming to the Target interface.
ยท Adaptee (TextView)
o defines an existing interface that needs adapting.
ยท Adapter (TextShape)
o adapts the interface of Adaptee to the Target interface.

 

์›๋ฆฌ ( Collaborations ) : 

ยท Clients call operations on an Adapter instance. In turn, the adapter calls Adaptee operations that carry out the request.


ํŒจํ„ด ์‚ฌ์šฉ์˜ ์žฅ๋‹จ์  ( Consequences ): 


Class and object adapters have different trade-offs.  

ํด๋ž˜์Šค ์–ด๋Œ‘ํ„ฐ์™€ ๊ฐ์ฒด์–ด๋Œ‘ํ„ฐ๋Š” ์„œ๋กœ์˜ ์žฅ๋‹จ์ ์ด ์žˆ๋‹ค.  

A class adapter  

ยท adapts Adaptee to Target by committing to a concrete Adapter class. As a consequence, a class adapter won't work when we want to adapt a class and all its subclasses.

ยท lets Adapter override some of Adaptee's behavior, since Adapter is a subclass of Adaptee.
ยท introduces only one object, and no additional pointer indirection is needed to get to the adaptee.

 

An object adapter
ยท lets a single Adapter work with many Adapteesโ€”that is, the Adaptee itself and all of its subclasses (if any). The Adapter can also add functionality to all Adaptees at once.
ยท makes it harder to override Adaptee behavior. It will require subclassing Adaptee and making Adapter refer to the subclass rather than the Adaptee itself.


๊ด€๋ จ ํŒจํ„ด๋“ค : 

Bridge has a structure similar to an object adapter, but Bridge has a different intent: It is meant to separate an interface from its implementation so that they can be varied easily and  independently. An adapter is meant to change the interface of an existing object.
Decorator
enhances another object without changing its interface. A decorator is thus more transparent to the application than an adapter is. As a consequence, Decorator supports  recursive composition, which isn't possible with pure adapters.
Proxy
defines a representative or surrogate for another object and does not change its interface.

 

์ถ”๊ฐ€ ์ •๋ณด :     

  • Adapter makes things work after they're designed; Bridge makes them work before they are.
  • Bridge is designed up-front to let the abstraction and the implementation vary independently. Adapter is retrofitted to make unrelated classes work together.
  • Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface.
  • Adapter is meant to change the interface of an existing object. Decorator enhances another object without changing its interface. Decorator is thus more transparent to the application than an adapter is. As a consequence, Decorator supports recursive composition, which isn't possible with pure Adapters.
  • Facade defines a new interface, whereas Adapter reuses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one.

 

 

 

์ถœ์ฒ˜ : http://sourcemaking.com/design_patterns/adapter

         Design Patterns : Element of Reusable Object Oriented Software ( by GoF, 1994 )