Hongbo

Oct 15, 2023

浅谈观察者模式

写在前头:希望你了解到的不仅是模式,而学会用OOP的眼光分析问题,解决问题

关键字:一对多,变化通知 、push&pull

描述: 观察者模式、订阅发布模式

原则: 好莱坞原则

示例: 图形编程、股票涨跌、订阅发布

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//1. 股票涨跌

//观察者接口
public interface Observer {
public void update(Stock stock, Object arg);
}

//散户
public class PrivateInvestor implements Observer {

@Override
public void update(Stock stock, Object arg) {
System.out.println("PrivateInvestor: Current price:" +stock.getPrice()+", Sell 100!");
System.out.println("State:"+arg);
}
}

//投资机构
public class InstitutionInvestor implements Observer {

@Override
public void update(Stock stock, Object arg) {

System.out.println("InstitutionInvestor: Current price:" +stock.getPrice()+", Sell 1000!");
System.out.println("State:"+arg);
}
}

//股票类
public class Stock {
//所有关注股票的观察者的集合
private List<Observer> observers= new ArrayList<Observer>();
//股票价格
private double price;

public double getPrice() {
return this.price;
}

public Stock(double price) {
this.price=price;
}
//通知所有观察者
public void notifyAllObservers() {
for(Observer observer: observers) {
observer.update(this,"all ok!");
}
}

//新增观察者
public void addObserver(Observer observer) {
observers.add(observer);
}
//移除观察者
public void removeObserver(Object observer) {
observers.remove(observer);
}
//改变价格
public void setPrice(double p) {
this.price=p;

if(this.price>80 || this.price<10) {
notifyAllObservers();
}
}

//test
public static void main(String[] args) {
Stock stock=new Stock(10);

stock.addObserver(new PrivateInvestor());
stock.addObserver(new InstitutionInvestor());

stock.setPrice(100);
stock.setPrice(4);
}
}

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//2. 订阅发布

//主体类
public interface Subject {

public void update(Object arg);
public void addObserver(Subject s);
}

public class User implements Subject {

private List<Subject> observers= new ArrayList<>();
private String name="none";
private String info="Hello World!";

//构造函数
public User(String name) {
this.name=name;
}
public User(Subject s, String name) {
s.addObserver(this);
this.name=name;
}

@Override
public void addObserver(Subject s) {
observers.add(s);
}


public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
notifyAllObservers();
}

@Override
public void update(Object arg) {
System.out.println(arg+" to "+this.name);
}


public void notifyAllObservers() {

for(Subject o: observers) {
o.update(this.name+": "+this.getInfo());
}

}

public static void main(String[] args) {
User user1=new User("User1");

//user2 观察 user1
User user2=new User(user1, "User2");
user1.setInfo("I have updated!");

//user2添加观察者user3, user3 观察user2
user2.addObserver(new User("User3"));
user2.setInfo("I got mistake!");

for(int i=0; i<10; i++) {
user1.addObserver(new User("user0"+i));
}

user1.setInfo("I have the second time updated!");
}

}
OLDER > < NEWER