π μ΄ κΈμ μΈνλ°μμ μ 곡νλ "μ€νλ§ ν΅μ¬ μ리 - κ³ κΈνΈ" κ°μλ₯Ό μκ°νλ©΄μ μ 리ν λ΄μ©μ λ°νμΌλ‘ μμ±ν κΈμ λλ€.
μ μ μ½λ μμ μΌλ‘ κ³΅ν΅ λ‘μ§μ μμ±ν μ μκΈ° μν΄ κ³ μλ λ©μλ ν¨ν΄μ μκ°νλ€.
κ³΅ν΅ λ‘μ§ (λ‘κ·Έ μΆμ κΈ°) μꡬμ¬ν
* λͺ¨λ PUBLIC λ©μλμ νΈμΆκ³Ό μλ΅ μ 보λ₯Ό λ‘κ·Έλ‘ μΆλ ₯
* μ ν리μΌμ΄μ μ νλ¦μ λ³κ²½νλ©΄ μλ¨ - λ‘κ·Έλ₯Ό λ¨κΈ΄λ€κ³ ν΄μ λΉμ¦λμ€ λ‘μ§μ λμμ μν₯μ μ£Όλ©΄ μλ¨
* λ©μλ νΈμΆμ κ±Έλ¦° μκ°
* μ μ νλ¦κ³Ό μμΈ νλ¦ κ΅¬λΆ - μμΈ λ°μ μ μμΈ μ λ³΄κ° λ¨μμΌ ν¨
* λ©μλ νΈμΆμ κΉμ΄ νν
* HTTP μμ²μ ꡬλΆ
* HTTP μμ² λ¨μλ‘ νΉμ ID λ₯Ό λ¨κ²¨μ μ΄λ€ HTTP μμ²μμ μμλ κ²μΈμ§ λͺ ννκ² κ΅¬λΆμ΄ κ°λ₯ν΄μΌ ν¨
* νΈλμμ ID (DBνΈλμμ X)
β» ν νλ¦Ώ λ©μλ ν¨ν΄
ν
νλ¦Ώ λ©μλ ν¨ν΄μ μ¬μ©νμ¬ κ°μΈ νλ‘μ νΈμ μμ²λ³ μ€ν μκ°μ μΆμ νλ LogTrace λ₯Ό κ°λ°νλ€.
μ΄ν΄λκ° μ΄λμ λ μλ€κ³ μκ°νμ¬ κ΄λ ¨νμ¬ λ°λ‘ κΈ°λ‘ν΄λμ§ μκ² λ€. κΈ μ°Έκ³ λ°λ
β» μ λ΅ν¨ν΄
ν νλ¦Ώ λ©μλ ν¨ν΄ < μ λ΅ν¨ν΄μΈ μ΄μ : μ λ΅ν¨ν΄μ ν νλ¦Ώ λ©μλ ν¨ν΄κ³Ό λΉμ·ν μν μ νλ©΄μ μμμ λ¨μ μ μ κ±°ν μ μλ λμμΈ ν¨ν΄μ΄λ€.
- ν νλ¦Ώ λ©μλ ν¨ν΄ : λΆλͺ¨ ν΄λμ€μ λ³νμ§ μλ λΆλΆλ€μ λͺ¨μλκ³ , λ³νλ λΆλΆμ μμ ν΄λμ€μ λμ΄μ μμμ μ¬μ©ν΄μ λ¬Έμ λ₯Ό ν΄κ²°νλ€.
- μ λ΅ ν¨ν΄ : λ³νμ§ μλ λΆλΆμ Context λΌλ κ³³μ λκ³ , λ³νλ λΆλΆμ Strategy λΌλ μΈν°νμ΄μ€λ₯Ό λ§λ€κ³ ν΄λΉ μΈν°νμ΄μ€λ₯Ό ꡬννλλ‘ ν΄μ λ¬Έμ λ₯Ό ν΄κ²°νλ€. μμμ΄ μλλΌ μμμΌλ‘ λ¬Έμ λ₯Ό ν΄κ²°νλ€. κ±°λν λ¬Έλ§₯μ΄ μ‘΄μ¬νκ³ , μ λ΅μ΄ μ‘°κΈμ© λ°λλ κ².
βΆ μ λ΅ν¨ν΄V1 μ ꡬμ±
Strategy : λ³νλ λΆλΆμ λͺ¨μλμ μΈν°νμ΄μ€
public interface Strategy {
void call();
}
@Slf4j
public class StrategyLogic1 implements Strategy {
@Override
public void call() {
log.info("λΉμ¦λμ€ λ‘μ§1 μ€ν");
}
}
ContextV1 : λ³νμ§ μλ λ‘μ§μ κ°μ§κ³ μλ ν νλ¦Ώ μν + Strategy λ₯Ό λ΄λΆνλλ‘ λκ³ μμ(μ΄κ±Έ ν΅ν΄ Strategy λ₯Ό μ£Όμ λ°μ)
public class ContextV1 {
private Strategy strategy;
public ContextV1(Strategy strategy) {
this.strategy = strategy;
}
public void execute() {
long startTime = System.currentTimeMillis();
//λΉμ¦λμ€ λ‘μ§ μ€ν
strategy.call(); //μμ
//λΉμ¦λμ€ λ‘μ§ μ’
λ£
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime={}", resultTime);
}
}
- Strategy νλμ λ³νλ λΆλΆμΈ Strategy μ ꡬν체λ₯Ό μ£Όμ νλ©΄ λλ€.
- Context μ½λλ Strategy μ ꡬν체λ₯Ό λ³κ²½νκ±°λ μλ‘ λ§λ€μ΄λ Context μ½λμλ μν₯μ μ£Όμ§ μλλ€. μ΄μ²λΌ μ λ΅ ν¨ν΄μ ν΅μ¬μ Context λ Strategy μΈν°νμ΄μ€μλ§ μμ‘΄νλ€λ μ μ΄λ€.
- λ³νμ§ μλ λ‘μ§μ κ°κ³ μλ ν νλ¦Ώ μν μ νλ μ½λλ₯Ό μ λ΅ν¨ν΄μμλ 컨ν μ€νΈλΌκ³ νλ€.
- Context λ ν¬κ² λ³νμ§ μμ§λ§, κ·Έ λ¬Έλ§₯μμμ Strategy λ₯Ό ν΅ν΄ μ λ΅μ΄ λ³κ²½λλ€κ³ μκ°νλ©΄ λ¨.
βΆ μ λ΅ν¨ν΄V1 μ μ¬μ©
@Test
void strategyV1() {
StrategyLogic1 strategyLogic1 = new StrategyLogic1();
ContextV1 context1 = new ContextV1(strategyLogic1);
context1.execute();
StrategyLogic2 strategyLogic2 = new StrategyLogic2();
ContextV1 context2 = new ContextV1(strategyLogic2);
context2.execute();
}
Strategy μ ꡬνμ²΄μΈ StrategyLogic1 μ μΈμ€ν΄μ€λ₯Ό μμ±νμ¬ ContextV1μ μ£Όμ νλ€.
μ΄λ κ² ν΄μ Context μμ μνλ μ λ΅μ μ£Όμ νλ€.
μ΄ λ°©λ²μ μ 쑰립, ν μ€ν λ°©λ²μ μ ν©νλ€. Context λ΄λΆ νλμ Strategy λ₯Ό λκ³ μ¬μ©νκ³ μκΈ° λλ¬Έμ λμ νλ² μ‘°λ¦½νκ³ λλ©΄ κ·Έ μ΄νλ‘λ Context λ₯Ό μ€ννκΈ°λ§ νλ©΄ λλ€. κ·Έλ¬λ λ¨μ μ νλ² μ‘°λ¦½ν μ΄ν μ λ΅μ λ³κ²½νκΈ°κ° λ²κ±°λ‘λ€λ μ μ΄λ€.
μ₯ ? Setter λ₯Ό μ 곡ν΄μ Strategy λ₯Ό λ겨 λ°μ μ 곡νλ©΄ λμ§ μλ ? ) λ§λ€. κ·Έλ μ§λ§ Context λ₯Ό μ±κΈν€μΌλ‘ μ¬μ©ν λλ λμμ± μ΄μλ± κ³ λ €ν μ μ΄ λ§λ€. κ·Έλμ μ λ΅μ μ€μκ°μΌλ‘ λ³κ²½ν΄μΌνλ©΄ μμ²λΌ Context λ₯Ό νλ λ μμ±νκ³ κ·Έκ³³μ λ€λ₯Έ Strategy λ₯Ό μ£Όμ νλ κ²μ΄ λμ μ μλ€.
μ μμλ Context μ Strategy λΌλ λ΄λΆ νλλ₯Ό λκ³ , μ£Όμ ν΄μ μ¬μ©νλ€.
μ΄λ²μλ μ§μ νλΌλ―Έν°λ‘ μ λ¬ν΄μ μ¬μ©ν΄λ³΄μ !
βΆ μ λ΅ν¨ν΄ V2μ ꡬμ±
ContextV2 : λ³νμ§ μλ λ‘μ§μ λͺ¨μλλ ν νλ¦Ώ μν + Strategy λ₯Ό νλΌλ―Έν°λ‘ μ λ¬ λ°μ
@Slf4j
public class ContextV2 {
public void execute(Strategy strategy) {
long startTime = System.currentTimeMillis();
//λΉμ¦λμ€ λ‘μ§ μ€ν
strategy.call(); //μμ
//λΉμ¦λμ€ λ‘μ§ μ’
λ£
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime={}", resultTime);
}
}
@Slf4j
public class StrategyLogic2 implements Strategy {
@Override
public void call() {
log.info("λΉμ¦λμ€ λ‘μ§2 μ€ν");
}
}
βΆ μ λ΅ν¨ν΄ V2μ μ¬μ©
@Test
void strategyV1() {
ContextV2 context = new ContextV2();
context.execute(new StrategyLogic1());
context.execute(new StrategyLogic2());
}
μ΄λ κ² νλ©΄ Context λ₯Ό μ€ννλ μμ μ μνλ Strategy λ₯Ό μ λ¬ν μ μλ€. (V1μμλ κ°μ²΄λ₯Ό μμ±νλ μμ μ Strategy λ₯Ό μ£Όμ ν΄μΌ νλ€. λ°λΌμ μ΄μ λ°©μκ³Ό λΉκ΅ν΄μ λ μ μ°νκ² λ³κ²½ κ°λ₯νλ€.)
β» μ½λ°± ν¨ν΄
μ½λ°±(callback) : λ€λ₯Έ μ½λμ μΈμλ‘μ λ겨주λ μ€νκ°λ₯ν μ½λ. (νλ§λλ‘ ν¨μκ° μΈμλ‘ λμ΄μ€λ κ²)
μλ° μΈμ΄μμ μ€ν κ°λ₯ν μ½λλ₯Ό μΈμλ‘ λκΈ°λ €λ©΄ κ°μ²΄κ° νμνλ€. μ΅κ·Όμλ μ£Όλ‘ λλ€λ₯Ό μ¬μ©νλ€.
ν νλ¦Ώ μ½λ°± ν¨ν΄
- ContextV2μ κ°μ λ°©μμ μ λ΅ν¨ν΄μ ν νλ¦Ώ μ½λ°± ν¨ν΄μ΄λΌκ³ νλ€.
- μ€νλ§μμ μ΄λ¦μ XxxTemplate κ° μλ€λ©΄ ν
νλ¦Ώ μ½λ°± ν¨ν΄μΌλ‘ λ§λ€μ΄μ Έ μλ€ μκ°νλ©΄ λλ€.
- μ: JdbcTemplate
- Template : μ λ΅ ν¨ν΄μ Context μ κ°λ€. λ³νμ§ μλ λΆλΆμ λͺ¨μλλ ν νλ¦Ώμ΄λ€.
- Callback : μ λ΅ ν¨ν΄μ Strategy μ κ°λ€. λ³νλ λΆλΆμ λͺ¨μλλ€.
βΆ ν νλ¦Ώ μ½λ°± ν¨ν΄ V1 ꡬμ±
Callback μΈν°νμ΄μ€
public interface Callback {
void call();
}
@Slf4j
public class TimeLogTemplate {
public void execute(Callback callback) {
long startTime = System.currentTimeMillis();
//λΉμ¦λμ€ λ‘μ§ μ€ν
callback.call(); //μμ
//λΉμ¦λμ€ λ‘μ§ μ’
λ£
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime={}", resultTime);
}
}
βΆ ν νλ¦Ώ μ½λ°± ν¨ν΄ V1 μ¬μ©
void callbackV1() {
TimeLogTemplate template = new TimeLogTemplate();
template.execute(new Callback() { //μ΅λͺ
λ΄λΆ ν΄λμ€
public void call() {
log.info("λΉμ¦λμ€ λ‘μ§1 μ€ν");
}
});
- Callback μΈν°νμ΄μ€λ₯Ό ꡬνμ²΄λ‘ λ§λ€λ©΄μ λμμ μ€ν
- μ½λ°±μ μ¬μ©ν κ²½μ° μ΅λͺ λ΄λΆ ν΄λμ€λ λλ€λ₯Ό μ¬μ©νλ κ²μ΄ νΈλ¦¬νλ€. (λ¬Όλ‘ λ³λμ ν΄λμ€λ₯Ό λ§λ€μ΄μ μ λ¬ν΄λ λ¨)
- ν νλ¦Ώ λ©μλ ν¨ν΄ : λ€νμ±κ³Ό μμμ μ¬μ©νμ¬ λ¬Έμ λ₯Ό ν΄κ²°νλ€. λΆλͺ¨κ° λ°λλ©΄ μμμ΄ μν₯μ λ°μ
- μ λ΅ ν¨ν΄ : μμμ μ¬μ©ν΄ λ¬Έμ λ₯Ό ν΄κ²°νλ€. Context μ Strategy λ‘ κ΅¬μ±λλ€. Strategy Interface λ₯Ό ꡬνν΄ μ λ΅μ λ³κ²½νλ€.
- ν νλ¦Ώ μ½λ°± ν¨ν΄ : μ λ΅ ν¨ν΄μΈλ° Strategy λ₯Ό μΈμλ‘ μ λ¬λ°κ² νλ κ²κ³Ό λμΌνλ€. μ΄λ μ©μ΄λ Template κ³Ό callback μ΄λΌκ³ μ¬μ©νλ€. μ΅λͺ λ΄λΆ ν΄λμ€ νΉμ λλ€λ₯Ό μ¬μ©νλ κ²μ΄ κΆμ₯λλ€.
μ μ μ½λλ‘ κ³΅ν΅ λ‘μ§μ μμ±νκΈ° μν΄ κ³ μλ λμμΈ ν¨ν΄μ μμλ΄€λ€.
κ·Έλ¬λ μ΄ λ°©λ²λ€μ κ²°κ΅ κ³΅ν΅ λ‘μ§μ μ μ©νκΈ° μν΄ μλ³Έ μ½λλ₯Ό μμ ν΄μΌνλ€λ λ¨μ μ΄ μλ€.