观察者模式

2018-03-19  本文已影响0人  y丶M1ng

观察者模式适合于一对多的关系,当一发生变化的时候可以通知多的那一方。将一这一方成为主体,而多的一方则为观察者。例如天气预报,当天气发生变化的时候即可通知已经订阅的观察者。而观察者不想被通知天气变化的时候也十分方面就可以取消订阅。

观察者模式的优缺点

优点

1.主题和观察者是抽象耦合 2.一键式的通知方式

缺点

1.如果观察者过多,通知效率低下2.观察者只能得到变化后的结果而不能知道变化的过程。

观察者模式的实现

首先我们要定义一个抽象主体类。所有的主题都通过继承这个抽象类来实现具体的主题。这个抽象主体中要编写一个notifyobservers方法,通过这个方法来通知所有的观察者。所以update()方法即为每个观察者的更新方法。

1.抽象主题

public abstract class subject {
    private List<observer> observers = new ArrayList<observer>(); // 作为观察者数组

    public void addObserver(observer observer) {
        observers.add(observer);
    }

    public void removeObserver(observer observer) {
        observers.remove(observer);
    }

    public void notifyobservers() {
        for (observer observer : observers) {
            observer.update(this);
        }
    }
}

抽象主题已经有了之后就要有观察者,我们也要定义一个抽象的观察者,为所有的具体观察者定义一个更新接口。在抽象主题中已经对观察者定义了一个update方法,这边要定义update方法。

2.抽象观察者接口

public interface observer {
    public void update(subject subject);
}

定义完抽象的接口,就要从抽象到具体,首先我们要写一个具体的主题。这个主题仅仅定义了一个消息属性,以及一个通知方法,通过此方法去调用抽象类的notifyobservers方法进行通知,同时将message内容赋予ConcreteSubject的message。让在update中可以调用到该属性。

3.具体主题类

public class ConcreteSubject extends subject {
    private String message;

    public String getMessage() {
        return message;
    }

    public void noiftychange(String message) {
        this.message = message;
        notifyobservers();
    }
}

完成了具体的主题,就剩下具体的观察者了。我们定一个name属性,用来知道每个观察者的姓名,实现observer接口,实现update方法 update方法就是具体的更新方式了。这边我们只是先通过输出到控制台的方式来表示更新。

4.具体观察者类

public class ConcreteObserver implements observer {
    String name;

    ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(subject subject) {
        String message = ((ConcreteSubject) subject).getMessage();
        System.out.println(name + "先生您收到的消息为:" + message);
    }

}

5.测试类

从代码中可以看出通过观察者模式,我们可以很灵活的进行增加或者删除订阅者,统一发送消息。

public class ClientTest {
    public static void main(String[] args) {
    ConcreteSubject concreteSubject=new ConcreteSubject();
    ConcreteObserver observer1=new ConcreteObserver("张");
    ConcreteObserver observer2=new ConcreteObserver("王");
    concreteSubject.addObserver(observer1);
    concreteSubject.addObserver(observer2);
    concreteSubject.noiftychange("今天气温要下降,请注意保暖");
    concreteSubject.removeObserver(observer1);
    concreteSubject.noiftychange("明天高温,请避免出门");

    }

}

6.测试的结果

测试结果.png
上一篇 下一篇

猜你喜欢

热点阅读