Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- spring boot
- deserializer
- yml
- 1*1000
- mysql not equal null
- createEntityGraph
- Protecle
- fractional seconds
- 오블완
- 운동해서 광명찾자
- @EntityListeners
- MSSQL
- +9:00
- NamedEntityGraph
- 티스토리챌린지
- mysql =
- getDateCellValue
- mysql equal null
- AuditingEntityListener
- load order
- https
- apatch poi
- pooled-lo
- RootGraph
- @CreateDate
- getEntityGraph
- MYSQL
- EmbeddedId
- 버전 문자열 비교
- sendFractionalSeconds
Archives
- Today
- Total
Hello
옵저버 패턴 본문
728x90
옵저버 패턴이란
- 한 객체의 상태가 바뀌면 의존하고 있는 모든 객체에 변경됨을 알려주는 일대다 의존성 관계를 정의한다.
- 주제(subject) / 옵저버(observer)로 표현한다. 두 관계는 느슨하게 결합되어있다.
- 주제는 옵저버가 인터페이스만 갖는다. 내부가 어떻게 구현되어있는지는 알지 않는다.
- 주제는 옵저버 인터페이스를 구현한 객체라면 새로 구상된 옵저버 클래스를 추가 할 수 있다.
- 서로 느슨한 결합이기 때문에 구현이 바뀌어도 주제 / 옵저버 구현만 되어있다면 영향을 미치지 않는다.
- 예) 유튜브 채널을 구독했다면 새로운 영상이 등록 되었을 때 알람을 보낸다. 채널을 구독한 사람들은 새로운 영상이 올라왔다는 알람을 받게 된다.
- 예) 집을 판매하기 위해 여러 부동산에 등록한다. 집을 판매하게 되면 부동산에 판매 완료 되었다는 연락을 해야한다.
- 주제가되는 객체가 데이터를 보내는 방식(push 방식), 옵저버에서 데이터를 가져가는 방식(pull 방식) 두 가지 방법으로 구분된다.
push방법을 활용한 예시 구현
Subject 인터페이스
public interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver(Video video);
}
Observer 인터페이스
public interface Observer {
void update(String name, Video video);
}
Subject 구현체
public class Channel implements Subject {
private final List<Observer> observers;
private String name;
private final List<Video> videos;
private final LocalDateTime createDate;
public Channel(String name) {
this.name = name;
observers = new ArrayList<>();
videos = new ArrayList<>();
createDate = LocalDateTime.now();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Video> getVideos() {
return videos;
}
public void addVideo(Video v){
videos.add(v);
notifyObserver(v);
}
public LocalDateTime getCreateDate() {
return createDate;
}
@Override
public void addObserver(Observer observer) {
this.observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
this.observers.remove(observer);
}
@Override
public void notifyObserver(Video video) {
for(Observer o : observers){
o.update(name, video);
}
}
}
Observer 구현체
- 채널 구독 해제를 위해 Subject를 필드로 갖고 removeChannel() 메소드를 작성했다.
public class SubscriberAlertObserver implements Observer {
private String name;
private Subject subject;
private final List<Video> noticeVideos;
public SubscriberAlertObserver(String name, Subject subject) {
this.name = name;
this.subject = subject;
subject.addObserver(this);
noticeVideos = new ArrayList<>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void removeChannel(){
this.subject.removeObserver(this);
}
@Override
public void update(String name, Video video) {
noticeVideos.add(video);
notice(name, video);
}
public void notice(String channelName, Video video) {
System.out.println(name + "님 " + channelName + "님이 " + video.getTitle() + "을 업로드 했습니다.");
System.out.println(video.getUploadDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
public void unfoldAlert() {
for (Video v : noticeVideos) {
System.out.println(v.getTitle());
System.out.println(v.getUploadDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
}
}
Video 클래스
public class Video {
private Integer no;
private String title;
private Boolean status;
private final LocalDateTime uploadDate;
public Video() {
uploadDate = LocalDateTime.now();
}
public Integer getNo() {
return no;
}
public void setNo(Integer no) {
this.no = no;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public LocalDateTime getUploadDate() {
return uploadDate;
}
}
Main
public static void main(String[] args) throws InterruptedException {
Channel channel = new Channel("죠르디TV");
SubscriberAlertObserver observerOne = new SubscriberAlertObserver("banana", channel);
SubscriberAlertObserver observerTwo = new SubscriberAlertObserver("mango", channel);
SubscriberAlertObserver observerThree = new SubscriberAlertObserver("orange", channel);
for (int i = 0; i < 5; i++) {
Video video = new Video();
video.setTitle((i + 1) + "번째 영상");
channel.addVideo(video);
Thread.sleep(3000L);
if (i == 3) {
observerThree.removeChannel();
}
}
}
자바 내장 옵저버 패턴 활용 예시 구현
728x90
'java > 디자인패턴' 카테고리의 다른 글
서킷 브레이커 패턴 (Circuit Breaker Pattern) (0) | 2023.10.16 |
---|