๋์์ธ ํจํด์ ๊ณต๋ถํ ๋ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ํด๋น ๋์์ธ ํจํด์ด ์ด๋ค ๊ฒฝ์ฐ์ ์ฌ์ฉ๋์ด์ผ ํ๋ ์ง๋ฅผ ์์์ผ ํ๋ ๊ฒ์ด๋ค. ํ ์คํธ ์ฝ๋๋ก ๋์์ธ ํจํด์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์๋๋ผ๋ ๋์์ธ ํจํด์ ์๋๋ฅผ ์ ๋๋ก ํ์ ํ์ง ๋ชปํ๊ณ ์ค์ ์ ํฉํ ์ฌ์ฉ์ฒ๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด ์๋ฏธ๊ฐ ์๋ค. ์ฌ์ฉ์ฒ๋ฅผ ์ ๋๋ก ์๊ณ ๊ฐ๋จํ๊ฒ ๊ตฌํํด๋ณด์.
ํ๋ก์ ํจํด์ ์ค์ ๊ฐ์ฒด๋ก์ ์ ๊ทผ์ ํต์ ํ๋๋ฐ ์ฌ์ฉ๋๋ค.
์ ๊ทผ์ ํต์ ํ๋ค๋ ๊ฒ์ด ๋ณด์์ ์ธ ๊ฒ๋ง์ ์๋ฏธํ๋ ๊ฒ์ ์๋๋ค. (๋น์ฐํ ๋จ์ํ ์ ๊ทผํต์ ์๋ ์ฌ์ฉํ ์ ์๋ค.) ๋ฐ์ดํฐ๋ฅผ ํด์ฑํ๋ ๋ฑ์ ์ฑ๋ฅํฅ์ ๋ชฉ์ ์ผ๋ก๋ ์ค์ ๊ฐ์ฒด๋ก์ ์ ๊ทผํต์ ๊ฐ ์ด๋ฃจ์ด์ง๋ค.
์ค์ ๊ฐ์ฒด์ ์์ ๋ฐ๋์ ํ๋ก์ ๊ฐ์ฒด๊ฐ ๋จผ์ ํธ์ถ๋๋๋ก ํ๊ณ ๊ตฌํ์ ๋ฐ๋ผ ํ๋ก์ ๊ฐ์ฒด์์ ์ค์ ๊ฐ์ฒด๋ก ์์ฒญ์ ์ ๋ฌํ๋ค. ํ๋ก์ ๊ฐ์ฒด์์ ์ค์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๊ธฐ ์ํด ๋ฐ๋์ ์ค์ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๊ฐ๊ณ ์์ด์ผ ํ๋ค.
๊ฐ๋จํ๊ฒ ํ ์คํธ ์ฝ๋๋ฅผ ํตํด ํ๋ก์ ํจํด์ด ์ ์ฉ๋์ง ์์ ๊ฒฐ๊ณผ์ ์ ์ฉ๋ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด์.
[ ์ธํฐํ์ด์ค ์ ์ ]
public interface Subject {
String operation();
}
์ค์ ๊ฐ์ฒด๋ ํธ์ถ๋์ ๋ ๋ก๊ทธ๋ฅผ ์ฐ๊ณ 1์ด๊ฐ ์์ ์ ํ๋ค๊ณ ๊ฐ์ ํ๋ค.
[ ์ค์ ๊ฐ์ฒด์ ํด๋นํ๋ ๊ตฌํ ํด๋์ค ์ ์ ]
@Slf4j
public class RealSubject implements Subject {
@Override
public String operation() {
log.info("RealSubject ํธ์ถ");
sleep(1000);
return "data";
}
private void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
์ธํฐํ์ด์ค๋ฅผ ํตํด ๊ตฌํ์ฒด๋ฅผ ์ฃผ์ ๋ฐ์ ์ฌ์ฉํ Client ํด๋์ค๋ฅผ ์ ์ํ๋ค.
public class ProxyPatternClient {
private final Subject subject;
public ProxyPatternClient(Subject subject) {
this.subject = subject;
}
public void execute() {
subject.operation();
}
}
ํ
์คํธ
execute
๋ฅผ 5๋ฒ ํธ์ถํ๊ณ execute
๋ ์ค์ ๊ฐ์ฒด์ operation
์ ํธ์ถํ๊ธฐ ๋๋ฌธ์ 5์ด์ ์๊ฐ์ด ์์๋ ๊ฒ์ด๋ค.
@Test
void noProxyTest() {
RealSubject realSubject = new RealSubject();
ProxyPatternClient client = new ProxyPatternClient(realSubject);
client.execute();
client.execute();
client.execute();
client.execute();
client.execute();
}
ํ๋ก์ ํจํด์ด ์ ์ฉ๋์ง ์์ ๊ฒฝ์ฐ ์ค์ ๊ฐ์ฒด์ 1์ด๊ฐ ๊ฑธ๋ฆฌ๋ ์์ ์ ๋บด๋จน์ง ์๊ณ ๋ชจ๋ ์คํํ๋ค. ์ด์ ํ๋ก์ ํจํด์ ์ ์ฉํด์ ์ค์ ๊ฐ์ฒด์ ์์ ๊ฒฐ๊ณผ๋ฅผ ์บ์ฑํด์ ์ค์ ๊ฐ์ฒด๋ก์ ์ ๊ทผ์ ํต์ ํด๋ณด์.
ํ๋ก์ ์ญํ ์ ํ ํด๋์ค๋ฅผ ์ ์ํ๋ค. ์ค์ ๊ฐ์ฒด์ ๋์ผํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ ํ์์ฌ๋ถ์ ๋ฐ๋ผ ์ค์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๊ธฐ ์ํด ์ฃผ์
๋ฐ์์ผ ํ๋ค.
์ถ๊ฐ๋ก ์บ์ฑ์ ์ํ ํ๋๋ฅผ ํ๋ ์ถ๊ฐํ๋ค(cacheData
) ๋ง์ฝ cacheData
์ ๊ฐ์ด ์๋ค๋ฉด (์บ์ฑ๋ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด) ์ค์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๊ณ ๊ฐ์ด ์๋ค๋ฉด ์บ์ฑ๋ ๊ฐ์ ๊ทธ๋๋ก ๋ฐํํ๋ค.
@Slf4j
public class CacheProxy implements Subject {
private final RealSubject realSubject;
private String cacheData;
public CacheProxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public String operation() {
log.info("CacheProxy ํธ์ถ");
if (cacheData == null) {
cacheData = realSubject.operation();
}
return cacheData;
}
}
ํด๋ผ์ด์ธํธ๋ Subject
์ธํฐํ์ด์ค์๋ง ์์กดํ๋ฏ๋ก ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ฃผ์
ํด๋ ์๋ฌด๋ฐ ์ง์ฅ์ด ์๋ค. ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ฃผ์
ํ๊ณ ๋์ผํ ํ
์คํธ๋ฅผ ๋ฐ๋ณตํ๋ค.
ํ ์คํธ
@Test
void cacheProxyTest() {
CacheProxy cacheProxy = new CacheProxy(new RealSubject());
ProxyPatternClient client = new ProxyPatternClient(cacheProxy);
client.execute();
client.execute();
client.execute();
client.execute();
client.execute();
}
1์ด๋ ์๊ฐ์ด ์์๋๊ณ ๋ก๊ทธ๋ ์ค์ ๊ฐ์ฒด๋ ํ ๋ฒ๋ง ํธ์ถ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ธํ๋ฐ - ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ณ ๊ธํธ (๊น์ํ ๋)