ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Observer 패턴 - Poll을 Push로!!
    CS/디자인패턴 2023. 12. 25. 23:56

     

     

    목차

    1. 빠른 요약
    2. 옵저버 패턴 3장 그림 요약
    3. 시나리오
    4. 코드

     

     

    Poll을 Push로!!

     

    프로그래밍을 하다보면 a객체의 상태에 의존하여 b객체가 변경되어야하는 경우들이 생긴다. 보통은 b객체에서 a에게 '너의 상태가 변경되었니?' 물어보며 상태변화를 확인한다.(Poll)

     

    하지만 언제 변할지 모르는 상태를 확인하기위해 몇 번을 얼마의 간격으로 물어봐야할까?

    이런 문제를 a객체가 변경이 발생했을 때 '나 변했다~'를 b객체에게 알려주는 형태를 사용하면서 해결할 수 있다.(push)

     

    이런 컨셉을 구현한 방법이 옵저버 패턴이다.
    이번 글과 다음 글을 통해서 구체적인 예시를 확인해보자~

     

     

    그림으로 보면?

    • A객체의 변화를 B객체가 알고 싶을 때

     

    • A객체의 변화를 여러개의 객체가 알고 싶을 때

     

     

    유튜브 알림설정을 해보자

    내가 구독하고 있는 유튜버가 새로운 영상을 올리기를 학수고대하고 있다. 매일 한 시간 간격으로 유튜버의 채널에 들어가보지만 일주일째 새로운 동영상은 올라오지 않고 있다..

     

    뒤늦게 발견한 알림버튼.. 이제 나는 알림설정을 하고, 더 이상 한 시간 단위로 유튜버의 채널에 들어가지 않기로 하였다.

    알림 설정한 것이 잊혀질 쯤, 새로운 영상이 업데이트 되었다는 알림을 받았다!

     

     

    코드로 보자

    코드를 나열하기 전에 간단히 구성을 보여주는 이미지를 보자

     

     

     

    실제 구현 코드

    RunApp.java
    package notification;
    
    import java.util.*;
    
    public class RunApp {
    
    	public static void main(String[] args) {
    		Scanner scanner = new Scanner(System.in);
    		Service service = new Service();
    		
    		List<User> users = new ArrayList<>();
    		
    		users.add(new User(true, "유저1"));
    		users.add(new User(false, "유저2"));
    		users.add(new User(true, "유저3"));
    	
    		
    		users.forEach((user) -> {
    			if (user.getWantNotified()) {
    				service.register(user);
    			}
    		});
    		
    		System.out.println("1: 동영상 업로드, 2: 업로드 x");
    		int shouldUpload = scanner.nextInt();
    				
    		if (shouldUpload == 1) {			
    			service.uploadNewVideo(); // 모든 등록된 유저에게 알림
    		}
    
    		System.out.println("0 ~ 2까지의 유저 번호 입력");
    		int idx = scanner.nextInt();
    		
    		service.unregister(users.get(idx));
    		service.uploadNewVideo();
    		
    		scanner.close();
    	}
    
    }

     

    Notificatioin.java
    package notification;
    
    import java.util.*;
    
    public class NotificationManager implements Observable<User> {
    	List<User> users;
    	
    	NotificationManager() {
    		this.users = new ArrayList<>();
    	}
    	
    	@Override
    	public void register(User user) {
    		users.add(user);
    	}
    	
    	@Override
    	public void unregister(User user) {
    		users.remove(user);
    	}
    	
    	@Override
    	public void broadcast(String msg) {
    		users.forEach((user) -> user.update(msg));
    	}
    }

     

    Service.java
    public class Service {
    	NotificationManager manager = new NotificationManager();
    	
    	void register(User user) {
    		manager.register(user);
    	}
    	
    	void unregister(User user) {
    		manager.unregister(user);
    	}
    	
    	void uploadNewVideo() {
    		manager.broadcast("새로운 비디오가 업데이트 되었습니다!");
    	}
    }

     

    User.java
    package notification;
    
    public class User implements Observer {
    	private boolean wantNotified;
    	private String name;
    	
    	User(boolean want, String name) {
    		this.wantNotified = want;
    		this.name = name;
    	}
    	
    	boolean getWantNotified() {
    		return wantNotified;
    	}
    	
    	@Override
    	public void update(String msg) {
    		System.out.printf("%s 님! %s \n", this.name, msg);
    	}
    }

     

     

     

     


    [이미지 출처]
    https://www.flaticon.com/kr/free-icon/alarm-clock_4832081 (글 대표 이미지)

     

     

     

     

Designed by Tistory.