设计模式之观察者模式

115 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情

简介

观察者模式的定义:

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

案例

我们通过使用微博关注明星作为例子。粉丝们在社交平台上注册账号并关注自己喜欢的明星,明星在这个社交平台上发布照片等动态时,各位关注过的粉丝就可以收到通知。

我们先定义一个明星类,明星当然有一群粉丝fansList,然后有一个状态的变量以及改变这个状态的方法,改变这个状态之后还有去通知自己的每一个粉丝,最后还有一个新增粉丝的方法:

public class SuperStar {
    private List<Fans> fansList = new ArrayList<Fans>();
    private String state;
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
        notifyAllFans();
    }
    public void addFans(Fans fans) {
        fansList.add(fans);
    }

    public void notifyAllFans() {
        fansList.forEach(e -> e.notifys());
    }
}

接下来我们定义一个抽象的粉丝类,各色类型的粉丝分别继承它,然后拥有一个notifys方法用于被通知他所关注的明星的动态:

public abstract class Fans {
    protected SuperStar superStar;
    public abstract void notifys();
}

然后定义一个法外狂徒张三,我们发现构造方法种除了指向一个明星对象之外,还调用了明星的新增粉丝的方法,即将自己设置为该明星的粉丝。

public class Zhangsan extends Fans {
    public Zhangsan(SuperStar superStar) {
        this.superStar = superStar;
        this.superStar.addFans(this);
    }
    @Override
    public void notifys() {
        System.out.println("zhangsan accept notify" + superStar.getState());
    }
}

定义另一个法外狂徒李四:

public class Lisi extends Fans {
    public Lisi(SuperStar superStar) {
        this.superStar = superStar;
        this.superStar.addFans(this);
    }
    @Override
    public void notifys() {
        System.out.println("lisi accept notify" + superStar.getState());
    }
}

在测试类我们我们实例化一个明星和两个粉丝,然后在明星改变动态的时候,张三和李四均收到了通知:

public class App {
    public static void main(String[] args) {
        SuperStar superStar = new SuperStar();
        Zhangsan zhangsan = new Zhangsan(superStar);
        Lisi lisi = new Lisi(superStar);
        superStar.setState("eat");
    }
}

总结

一个对象的改变会导致一个或多个对象发生改变,而并不知道具体有多少对象将会发生改变,也不知道这些对象是谁,这个时候我们就要考虑使用观察者模式了。其实在我们生活中很多场景都适用于观察者模式,比如买了彩票等开奖通知,还有我们Java GUI编程中的各种Listenner等。