π‘ μ΅μλ²(Observer) ν¨ν΄μ΄λ?
κ°μ²΄μ λ°μνλ λͺ¨λ μ΄λ²€νΈμ λνμ¬ μ΅μλ²(κ΄μ°°μ)λ€μκ² μλ¦¬κ³ , μ΅μλ²λ€μ μλ¦Όμ λ°μ μ‘°μΉλ₯Ό μ·¨νλ νλ ν¨ν΄μ λλ€. μΌλͺ ꡬλ 맀컀λμ¦μ ꡬνν ν¨ν΄μΌλ‘, λ€λ₯Έ λμμΈ ν¨ν΄λ€κ³Ό λ€λ₯΄κ² μΌλλ€ μμ‘΄μ±μ κ°μ§λλ€.
μ΅μλ² ν¨ν΄μ μμλ‘λ MVC ν¨ν΄(Model, View, Controller)μ΄ μμ΅λλ€. MVCμ Modelκ³Ό Viewμ κ΄κ³λ Observer ν¨ν΄μ Subject μν κ³Ό Observer μν μ κ΄κ³μ λμλ©λλ€. μ¦, νλμ Modelμ 볡μμ Viewκ° λμν©λλ€.
π‘ ν΄λμ€ λ€μ΄μ΄κ·Έλ¨μΌλ‘ λ³Έ μ΅μλ² ν¨ν΄
- Publisher(Subject) : κ΄μ°° λΉνλ λμμΌλ‘, Subscriber(Observer)λ€μ 리μ€νΈλ‘ κ°κ³ μλ€. (Aggregation)
- μ μ΄λ²€νΈκ° λ°μνλ©΄ Publisherλ ꡬλ 리μ€νΈ κ° κ°μ²΄μ μλ¦Ό λ©μλλ₯Ό νΈμΆνλ€. (Update)
- Subscriber(Observer) Interface : ꡬλ μλ€μ λ¬Άλ μΈν°νμ΄μ€λ‘, λλΆλΆ λ¨μΌ update λ©μλλ‘ κ΅¬μ±λμ΄ μλ€.
- Concrete Subscriber(Observer) : κ΄μ°°μ μννλ κ°μ²΄λ‘, Subjectκ° λ°νν μλ¦ΌμΌλ‘ νμ¬ μνλ₯Ό μ·¨λνκ³ , μ΄μ λν μ 보λ₯Ό μ²λ¦¬νλ€. μ΄ κ°μ²΄λ€μ Subscriber Interfaceμμ μ μλ update λ©μλλ₯Ό μμλ°λλ€.
- Client : Publisherμ Subscriberλ₯Ό λ³λλ‘ μμ±ν ν λ±λ‘νλ€.
π‘ μ΅μλ² ν¨ν΄ ꡬν
- Subject(Publisher)
interface ISubject {
void registerObserver(IObserver o);
void removeObserver(IObserver o);
void notifyObserver();
}
class ConcreteSubject implements ISubject {
// κ΄μ°°μλ€μ λ±λ‘νμ¬ λ΄λ 리μ€νΈ
List<IObserver> observers = new ArrayList<>();
// κ΄μ°°μλ₯Ό 리μ€νΈμ λ±λ‘
@Override
public void registerObserver(IObserver o) {
observers.add(o);
System.out.println(o + " ꡬλ
μλ£");
}
// κ΄μ°°μλ₯Ό 리μ€νΈμ μ κ±°
@Override
public void removeObserver(IObserver o) {
observers.remove(o);
System.out.println(o + " ꡬλ
μ·¨μ");
}
// κ΄μ°°μμκ² μ΄λ²€νΈ μ‘μ
@Override
public void notifyObserver() {
for(IObserver o : observers) { // κ΄μ°°μ 리μ€νΈλ₯Ό μννλ©°
o.update(); // μμ
}
}
}
- Observer(Subscriber)
interface IObserver {
void update();
}
class ObserverA implements IObserver {
public void update() {
System.out.println("ObserverA νν
μ΄λ²€νΈ μλ¦Όμ΄ μμ΅λλ€.");
}
public String toString() { return "ObserverA"; }
}
class ObserverB implements IObserver {
public void update() {
System.out.println("ObserverB νν
μ΄λ²€νΈ μλ¦Όμ΄ μμ΅λλ€.");
}
public String toString() { return "ObserverB"; }
}
- Client(main)
public class Client {
public static void main(String[] args) {
// λ°νμ λ±λ‘
ISubject publisher = new ConcreteSubject();
// λ°νμλ₯Ό ꡬλ
ν κ΄μ°°μλ€ λ¦¬μ€νΈλ‘ λ±λ‘
IObserver o1 = new ObserverA();
IObserver o2 = new ObserverB();
publisher.registerObserver(o1);
publisher.registerObserver(o2);
// κ΄μ°°μμκ² μ΄λ²€νΈ μ ν
publisher.notifyObserver();
// ObserverBκ° κ΅¬λ
μ·¨μ
publisher.removeObserver(o2);
// ObserverA νν
λ§ μ΄λ²€νΈ μ ν
publisher.notifyObserver();
}
}
π‘ λ§λ¬΄λ¦¬
μ΅μλ² ν¨ν΄μ
- λμ κ°μ²΄μ μνκ° λ³κ²½λ λλ§λ€ λ€λ₯Έ κ°μ²΄μ λμμ νΈλ¦¬κ±°ν΄μΌ ν λ
- μΌλΆ κ°μ²΄λ€μ΄ μ νλ μκ° λμ λλ νΉμ κ²½μ°μλ§ λ€λ₯Έ κ°μ²΄λ€μ κ΄μ°°ν΄μΌ ν λ
μ μ¬μ©ν μ μμ΅λλ€.
Subjectμ μν λ³κ²½μ μ£ΌκΈ°μ μΌλ‘ μ‘°ννμ§ μκ³ λ μλμΌλ‘ κ°μ§ν μ μκ³ , λ°νμμ μ½λλ₯Ό λ³κ²½νμ§ μκ³ λ μ ꡬλ μ ν΄λμ€λ₯Ό λμ ν μ μμ΄ κ°λ°© νμ μμΉ(OCP)μ μ€μν©λλ€. λ°νμμ κ°μ²΄ κ°μ κ΄κ³λ₯Ό νμ±ν μ μμΌλ©°, κ°μ²΄ κ°μ κ΄κ³λ₯Ό λμ¨νκ² μ μ§ν μ μμ΅λλ€.
κ·Έλ¬λ, μλ¦Ό μμλ₯Ό μ μ΄ν μ μκ³ , μ΅μλ² ν¨ν΄μ μμ£Ό ꡬμ±νλ©΄ μ½λ 볡μ‘λκ° μ¦κ°ν μ μμΌλ©°, λ€μμ κ°μ²΄λ₯Ό μ΅μλ²λ‘ λ±λ‘ν ν ν΄μ§νμ§ μλλ€λ©΄ λ©λͺ¨λ¦¬ λμκ° λ°μν μ μλ€λ λ¨μ μ΄ μμ΅λλ€.