观察者模式
观察者模式,是实现对象之间联动的一种解决方案,当一个对象发生变化,其他对象会得到通知
四个角色
- 抽象观察者(Observer)
- 具体观察者(ConcreteObserver)
- 抽象目标(Target)
- 具体目标(ConcreteTarget)
例子:RNG战队五名成员,letme、xiaohu、mlxg、uzi、ming。当有一名队友遭受到攻击时,其他队友都知道了他被攻击,都前来支援。
- 定义抽象观察者(Player)
public interface Player {
String getName();
void help();
void beAttached(Team team);
}
- 定义抽象目标(Team)
public abstract class Team {
protected String teamName;
protected List<Player> players = new ArrayList<>();
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public void join(Player player) {
players.add(player);
}
public void quit(Player player) {
players.remove(player);
}
public void callHelp(String playerName) {
System.out.println(this.teamName + "战队紧急通知," + playerName + "呼叫救援......");
notifyOtherPlayers(playerName);
}
public abstract void notifyOtherPlayers(String name);
}
- 定义具体观察者(ConcretePlayer)
public class ConcretePlayer implements Player {
private String name;
public ConcretePlayer(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name;
}
@Override
public void help() {
System.out.println(this.name + "前来支援......");
}
@Override
public void beAttached(Team team) {
team.callHelp(this.name);
}
}
- 定义具体目标类
public class DragonTeam extends Team {
@Override
public void notifyOtherPlayers(String name) {
players.stream().filter(player -> !name.equals(player.getName())).forEach(player -> player.help());
}
}
- 模拟实际场景
public class Main {
public static void main(String[] args) {
Team team = new DragonTeam();
team.setTeamName("RNG");
Player letme = new ConcretePlayer("letme");
team.join(letme);
Player xiaohu = new ConcretePlayer("xiaohu");
team.join(xiaohu);
Player mlxg = new ConcretePlayer("mlxg");
team.join(mlxg);
Player uzi = new ConcretePlayer("uzi");
team.join(uzi);
Player ming = new ConcretePlayer("ming");
team.join(ming);
uzi.beAttached(team);
}
}
- 结果如下
RNG战队紧急通知,uzi呼叫救援......
letme前来支援......
xiaohu前来支援......
mlxg前来支援......
ming前来支援......
总结
优点:可以实现对象间一对多联动
缺点:如果观察者过多,执行效率会降低
补充
jdk自带了观察者模式的接口(Observer)和目标类(Observable)
- 定义具体观察者,实现jdk的观察者Observer接口
public class ConcretePlayer implements Observer {
private String name;
public ConcretePlayer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
if (name.equals(arg)) {
return;
}
System.out.println(this.name + "前来支援......");
}
}
- 定义具体目标类继承Observable
public class DragonTeam extends Observable {
public void setChange() {
setChanged();
}
}
- 具体实现
public class Main {
public static void main(String[] args) {
DragonTeam team = new DragonTeam();
ConcretePlayer letme = new ConcretePlayer("letme");
team.addObserver(letme);
ConcretePlayer xiaohu = new ConcretePlayer("xiaohu");
team.addObserver(xiaohu);
ConcretePlayer mlxg = new ConcretePlayer("mlxg");
team.addObserver(mlxg);
ConcretePlayer uzi = new ConcretePlayer("uzi");
team.addObserver(uzi);
ConcretePlayer ming = new ConcretePlayer("ming");
team.addObserver(ming);
team.setChange();
team.notifyObservers(uzi.getName());
}
}
- 结果如下
ming前来支援......
mlxg前来支援......
xiaohu前来支援......
letme前来支援......