观察者设计模式简介:
观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。观察者模式的实现和结构:实现观察者模式时要注意具体目标对象和具体观察者对象之间不能直接调用,否则将使两者之间紧密耦合起来,这违反了面向对象的设计原则。
- 抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 抽象观察者,它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者,实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
基于简单的交通灯系统分析观察者设计模式
交通信号灯系统:路口中的交通信号灯会根据预先的设定,周期性的变化颜色(红灯、绿灯),当交通信号灯的颜色变化是,向路口中的交通参与者(车辆、行人)发出通知,交通参与者(车辆、行人)接收到通知时,采取相应的的行动(通过路口或等待)。
- 事件源(被关察者)是交通灯。
- 事件是交通灯颜色的变化。
- 抽象的观察者是交通参与者,具体的观察者是行人和车辆。
- 观察者(车辆、行人)需要关注或监听交通灯的颜色,才能获得交通灯的信息,然后采取行动。
- 系统需要维护一个交通参与者列表,以便于在交通灯颜色变化时通知它们。同时也需要交通参与者能够接受通知。
其相关的UML类图如下:
关键代码如下:
定义TrafficLightEvent类,在其中注册具体观察者的监听器,同时使事件发生。
package observerPatterns; import java.util.*; public class TrafficLightEvent { public static void main(String[] args) { TrafficLight light=new TrafficLight(); //事件源 信号灯 light.addTrafficListener(new Cars()); //注册监听器 车辆 light.addTrafficListener(new People()); //注册监听器 行人 light.changeColor("Red"); System.out.println("********************"); light.changeColor("Green"); } }
定义TrafficLight类,它保存了观察者的List,增加/删除观察者的方法,以及当交通灯颜色变化时的处理和通知方法 。
package observerPatterns; import java.util.*; /* TrafficLight */ public class TrafficLight { private List<Traffic> listener; //监听器容器 public TrafficLight() { listener=new ArrayList<Traffic>(); } /* 事件源绑定监听器 */ public void addTrafficListener(Traffic cars) { listener.add(cars); }
public void removeTrafficListener(Traffic cars) {
listener.remove(cars);
} /* 事件触发器 */ public void changeColor(String color) { System.out.println("Traffic Light Color: "+ color); LightColor event=new LightColor(this, color); notifies(event); //通知注册在该事件源上的所有监听器 } /* 当事件发生时,调用事件处理方法 */ protected void notifies(LightColor e) { Traffic traffic = null; Iterator<Traffic> iterator=listener.iterator(); while(iterator.hasNext()) { traffic = iterator.next(); traffic.see(e); } } }
定义具体观察者 Cars类实现抽象观察者 Traffic 接口的 see方法。
package observerPatterns; import java.util.*; /* 抽象观察者类*/ public interface Traffic extends EventListener { public void see(LightColor e); }
package observerPatterns; /* 具体观察者类 车辆 */ public class Cars implements Traffic { public void see(LightColor e) { if("Red".equals(e.getColor())) { System.out.println("***Cars Stop"); } else { System.out.println("***Cars Pass"); } } }
观察者模式在这个应用场景的适用性:本场景对象间存在一对多关系,即:一个交通灯对应多个交通参与者,当交通灯颜色变化会影响交通参与者的行为,适用于观察者模式。
观察者设计模式后对系统架构和代码结构带来了哪些好处:观察者设计模式降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。使代码结构更清晰。
用到的多态机制:抽象观察者 Traffic接口 see()方法的多种不同的实现方式(具体观察者车辆、行人对see()方法有不同的实现方式)。
应用范例完整的源代码 : https://github.com/LiScott012/DesignPatterns.git