[Java] μ λ΅ ν¨ν΄ vs ν νλ¦Ώ λ©μλ ν¨ν΄ vs μν ν¨ν΄
νλ‘μ νΈμμ λ°νμ μ κ°μ²΄λ₯Ό λμ μΌλ‘ κ΄λ¦¬νκ³ , OCPλ₯Ό λ§μ‘±νλ μ½λλ‘ κ°μ νκΈ° μν΄ λμμΈ ν¨ν΄μ κ³ λ €ν κ³Όμ μ κΈ°λ‘νμλ€.
1. μ λ΅ ν¨ν΄ vs ν νλ¦Ώ λ©μλ ν¨ν΄
ν νλ¦Ώ λ©μλ ν¨ν΄μ μΆμ ν΄λμ€λ₯Ό μμνλ κ΅¬μ‘°λ‘ μ€κ³λμ΄ μλ€.
μμμ μμ ν΄λμ€μ νμ ν΄λμ€κ° κ°λ ₯νκ² λ°μ λμ΄ μμ΄ κ²°ν©λκ° λλ€. λν μμ κ΄κ³λ μ»΄νμΌ λ¨κ³μμ κ²°μ λκΈ° λλ¬Έμ μ€ν μ€ κ°μ²΄λ₯Ό λμ μ λ³κ²½νλ κ²μ΄ λΆκ°νλ€.
λ°νμ μ κ°μ²΄λ₯Ό λμ μΌλ‘ κ΄λ¦¬ν΄μΌ νλ κ²½μ°μλ μ΄λ¬ν μ΄μ λ‘ ν νλ¦Ώ λ©μλ ν¨ν΄μ μ ν©νμ§ μλ€.
2. μ λ΅ ν¨ν΄ vs μν ν¨ν΄
2-1. μ λ΅ ν¨ν΄
μ λ΅ ν¨ν΄μ νΉμ μμ μ μννλ λ°©λ²μ μΊ‘μννκ³ , μ΄ λ°©λ²λ€μ μνΈ κ΅μ²΄κ° κ°λ₯νλλ‘ ν ν¨ν΄μ΄λ€.
Context : λ³κ²½λμ§ μλ κ², μ λ΅ ν¨ν΄μ μ΄μ©νλ μν μ νκ³ DIλ₯Ό ν΅ν΄ λμ μΌλ‘ μ λ΅μ λ³κ²½νλ€.
Strategy : μΈλΆμμ λμΌν λ°©μμΌλ‘ μκ³ λ¦¬μ¦μ νΈμΆνλ λ°©λ²μ λͺ μν΄μ€λ€.
ConcreateStrategy : λ³κ²½λλ κ², Strategyμμ λͺ μν μκ³ λ¦¬μ¦μ ꡬνν ν΄λμ€
μμ μ½λ
κ°λ¨ν κ²°μ λ°©μ μ νμ μν μ λ΅ ν¨ν΄μ μ μ©ν μ½λμ΄λ€.
κ²°μ λ°©μμ μΉ΄λ, νκΈ λ κ°μ§ λ°©μμ΄ μλ€.
// μ λ΅ μΈν°νμ΄μ€
interface PaymentStrategy {
void pay(int amount);
}
// μ½ν¬λ¦¬νΈ μ λ΅ ν΄λμ€
class CreditCardStrategy implements PaymentStrategy {
private String cardNumber;
public CreditCardStrategy(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println("Paying " + amount + " using Credit Card.");
}
}
class PaypalStrategy implements PaymentStrategy {
private String emailId;
public PaypalStrategy(String emailId) {
this.emailId = emailId;
}
@Override
public void pay(int amount) {
System.out.println("Paying " + amount + " using Paypal.");
}
}
// 컨ν
μ€νΈ ν΄λμ€
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public ShoppingCart(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy; // μ λ΅μ μμ±μ μ£Όμ
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart(new CreditCardStrategy("1234-5678-9012-3456"));
cart.checkout(100);
cart = new ShoppingCart(new PaypalStrategy("myemail@example.com"));
cart.checkout(200);
}
}
2-2. μν ν¨ν΄
μν ν¨ν΄μ κ°μ²΄μ λ΄λΆ μνμ λ°λΌ νμλ₯Ό λ³κ²½ν΄μ£Όλ λμμΈ ν¨ν΄μ΄λ€.
Context : νμ¬ μνλ₯Ό λνλ΄λ μν κ°μ²΄λ₯Ό κ°μ§λ©°, μνμ λ°λΌ λ€λ₯Έ νλμ μννλ€. νΉμ μνμ λν νλμ μ§μ ꡬννμ§ μκ³ , νμ¬ μν κ°μ²΄μ μμνλ€.
State : λͺ¨λ ꡬ체μ μΈ μν ν΄λμ€λ€μ΄ ꡬνν΄μΌ νλ λ©μλλ€μ μ μνλ€. μ΄ λ©μλλ€μ μνμ λ°λΌ λ¬λΌμ§λ νλμ μ μνλ€.
ConcreateState: μν μΈν°νμ΄μ€λ₯Ό ꡬνν ν΄λμ€, κ° ν΄λμ€λ κ°μ²΄κ° νΉμ μνμ μμ λ μ΄λ»κ² νλν΄μΌ νλμ§λ₯Ό μ μνλ€. μλ₯Ό λ€μ΄, "μ΄λ¦Ό", "λ«ν", "μΌμμ μ§"λ±μ μνκ° μμ μ μμΌλ©° κ°κ°μ μνμ λν νλ λ‘μ§μ΄ μ΄ ν΄λμ€μ ꡬνλλ€.
μν κ°μ²΄λ
νμ¬ κ°μ²΄μ μνλ₯Ό λνλ΄λ κ°μ²΄λ₯Ό λ§νλ€. μν ν¨ν΄μμλ μ΄ μν κ°μ²΄κ° μμ€ν μ νλμ κ²°μ νλ€.
Context κ°μ²΄λ μν κ°μ²΄λ₯Ό μ¬μ©νμ¬ νμ¬ μνμ λ§λ νλμ μννκ² λλ€.
μ¦, μν κ°μ²΄λ Concreate ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό λ§νλ€. κ·Έλμ μν κ°μ²΄λ§λ€ λ€λ₯΄κ² ꡬνλμ΄ μλ νλμ΄ νμ¬ μν κ°μ²΄μ λ°λΌμ νΈμΆλλ κ²μ΄λ€.
(μλμ μμ μ½λμμ νμ¬ μ νΈλ± λΆλΉ(μν κ°μ²΄)μ΄ λΉ¨κ°λΆμΌ λ changeSignal()μ νΈμΆνλ©΄ μ νΈλ±μ΄ μ΄λ‘λΆμ΄ λκ³ , νμ¬ μν κ°μ²΄κ° λ ΈλλΆμΌλ changeSignal()μ νΈμΆνλ©΄ μ νΈλ±μ΄ λΉ¨κ°λΆμ΄ λλκ²μ²λΌ)
μμ μ½λ
κ°λ¨ν κ΅ν΅ μ νΈλ± μμ€ν μ μμ μ½λμ΄λ€.
μ νΈλ± λΆλΉμ λΉ¨κ°μμΌλλ λ ΉμμΌλ‘, λ ΉμμΌλλ λ ΈλμμΌλ‘, λ ΈλμμΌ λλ λΉ¨κ°μμΌλ‘ λ³κ²½λμ΄μΌ νλ€.
μ¬κΈ°μ μν κ°μ²΄λ μ νΈλ±μ νμ¬ μκΉμ λνλ΄λ©°, 컨ν μ€νΈ κ°μ²΄λ μ΄ μνμ λ°λΌ μ νΈλ±μ νλμ κ²°μ νλ€.
// μν μΈν°νμ΄μ€
public interface State {
void changeState(TrafficLight trafficLight);
}
// μ½ν¬λ¦¬νΈ μν ν΄λμ€
public class RedLightState implements State {
@Override
public void changeState(TrafficLight trafficLight) {
System.out.println("λΉ¨κ° λΆμμ μ΄λ‘ λΆλ‘ λ°λλλ€.");
trafficLight.setState(new GreenLightState());
}
}
public class GreenLightState implements State{
@Override
public void changeState(TrafficLight trafficLight) {
System.out.println("μ΄λ‘ λΆμμ λΉ¨κ° λΆλ‘ λ°λλλ€.");
trafficLight.setState(new RedLightState());
}
}
public class YellowLightState implements State{
@Override
public void changeState(TrafficLight trafficLight) {
System.out.println("λ
Έλ λΆμμ λΉ¨κ° λΆλ‘ λ°λλλ€.");
trafficLight.setState(new RedLightState());
}
}
// 컨ν
μ€νΈ ν΄λμ€
public class TrafficLight {
private State state;
public TrafficLight() {
this.state = new RedLightState();
}
public void changeSignal() {
state.changeState(this);
}
public void setState(State state) {
this.state = state;
}
}
public class Main {
public static void main(String[] args) {
TrafficLight trafficLight = new TrafficLight();
for (int i = 0; i < 6; i++) {
trafficLight.changeSignal();
}
}
}
μ€ν κ²°κ³Ό
2-3. μ 리
곡ν΅μ
β μΈν°νμ΄μ€λ₯Ό μ¬μ©νμ¬ Concreate classλ₯Ό μΊ‘μν νλ€.
β‘ Context classλ μν₯μ λ°μ§ μκ³ , λ³κ²½μ μ μ°ν λμ²κ° κ°λ₯νλ€. → OCPλ₯Ό λ§μ‘±νλ€.
μ°¨μ΄μ
β ν΄λΌμ΄μΈνΈκ° DIλ₯Ό ν΅ν΄ μνλ₯Ό μ£Όμ (μ€μ )ν΄μ£Όλ μ λ΅ ν¨ν΄κ³Όλ λ¬λ¦¬, μν ν¨ν΄μ μ£Όμ λ°λ κ²μ΄ μκ³ λ‘μ§μ λλ©΄μ νμ¬ κ°μ²΄ μνμ λ°λΌ νμλ₯Ό λ³κ²½νλ€.
[μ λ΅ ν¨ν΄]
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart(new CreditCardStrategy("1234-5678-9012-3456"));
cart.checkout(100);
cart = new ShoppingCart(new PaypalStrategy("myemail@example.com"));
cart.checkout(200);
}
}
μ λ΅ ν¨ν΄μ κ²½μ° main λ©μλμμ 컨ν μ€νΈ ν΄λμ€ κ°μ²΄λ₯Ό μμ±νκ³ μμ±μ μ£Όμ μ ν΅ν΄ μ λ΅μ λ³κ²½νλ€.
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public ShoppingCart(PaymentStrategy paymentStrategy) { // μμ±μ μ£Όμ
this.paymentStrategy = paymentStrategy;
}
public void checkout(int amount) {
paymentStrategy.pay(amount);
}
}
컨ν μ€νΈ ν΄λμ€λ μ λ΅ μΈν°νμ΄μ€ νμ μ μ λ΅ κ°μ²΄λ₯Ό μ£Όμ λ°λλ€.
[μν ν¨ν΄]
public class Main {
public static void main(String[] args) {
TrafficLight trafficLight = new TrafficLight();
for (int i = 0; i < 6; i++) {
trafficLight.changeSignal();
}
}
}
μν ν¨ν΄μ κ²½μ° main ν΄λμ€μμ κ°μ²΄λ₯Ό μ μΈνκ³ λ©μλ νΈμΆλ§ νλ€.
public class TrafficLight {
private State state; // μν μΈν°νμ΄μ€ νμ
μ λ³μ μ μΈ
public TrafficLight() {
this.state = new RedLightState();
}
public void changeSignal() {
state.changeState(this);
}
// setterλ‘ μν κ°μ²΄ λ³κ²½
public void setState(State state) {
this.state = state;
}
}
컨ν μ€νΈ ν΄λμ€μμ λ‘μ§μ λ°λΌ μν μΈν°νμ΄μ€ νμ μ μν κ°μ²΄λ€μ λ³κ²½νλ€.
public class YellowLightState implements State{
@Override
public void changeState(TrafficLight trafficLight) {
System.out.println("λ
Έλ λΆμμ λΉ¨κ° λΆλ‘ λ°λλλ€.");
trafficLight.setState(new RedLightState());
}
}
main λ©μλμμ νΈμΆν changeSignal() λ©μλ λ΄λΆλ₯Ό 보면 setState() λ©μλλ₯Ό ν΅ν΄ κ°μ²΄ μνμ λ°λΌ λ€λ₯Έ νλμ΄ νΈμΆλλ€.
β‘ μ λ΅ ν¨ν΄μ κ°μ²΄λ€μ΄ ν μ μλ νμμ λν΄ Concreate ν΄λμ€λ₯Ό λ§λ€κ³ μ μ¬ν νμλ€μ μΊ‘μννκ³ , μν ν¨ν΄μ μνμ λ°λ₯Έ νλμ μΊ‘μννλ€.
βοΈ DIλ₯Ό ν΅ν μ λ΅μ λ°λ₯Έ κ°μ²΄λ₯Ό λμ μΌλ‘ λ³κ²½νλ μμ μ΄ νμνλ νλ‘μ νΈμμλ μ λ΅ ν¨ν΄μ μ μ©νμλ€.