기타/디자인패턴
행위패턴 > 옵저버 *
ssseung
2021. 2. 12. 15:39
객체의 상태변화에 따라 다른 객체의 상태도 연동되도록 일대다 객체 의존 관계를 구성
데이터 변경이 발생했을 경우 상대 클래스나 객체에 의존하지 않으면서 데이터 변경을 통보하고자 할 때 유용
Subject 와 Observer 는 서로를 변수로 가지고 있는다.
Observer 는 생성자에서 받은 subject 를 registerObserver(this)로 등록해두고,
Subject 에서는 자신에게 변화가 있을 때 Observer notify 를 호출한다.
push방식, poll 방식으로 구현할 수 있다.
Product 에 상태에 변화가 생기면 Observer 에서 이를 감지하고 ProductDisplay 에게 알려준다.
public class ObTest {
public static void main(String[] args) {
// 하나의 product 와 하나의 observer 를 가지는 경우
Product pd = new Product("productA", 300);
Observer pob = new ProductObserver(pd);
pd.stock(100);
pd.release(200);
// 여러개의 observer 에 하나의 product 를 등록
Observer pob2 = new ProductObserver(pd);
pd.release(50);
//product 여러개가 있는 list 를 observer 에 등록
Products list = new Products();
Observer listObserver= new ProductObserver(list);
list.add(pd);
}
}
public interface Subject {
public void registerObserver(Observer productObserver);
public void removeObserver(Observer ob);
public void notifyObserver();
}
public class Product implements Subject {
String name;
int quantity;
List<Observer> observers;
public Product(String name, int quantity) {
this.name = name;
this.quantity = quantity;
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer ob) {
observers.add(ob);
notifyObserver();
}
@Override
public void removeObserver(Observer ob) {
observers.remove(ob);
}
@Override
public void notifyObserver() {
for(Observer ob: observers) {
ob.getData();
}
}
public void stock(int quantity) {
this.quantity += quantity;
notifyObserver();
}
public void release(int quantity) {
if(this.quantity >= quantity) {
this.quantity -= quantity;
}
notifyObserver();
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return super.equals(obj);
}
@Override
public String toString() {
return "Product [ name= " + this.name + ", quantity= " + this.quantity + " ]";
}
}
public interface Observer {
public void getData();
public void updateData(Subject subject);
}
public class ProductObserver implements Observer{
private Subject subject;
private ProductDisplay display;
public ProductObserver(Subject subject) {
this.subject = subject;
this.display = new ProductDisplay(subject);
this.subject.registerObserver(this);
}
@Override
public void getData() {
display();
}
@Override
public void updateData(Subject subject) {
this.subject = subject;
display();
}
private void display() {
System.out.println("ProductObserver display = " + "this=" + this.toString()
+ ", subject= " + this.subject);
this.display.display();
}
}
public class ProductDisplay {
Subject product ;
public ProductDisplay(Subject product ) {
this.product = product;
}
public void display() {
System.out.println("ProductDisplay = [ " + product + " ]");
}
}
headFirst Design Patterns 참조
반응형