设计模式(13)---观察者模式
观察者模式 Observer(行为型模式)
1.概述
观察者模式:定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
例1:开车的司机作为观察者,路上的红绿灯作为观察目标,当红绿灯的颜色状态发生改变时,司机得到通知,并更新自己的行为。
例2:一个能够显示商品信息的页面,当数据库的关于商品的信息发生改变时,页面的信息也会发生相应的改变。
2.结构图
3.代码
代码简述:玩魔兽争霸这类游戏时,队友遭到敌人攻击,地图上会有红色标记提示,其他队友作为观察者,更新自己的状态,前去支援。
1 import java.util.ArrayList; 2 3 /* 4 * 抽象观察目标类 5 */ 6 public abstract class Subject { 7 8 //存储所有具体的观察者 9 protected ArrayList<Observer> players = new ArrayList<Observer>(); 10 public Subject() { 11 12 } 13 14 //加入方法 15 public void attach(Observer obs) { 16 System.out.println(obs.getName() + "加入"); 17 players.add(obs); 18 } 19 20 //退出方法 21 public void detach(Observer obs) { 22 System.out.println(obs.getName() + "退出"); 23 players.remove(obs); 24 } 25 26 //声明抽象通知方法 27 public abstract void notify(String name); 28 29 }
1 /* 2 * 具体观察目标类 3 */ 4 public class ConcreteSubject extends Subject { 5 6 public ConcreteSubject() { 7 // TODO Auto-generated constructor stub 8 } 9 10 @Override 11 public void notify(String name) { 12 //遍历观察者集合,调用每一个观察者(自己除外)的更新方法 13 for(Object obs : players) { 14 if (!((Observer)obs).getName().equalsIgnoreCase(name)) { 15 ((Observer)obs).update(); 16 } 17 } 18 19 } 20 21 }
1 /* 2 * 抽象观察者 3 */ 4 interface Observer { 5 6 public String getName(); 7 public void setName(String name); 8 public void update(); 9 public void beAttacked(Subject s); 10 11 }
1 /* 2 * 具体观察者 3 */ 4 public class ConcreteObserver implements Observer { 5 6 private String name; 7 public ConcreteObserver(String name) { 8 this.name = name; 9 } 10 @Override 11 public String getName() { 12 return this.name; 13 } 14 @Override 15 public void setName(String name) { 16 this.name = name; 17 18 } 19 20 //更新自己的状态 21 @Override 22 public void update() { 23 System.out.println(name+"前去支援"); 24 25 } 26 27 @Override 28 public void beAttacked(Subject s) { 29 System.out.println(name+"遭到攻击"); 30 s.notify(this.name); 31 32 } 33 34 }
1 public class Test { 2 3 public static void main(String[] args) { 4 ConcreteSubject s = new ConcreteSubject() ; 5 6 Observer o1,o2,o3 ; 7 o1 = new ConcreteObserver("A队员"); 8 o2 = new ConcreteObserver("B队员"); 9 o3 = new ConcreteObserver("C队员"); 10 11 s.attach(o1); 12 s.attach(o2); 13 s.attach(o3); 14 15 o1.beAttacked(s); 16 17 } 18 19 }
4.适用场景
(1)一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象将发生改变,也不知道这些对象是谁。
(2)一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使各自的变化都不会影响到另一边的变化。