νλ‘μ(Proxy)λ μμ΄λ‘ λ리μλ₯Ό λ»νλ€. νλ‘μ ν¨ν΄μ ꡬ쑰 ν¨ν΄ μ€ νλλ‘ ν΄λΌμ΄μΈνΈκ° μ§μ μλ²μ μμ²νλ κ²μ΄ μλλΌ μ΄λ€ λ리μ κ°μ²΄λ₯Ό ν΅ν΄ κ°μ μ μΌλ‘ μλ²μ μμ²νλ ν¨ν΄μ λ§νλ€. μ¬κΈ°μ ν΄λΌμ΄μΈνΈλ μλ’°μΈμ μλ―Ένλ©° μλ²λ μλΉμ€λ μνμ μ 곡νλ μ¬λ λλ 물건μ λ»νλ€. μ¦ μΉμμλ ν΄λΌμ΄μΈνΈλ μ¬μ©μκ° μ μν μΉ λΈλΌμ°μ κ° λκ³ , μλ²λ ν΄λΌμ΄μΈνΈμ μμ²μ μ²λ¦¬νλ€.
1. κ°μ νλ‘μ(Virtual Proxy) - μ€μ κ°μ²΄μ ν¬κΈ°κ° κ±°λν΄μ μμ±κ³Ό μ κ·Όμ λΉμ©μ΄ λ§μ΄ λλ κ²½μ° νμν μμ μλ§ κ°μ²΄λ₯Ό μμ±νλλ‘ μ§μ°λ μ΄κΈ°νλ₯Ό μνν μ μλ€.
2. λ³΄νΈ νλ‘μ(Protection Proxy) - μ€μ κ°μ²΄μ λν μ κ·Όμ ν΅μ νμ¬ νΉμ κΆνμ κ°μ§ μ¬μ©μ(ν΄λΌμ΄μΈνΈ)λ§μ΄ μ κ·Όνλλ‘ μ μ΄ν μ μλ€.
μλ²μ νλ‘μλ κ°μ κ°μ²΄λ₯Ό μ¬μ©ν΄μΌνλ€. ν΄λΌμ΄μΈνΈκ° μλ²μκ² μμ²ν κ²μΈμ§ νλ‘μμ μμ²ν κ²μΈμ§ λͺ°λΌμΌ(λ체 κ°λ₯ν΄μΌλ§) νλ‘μ κ°μ²΄λΌκ³ ν μ μλ€. `Client -> Server`μμ `Server -> Proxy`λ‘ μμ‘΄ κ΄κ³κ° λ°λλλΌλ, ν΄λΌμ΄μΈνΈλ κ·Έ μ½λλ₯Ό μ ν λ³κ²½νμ§ μμλ λλ€. μ¬μ§μ΄ λ³κ²½ μ¬μ€μ‘°μ°¨ λͺ¨λ₯Ό μ μλ€. ν΄λΌμ΄μΈνΈλ μλ² μΈν°νμ΄μ€λ§μ μμ‘΄νκ³ μμΌλ©° μλ²μ νλ‘μκ° μλ² μΈν°νμ΄μ€μ μμ‘΄νλ€. μ΄ λ΄μ©μ΄ DI(Dependency Injection: μμ‘΄μ± μ£Όμ )μ ν΅μ¬μ΄λ€.
π μ κ·Ό μ μ΄λ₯Ό μν΄ νλ‘μλ₯Ό μ¬μ©ν μμ
ν΄λΌμ΄μΈνΈκ° μμ² μ μ μ μ ν μ 보λ₯Ό μ 곡νκ³ μ΄ μ νμ String κ°μΌλ‘ "user" λλ "admin"μΌλ‘ μ£Όμ΄μ§λ€κ³ κ°μ νμ λ, "user"λΌλ©΄ DB μ κ·Όμ μ ννκ³ "admin"μ΄λΌλ©΄ DB μ κ·Όμ νμ©νλ μꡬμ¬νμ΄ μλ€λ©΄ μ½λλ λ€μκ³Ό κ°μ΄ μμ±λ μ μλ€.
public class ClientExample {
public static void main(String[] args) {
// ν΄λΌμ΄μΈνΈλ‘λΆν° λ°μ μ 보μ λ°λΌ μ μ μ ν μ€μ
// μ¬κΈ°μλ κ·Έλ₯ "admin"μΌλ‘ μ μΈνμ§λ§, μΉμ΄λΌλ©΄ request.getParameter("level") λ±μΌλ‘ λ°μμ¬ μ μμ
String username = "admin"; // λλ "user"
// ν©ν 리λ₯Ό ν΅ν΄ μ μ ν νλ‘μ μμ±
UserServiceProxyFactory proxyFactory;
if ("admin".equals(username)) {
proxyFactory = new AdminUserServiceProxyFactory();
} else {
// "user"μΈ κ²½μ° DB μ κ·Όμ΄ λΆκ°λ₯ν νλ‘μ μμ±
proxyFactory = new RegularUserServiceProxyFactory();
}
// μμ±λ νλ‘μλ‘ UserControllerλ₯Ό μμ±
UserController userController = new UserController(proxyFactory.createServiceProxy());
// ν΄λΌμ΄μΈνΈ μμ² μ²λ¦¬
userController.handleRequest();
}
}
μΆμ ν©ν 리 ν¨ν΄, κ·Έλ¦¬κ³ ν©ν 리 λ©μλ ν¨ν΄ λν μ μ©λμ΄ μλ κ²μ λ³Ό μ μλ€.
κ° κ°μ²΄μ μμ κ³μΈ΅λλ λ€μκ³Ό κ°λ€.
μΆμ ν©ν 리 ν¨ν΄κ³Ό ν©ν 리 λ©μλ ν¨ν΄ λν μ μ©λ κ²μ νμΈν μ μλ€.`UserServiceProxy`λ λ΄λΆμ `UserServiceImpl`μ κ°μ§κ³ μμΌλ©° νμν λλ§λ€ μ€μ κ°μ²΄μ μ κ·Όνλ€. λ°μ½λ μ΄ν° ν¨ν΄κ³Ό μ μ¬νμ§λ§ μ κ·Ό μ μ΄λ₯Ό λͺ©μ μΌλ‘ νλ‘μλ₯Ό μ¬μ©νλ€λ μ μμ ꡬλΆλ μ μλ€.
π μΊμ±
ν λ²μ μ‘°ν μ΄νμ λ³νμ§ μλ λ°μ΄ν°μ κ²½μ°, μ²μ μ‘°ννμ λ κ·Έ λ°μ΄ν°λ₯Ό 보κ΄ν΄λμλ€κ° μ¬μμ² μ 보κ΄λ λ°μ΄ν°λ₯Ό μ¬μ©νλ€λ©΄ λΆνμν μμ λλΉλ₯Ό κ°μμν¬ μ μλ€. μ΄λ₯Ό μΊμ±μ΄λΌκ³ νλ€.
import java.util.HashMap;
import java.util.Map;
// μ€μ κ°μ²΄μ μΈν°νμ΄μ€
interface Component {
String operation();
}
// μ€μ κ°μ²΄
class RealComponent implements Component {
public String operation() {
System.out.println("μ€μ κ°μ²΄κ° λ©μλ μ€ν");
return "result";
}
}
// νλ‘μ
class CachingProxy implements Component {
private RealComponent realComponent;
private Map<String, String> cache;
public CachingProxy() {
this.cache = new HashMap<>();
}
public String operation() {
if (realComponent == null) {
realComponent = new RealComponent();
}
// if μΊμ νμΈνκ³ λ°μ΄ν°κ° μμΌλ©΄ μΊμμ μ μ₯ν΄λμλ λ°μ΄ν° λ°ν
// else μΊμμ λ°μ΄ν°κ° μμΌλ©΄ μ€μ κ°μ²΄ νΈμΆ
if (cache.containsKey("result") {
System.out.println("νλ‘μκ° μΊμ± λ°μ΄ν° λ°ν");
return cache.get("result");
} else {
// μ€μ κ°μ²΄ νΈμΆ
String result = realComponent.operation();
// κ²°κ³Όλ₯Ό μΊμμ μ μ₯
cache.put("result", result);
return result;
}
}
}
// ν΄λΌμ΄μΈνΈ μ½λ
public class Client {
public static void main(String[] args) {
// ν΄λΌμ΄μΈνΈ μ½λλ νλ‘μλ₯Ό ν΅ν΄ μ€μ κ°μ²΄μ κ°μ μ μΌλ‘ μ κ·Ό
CachingProxy proxy = new CachingProxy();
System.out.println(proxy.operation()); // μ²μ νΈμΆμ μ€μ κ°μ²΄μμ μ°μ° μν
System.out.println(proxy.operation()); // λ λ²μ§Έ νΈμΆλΆν°λ νλ‘μμμ μΊμ λ°μ΄ν° λ°ν
}
}
// μΆλ ₯
// μ€μ κ°μ²΄κ° λ©μλ μ€ν
// result
// νλ‘μκ° μΊμ± λ°μ΄ν° λ°ν
// result
ν΄λΌμ΄μΈνΈκ° μ²μ μμ²νμ λλ§ μ€μ κ°μ²΄μ μ κ·Όνκ³ , κ·Έ μ΄νλ‘λ μΊμμ μ μ₯λ λ°μ΄ν°λ₯Ό μ¬μ©νλ€. μ€ν μκ°μ ν¬κ² μ€μ¬ μ±λ₯ ν₯μμ λμμ΄ λλ€.
μΊμ±μ μ¬μ©ν λλ λ°λμ λ€μμ μ£Όμμ μ κ³ λ €νλ€.
1. μΊμ± λ°μ΄ν°λ νμ μ€μ λ°μ΄ν°μ μΌμΉν΄μΌ νλ€. λ°μ΄ν°κ° κ°±μ λλ€λ©΄ μΊμ± λ°μ΄ν° λν κ°±μ λμ΄μΌ νλ€. μ€μ λ°μ΄ν°μ μΊμ± λ°μ΄ν°μ μΌκ΄μ±μ΄ μ μ§λμ§ μμΌλ©΄ μ λ’°μ±μ΄ κΉ¨μ§ μ μλ€. μ΄λ₯Ό λ°©μ§νκΈ° μν΄ μ μ ν μΊμ± λ§λ£ κΈ°κ°μ μ€μ νλ€.
2. μΊμ± λ°μ΄ν°λ λ©λͺ¨λ¦¬λ₯Ό μ¬μ©νλ―λ‘ μ£Όμνλ€. λ무 λ§μ μΊμ± λ°μ΄ν°λ₯Ό μ¬μ©νλ€λ©΄ μ€νλ € μ±λ₯ μ νλ₯Ό μΌμΌν¬ μ μλ€.
3. λ©ν° μ°λ λ νκ²½μμ λκΈ°ν λ¬Έμ κ° λ°μν μ μμΌλ―λ‘ μ£Όμνλ€.
4. μΊμ± λ°μ΄ν°μ 보μμ μ£Όμνλ€.
π Spring MVC λ΄ νλ‘μ ν¨ν΄ μ μ©
MVC ν¨ν΄μμ`Service`μ ꡬνμ²΄κ° `Repository`μ ꡬν체λ₯Ό μ§μ μ°Έμ‘°νλ λμ `ServiceImpl`μ μ°Έμ‘°νλ `ServiceProxy`κ° `RepositoryImpl`μ μ°Έμ‘°νλ `RepositoryProxy`λ₯Ό νΈμΆνλλ‘ μ€κ³νλ€λ©΄ Service κ³μΈ΅μ΄ λ°μ΄ν° μ κ·Ό κ³μΈ΅κ³Ό μμ ν λΆλ¦¬λλ―λ‘ λμ λμ¨νκ² κ²°ν©λ μ μλ€. λ°μ΄ν° μ κ·Ό κ³μΈ΅μ΄ λ³κ²½λμ λ (μλ‘μ΄ λ°μ΄ν° μμ€λ DB μ κ·Ό λ°©μμ΄ λμ λλλΌλ) μ€μ κ°μ²΄μΈ `RepositoryImpl`μ μ°Έμ‘°νλ `RepositoryProxy`μ μ½λλ§ λ³κ²½νλ©΄ λλ€. μ΄λ κ°μ²΄ μ§ν₯ 5λ μμΉ μ€ νλμΈ OCP(κ°λ°© νμ μμΉ: Open-closed Principle)μ λΆν©νλ€.
1. νλ‘μμ μ€μ κ°μ²΄λ νλμ μΈν°νμ΄μ€λ₯Ό ꡬννλ€.
1-1. μ€μ κ°μ²΄μ μΈν°νμ΄μ€κ° μ‘΄μ¬νμ§ μμ κ²½μ° νλ‘μ κ°μ²΄κ° μ€μ κ°μ²΄λ₯Ό μμνλ€. ν΄λΌμ΄μΈνΈ μμ±μμ λ§€κ° λ³μ νμ μ΄ μ€μ κ°μ²΄λΌλ©΄ λ€νμ±μ μ μ©μ λ°μ μ°Έμ‘°νλ κ°μ²΄κ° μ€μ κ°μ²΄ λλ νλ‘μ κ°μ²΄λ‘ λ³κ²½λλλΌλ ν΄λΌμ΄μΈνΈμ μ½λλ₯Ό μμ ν νμκ° μλ€. λ¨, μΈν°νμ΄μ€ κΈ°λ°μ νλ‘μκ° μμμ μ μ½μ΄ μκΈ° λλ¬Έμ λ μ 리ν μ μλ€.
2. νλ‘μλ λ΄λΆμ μ€μ κ°μ²΄λ₯Ό κ°μ§κ³ μλ€.
3. μ€μ κ°μ²΄ λμ νλ‘μ κ°μ²΄λ₯Ό μ€νλ§ λΉμΌλ‘ λ±λ‘νλ κ²½μ° μ€νλ§ μ»¨ν μ΄λμλ νλ‘μ κ°μ²΄λ§ λ±λ‘λλ€. νλ‘μ κ°μ²΄κ° λ΄λΆμμ μ€μ κ°μ²΄λ₯Ό μ°Έμ‘°νκ³ μλ€.
νλ‘μ κ°μ²΄: μ€νλ§ μ»¨ν μ΄λ, JVM Heap λ©λͺ¨λ¦¬μ μ¬λΌκ°
μ€μ κ°μ²΄: JVM Heap λ©λͺ¨λ¦¬μλ§ μ¬λΌκ°(μ€νλ§ μ»¨ν μ΄λκ° κ΄λ¦¬νμ§ μλλ€.)
π νλ‘μ ν¨ν΄ vs λ°μ½λ μ΄ν° ν¨ν΄
νλ‘μ ν¨ν΄κ³Ό λ°μ½λ μ΄ν° ν¨ν΄μ λ§€μ° μ μ¬νλ€. λμ νλ‘μμ μμ± λͺ©μ μΌλ‘ ꡬλΆλ μ μλ€. νλ‘μ ν¨ν΄μ μ κ·Ό μ μ΄κ° λͺ©μ μ΄λ©° λ°μ½λ μ΄ν° ν¨ν΄μ μλ‘μ΄ κΈ°λ₯μ μΆκ°κ° λͺ©μ μ΄λ€. νλ‘μ ν¨ν΄κ³Ό λ°μ½λ μ΄ν° ν¨ν΄ λ λ€ νλ‘μ, μ¦ λ리μλ₯Ό μ¬μ©νμ§λ§ μλκ° λ€λ₯΄λ€λ κ²μ΄ μ€μνλ€. νλ‘μ ν¨ν΄μ νλ‘μλ₯Ό μ¬μ©νλ λμμΈ ν¨ν΄ μ€ νλλ‘ μ΄λ¦μ΄ νλ‘μ ν¨ν΄μΌ λΏ λ°λμ νλ‘μ ν¨ν΄λ§μ΄ νλ‘μλ₯Ό μ¬μ©νλ κ²μ μλλ€.
νλ‘μ ν¨ν΄: μ κ·Ό μ μ΄
λ°μ½λ μ΄ν° ν¨ν΄: λΆκ° κΈ°λ₯ μΆκ°
β¨ μ₯μ
1. μ€μ κ°μ²΄κ° κ±°λν κ²½μ° νμν μμ μλ§ κ°μ²΄λ₯Ό μμ±νκΈ° λλ¬Έμ λΉμ©μ μλ μ μλ€. = μ§μ°λ μ΄κΈ°ν(Lazy initialization)
2. νλ‘μ κ°μ²΄μμ μΊμ±μ μ¬μ©ν κ²½μ° μμ²λ§λ€ κ±°λν κ°μ²΄μ μ κ·Όνμ§ μκ³ λ λ°μ΄ν°λ₯Ό λ°νν μ μμ΄ λΉ λ₯Έ μλ΅μ΄ κ°λ₯νλ€.
3. ν΄λΌμ΄μΈνΈ μ½λλ₯Ό ν¬κ² λ³κ²½νμ§ μκ³ μ κ·Ό μ μ΄ μꡬ μ¬νμ λ°μν μ μλ€.
π λ¨μ
1. νλ‘μ κ°μ²΄μ μΆκ°λ‘ ν΄λμ€μ μμ΄ λμ΄λλ©΄ μ½λκ° λ³΅μ‘ν΄μ§ μ μλ€.
2. νλ‘μ κ°μ²΄κ° μΆκ°μ μΈ μμ μ μννκΈ° λλ¬Έμ μ±λ₯ μ νκ° λ°μν μ μλ€.
3. μ§μ°λ μ΄κΈ°νμ μ₯μ μ κ³§ μ€μ κ°μ²΄μ μμ± μμ μ΄ λΆλͺ νν΄μ§λ€λ λ¨μ μ μλ―Ένλ€. μ΄λ€ κ²½μ°μλ μ΄κΈ°ν μμ μ΄ λΆλͺ ν΄μΌ νλ μν©μ΄ μ‘΄μ¬νλ―λ‘ μ κ³ λ €νμ¬ ν¨ν΄μ μ μ©ν΄μΌνλ€.
[λμμΈ ν¨ν΄] λ°μ½λ μ΄ν°(Decorator) ν¨ν΄
'CS > λμμΈ ν¨ν΄' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[λμμΈ ν¨ν΄] μν(State) ν¨ν΄ (0) | 2024.01.17 |
---|---|
[λμμΈ ν¨ν΄] λ°μ½λ μ΄ν°(Decorator) ν¨ν΄ (0) | 2024.01.13 |
[λμμΈ ν¨ν΄] μ±κΈν€(Singleton) ν¨ν΄ (0) | 2024.01.10 |
[λμμΈ ν¨ν΄] ν©ν 리 λ©μλ(Factory Method) ν¨ν΄ (0) | 2024.01.10 |