๋์์ธ ํจํด์ ๊ณต๋ถํ ๋ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ํด๋น ๋์์ธ ํจํด์ด ์ด๋ค ๊ฒฝ์ฐ์ ์ฌ์ฉ๋์ด์ผ ํ๋ ์ง๋ฅผ ์์์ผ ํ๋ ๊ฒ์ด๋ค. ํ ์คํธ ์ฝ๋๋ก ๋์์ธ ํจํด์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์๋๋ผ๋ ๋์์ธ ํจํด์ ์๋๋ฅผ ์ ๋๋ก ํ์ ํ์ง ๋ชปํ๊ณ ์ค์ ์ ํฉํ ์ฌ์ฉ์ฒ๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด ์๋ฏธ๊ฐ ์๋ค. ์ฌ์ฉ์ฒ๋ฅผ ์ ๋๋ก ์๊ณ ๊ฐ๋จํ๊ฒ ๊ตฌํํด๋ณด์.
ํ๋ก์ ํจํด์ ์ค์ ๊ฐ์ฒด๋ก์ ์ ๊ทผ์ ํต์ ํ๋๋ฐ ์ฌ์ฉ๋๋ค.
์ ๊ทผ์ ํต์ ํ๋ค๋ ๊ฒ์ด ๋ณด์์ ์ธ ๊ฒ๋ง์ ์๋ฏธํ๋ ๊ฒ์ ์๋๋ค. (๋น์ฐํ ๋จ์ํ ์ ๊ทผํต์ ์๋ ์ฌ์ฉํ ์ ์๋ค.) ๋ฐ์ดํฐ๋ฅผ ํด์ฑํ๋ ๋ฑ์ ์ฑ๋ฅํฅ์ ๋ชฉ์ ์ผ๋ก๋ ์ค์ ๊ฐ์ฒด๋ก์ ์ ๊ทผํต์ ๊ฐ ์ด๋ฃจ์ด์ง๋ค.
์ค์ ๊ฐ์ฒด์ ์์ ๋ฐ๋์ ํ๋ก์ ๊ฐ์ฒด๊ฐ ๋จผ์ ํธ์ถ๋๋๋ก ํ๊ณ ๊ตฌํ์ ๋ฐ๋ผ ํ๋ก์ ๊ฐ์ฒด์์ ์ค์ ๊ฐ์ฒด๋ก ์์ฒญ์ ์ ๋ฌํ๋ค. ํ๋ก์ ๊ฐ์ฒด์์ ์ค์ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๊ธฐ ์ํด ๋ฐ๋์ ์ค์ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๊ฐ๊ณ ์์ด์ผ ํ๋ค.
๊ฐ๋จํ๊ฒ ํ ์คํธ ์ฝ๋๋ฅผ ํตํด ํ๋ก์ ํจํด์ด ์ ์ฉ๋์ง ์์ ๊ฒฐ๊ณผ์ ์ ์ฉ๋ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด์.
[ ์ธํฐํ์ด์ค ์ ์ ]
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์ด๋ ์๊ฐ์ด ์์๋๊ณ ๋ก๊ทธ๋ ์ค์ ๊ฐ์ฒด๋ ํ ๋ฒ๋ง ํธ์ถ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ธํ๋ฐ - ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ณ ๊ธํธ (๊น์ํ ๋)