观察者模式 java 举例_观察者模式简单例子

观测者模式定义了对象之间的一对多依赖,当一个对象状态发生改变时,其依赖者便会收到通知并做相应的更新。其原则是:为交互对象之间松耦合。以松耦合方式在一系列对象之间沟通状态,我们可以独立复用主题(Subject)/可观测者(Observable)和观测者(Observer),即只要遵守接口规则改变其中一方并不会影响到另一方。这也是其主要的设计原则。下面是一个简单的气象站发送天气信息给布告板,然后布告板把天气信息显示在板上的例子。

首先先建立三个接口,主题(Subject)、观测者(Observer)和显示内容(DisplayElement),分别代表气象站、布告板信息接收和布告板信息显示。

/**

* 主题

*/

public interface Subject {

// 观察者注册

public void registerObserver(Observer o);

// 删除观察者

public void removeObserver(Observer o);

// 当主题有内容更新时调用,用于通知观察者

public void notifyObserver();

}1

2

3

4

5

6

7

8

9

10

11

/**

* 观察者

*/

public interface Observer {

// 当气象站观测的天气发生变化时,主题会把参数值传给观察者

public void update(float temp);

}1

2

3

4

5

6

7

/**

* 用于布告板显示

*/

public interface DisplayElement {

// 在显示布告板上显示的操作

public void display();

}1

2

3

4

5

6

7

接下来是实现气象站()和布告板()了。

/**

* 气象站实现主题,发布气象信息(气温)

*/

public class WeatherStation implements Subject{

private ArrayList observers;

private float temp;

public WeatherStation() {

// 加个ArrayList存放所有注册的Observer对象;

observers = new ArrayList<>();

}

@Override

public void registerObserver(Observer o) {

// 当新的观察者注册时添加进来

observers.add(o);

}

@Override

public void removeObserver(Observer o) {

// 当观察者取消注册时去除该观察者

int i = observers.indexOf(o);

if (i>=0) {

observers.remove(i);

}

}

@Override

public void notifyObserver() {

// 更新状态,调用Observer的update告诉观察者有新的信息

for (int i = 0; i < observers.size(); i++) {

Observer observer = (Observer) observers.get(i);

observer.update(temp);

}

}

/*

* 此方法用于气象站收到的数据,并且调用更新使数据实时通知给观察者

*/

public void setMeasurements(float temp){

this.temp = temp;

System.out.println("气象站测量的温度为:" + temp + "℃");

notifyObserver();

}

}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

/**

* 布告板上的状态显示

*/

public class ConditionDisplay implements Observer,DisplayElement{

private float temp;

private Subject weatherStation;

public ConditionDisplay(Subject weatherStation) {

// 构造时需要间主题/被观察者对象作为注册之用

this.weatherStation = weatherStation;

weatherStation.registerObserver(this);

}

@Override

public void display() {

// 将数据显示在布告板上

System.out.println("布告板显示当前温度为:" + temp + "℃");

}

@Override

public void update(float temp) {

// 接受来自主题/被观察者(气象站)的数据

this.temp = temp;

display();

}

}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

测试结果

/**

* 天气观测站

*/

public class WeatherObserver {

public static void main(String[] args) {

// 首先创建一个主题/被观察者

WeatherStation weatherStation = new WeatherStation();

// 创建观察者并将被观察者对象传入

ConditionDisplay conditionDisplay = new ConditionDisplay(weatherStation);

// 设置气象站模拟收到的气温数据

weatherStation.setMeasurements(25);

weatherStation.setMeasurements(24);

weatherStation.setMeasurements(23);

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

130855511_1_20180421083034988

JAVA内置观察者模式

可以使用java内置的观察者模式,这样就无需自己写Subject和Observer类了,在java.util包下继承的Observable和实现Observer类即可。其修改后的代码如下:

/**

* 继承java内置的被观察者,因此不再需要注册和删除了

*/

public class WeatherStationN extends Observable{

private float temperature;

public WeatherStationN() {

// 由于继承了Observable,它已经创建了一个Vector来存放Observer对象的容器,所以此处不用再建立ArrayList

}

/*

* 此方法用于气象站收到的数据,并且调用更新使数据实时通知给观察者

*/

public void setMeasurements(float temp){

this.temperature = temp;

System.out.println("气象站测量的温度为:" + temp + "℃");

// 更新强调用表示有状态更新

setChanged();

notifyObservers(temperature);

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

/**

* 实现java内置Observer接口

*/

public class ConditionDisplayN implements java.util.Observer,DisplayElement{

private Observable observable;

private float temp;

public ConditionDisplayN(Observable observable) {

// 构造器需要Observable作为参数

this.observable = observable;

observable.addObserver(this);

}

@Override

public void display() {

// 将数据显示在布告板上

System.out.println("布告板显示当前温度为:" + temp + "℃");

}

@Override

public void update(Observable o, Object arg) {

// 当被观察者有更新使触发

if (o instanceof WeatherStationN) {

this.temp = (float) arg;

display();

}

}

}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

测试运行结果

/**

* 天气观测站

*/

public class WeatherObserver {

public static void main(String[] args) {

// 首先创建一个主题/被观察者

WeatherStationN weatherStationN = new WeatherStationN();

// 创建观察者并将被观察者对象传入

ConditionDisplayN conditionDisplayN = new ConditionDisplayN(weatherStationN);

// 设置气象站模拟收到的气温数据

weatherStationN.setMeasurements(30);

weatherStationN.setMeasurements(25);

weatherStationN.setMeasurements(20);

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

130855511_2_20180421083035394

注意:

Observer是一个接口,而Observable是一个类,在使用时必须继承它,因此在继承Observable时就无法再继承其他超类了,因为Java毕竟不支持多重继承。且在Observable更新前,即notifyObservers()或notifyObservers(Object arg)前要先调用setChange()标记更新状态

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
观察者模式是一种设计模式,其中一个对象(称为主题)维护其依赖项(称为观察者),并在其状态发生变化时通知它们。下面是一个使用Python实现观察者模式简单示例: ```python class Subject: def __init__(self): self._observers = [] def attach(self, observer): if observer not in self._observers: self._observers.append(observer) def detach(self, observer): try: self._observers.remove(observer) except ValueError: pass def notify(self, modifier=None): for observer in self._observers: if modifier != observer: observer.update(self) class Data(Subject): def __init__(self, name=''): Subject.__init__(self) self.name = name self._data = 0 @property def data(self): return self._data @data.setter def data(self, value): self._data = value self.notify() class Observer: def __init__(self, name): self.name = name def update(self, subject): print(f'{self.name} has been notified with data {subject.data}') # 创建主题和观察者 data = Data('Data 1') observer1 = Observer('Observer 1') observer2 = Observer('Observer 2') # 将观察者附加到主题上 data.attach(observer1) data.attach(observer2) # 更新数据并通知观察者 data.data = 1 ``` 在上面的例子中,主题类`Subject`维护一个观察者列表,并提供了`attach`,`detach`和`notify`方法来添加、删除和通知观察者。`Data`类是主题的具体实现,每当其数据属性发生变化时,它会调用`notify`方法来通知其观察者。`Observer`类是观察者的抽象,每当主题通知其时,它会调用`update`方法来处理通知。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值