티스토리 뷰

출처 링크: https://www.youtube.com/watch?v=_BpmfnqjgzQ 

관련 도서: http://www.yes24.com/Product/Goods/1778966

 

Head First Design Patterns - YES24

정말 쿨~ 하게 배우는 디자인 패턴 학습법다른 사람들이 뭔가를 만들어 놓았고, 누구든 마음대로 사용해도 되는 게 있다면 굳이 고생해서 똑같은 걸 만들어 써야 할 필요는 없을 것이다. 소프트

www.yes24.com

 

아래 내용은 제 100% 주관적인 내용입니다. 아래 내용이 잘못 되어도 어떠한 책임도 지지 않겠습니다.

비판적으로 내용을 받아들여주세요.

 

디자인 패턴 UML

UML을 보면 꽤 복잡해 보인다.

 

하지만 사실 복잡하지 않다. 천천히 뜯어 보어보자.

 

우선 위 그림에서 아래 그림1, 그림2 처럼 나눠서 봐야한다.

그림 1

 

그림 2

그림1과 그림2는 단지 아래 그림처럼 나눈것 뿐이다.

그림 1의 UML은 NewMachine에서 어떠한 변경이 있어서 notify를 실행하면 Observer의 구현체(EventSubscriber)는 변경을 감지할 수있다. 하지만 어떠한 내용이 바뀌었는지 알 수 없다. 단지 감지만 할 뿐이다.

 

반면에 그림 2의 UML은 notify를 실행하면 Observer의 구현체(AnnualSubscriber)는 변경을 감지한다. 그리고 Publish의 구현체(NewsMachine)을 가지고 있으므로 변경된 내용을 알 수 있다. 

 

이 둘의 차이를 구분하지 않고 책에서 하나만 소개하는 경우가 많은지 그림 2번에 대한 질문이 스택오버플로우에 자주 올라온다고 한다. 질문 내용 대부분이 "디자인 패턴은 설계를 추상화하는데 의미가 있는데.. 왜 구현체단(NewsMachine, AnnualSubscriber)에서 컴포지션 관계가 있나요?"

이유는 변경 내용을 알기 위해서이다. 위의 UML들에서는 AnuualSubscriber가 getTitle()과 getNews()를 통해서 필요한 정보를 얻을 수 있을 것이다. 

 

 

따라서 상황에 맞게 감지만 필요한지 아니면 감지하고 어떤 내용이 변경되었는지도 알아야 하는지에 따라 선택하면 된다.

 

 

 

디자인 패턴 Sample Code

코드 출처 : https://flowarc.tistory.com/entry/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-%EC%98%B5%EC%A0%80%EB%B2%84-%ED%8C%A8%ED%84%B4Observer-Pattern

public interface Observer { 
	public void update(String title, String news); 
}

 

public interface Publisher {
    public void add(Observer observer);
    public void delete(Observer observer);
    public void notifyObserver();
}

 

public class NewsMachine implements Publisher {
    private ArrayList < Observer > observers;
    private String title;
    private String news;
    public NewsMachine() {
        observers = new ArrayList < > ();
    }
    @Override public void add(Observer observer) {
        observers.add(observer);
    }
    @Override public void delete(Observer observer) {
        int index = observers.indexOf(observer);
        observers.remove(index);
    }
    @Override public void notifyObserver() {
        for (Observer observer: observers) {
            observer.update(title, news);
        }
    }
    public void setNewsInfo(String title, String news) {
        this.title = title;
        this.news = news;
        notifyObserver();
    }
    public String getTitle() {
        return title;
    }
    public String getNews() {
        return news;
    }
}

 

public class AnnualSubscriber implements Observer {
    private String newsString;
    private Publisher publisher;
    public AnnualSubscriber(Publisher publisher) {
        this.publisher = publisher;
        publisher.add(this);
    }
    @Override public void update(String title, String news) {
        this.newsString = title + " \n -------- \n " + news;
        display();
    }
    private void display() {
        System.out.println("\n\n오늘의 뉴스\n============================\n\n" + newsString);
    }
}

 

public class EventSubscriber implements Observer {
    private String newsString;
    private Publisher publisher;
    public EventSubscriber(Publisher publisher) {
        this.publisher = publisher;
        publisher.add(this);
    }
    @Override public void update(String title, String news) {
        newsString = title + "\n------------------------------------\n" + news;
        display();
    }
    public void display() {
        System.out.println("\n\n=== 이벤트 유저 ===");
        System.out.println("\n\n" + newsString);
    }
}

 

public class EventSubscriber implements Observer {
    private String newsString;
    private Publisher publisher;
    public EventSubscriber(Publisher publisher) {
        this.publisher = publisher;
        publisher.add(this);
    }
    @Override public void update(String title, String news) {
        newsString = title + "\n------------------------------------\n" + news;
        display();
    }
    public void display() {
        System.out.println("\n\n=== 이벤트 유저 ===");
        System.out.println("\n\n" + newsString);
    }
}

 

내가 느낀 이 패턴의 특징

 

 

 

 

구조는 스트래티지 패턴과도 비슷하다.

하지만 큰 차이점은 메시지를 받게되는 지점에서 메시지를 보낸 쪽의 정보를 알고 싶어하는지 여부일 것 같다.

모든 Observer패턴이 항상 그런건 아니지만 위의 그림 1은 Observer 패턴이라고 할 수 있지만 동시에 스트래티지 패턴이라고도 할 수 있다. 하지만 그림 2에서처럼 Observer 인터페이스의 구현체들에서 Publiser의 정보를 가져갈 수 있도록 함으로써 정보를 다른 곳으로 옮길 수 있게한다.

(여기에서는 notify를 통해서 Observer의 update()를 호출하여 메시지를 받는다. 스트래티지 패턴도 역할을 위임받은 곳으로 메소드가 호출되는 방향과 구조가 똑같다.)

 

 

 

어떨 때 이 패턴을 사용하면 좋을까?

 

1 : N 관계이고 역할을 위임받을 쪽에서 정보를 알아야 할 때!

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함