java设计模式-行为型模式-观察者模式

观察者模式

观察者模式,是实现对象之间联动的一种解决方案,当一个对象发生变化,其他对象会得到通知

四个角色

  • 抽象观察者(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前来支援......

回到主目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值