版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lkp1603645756/article/details/83902656
什么是观察模式呢?
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同事监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
它的特点是什么呢?
它将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维护一致性而使各类精密耦合,这样会给维护、扩展和重用都带来不便。
适合使用在什么场合?
当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。一个抽象模型有两个方面,其中一个方法依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。
观察者模式所做的工作其实就是在接触耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。
我们来看看观察者模式的结构图:
接下里来用代码来实践下。
首先创建一个Subject类,抽象通知者,一般用一个抽象类或者一个接口实现。
/**
* 作者:LKP
* 时间:2018/11/9
*/
public class Subject {
private List<Observer> observers = new ArrayList<>();
//增加观察者
public void Attch(Observer observer){
observers.add(observer);
}
//移除观察者
public void Detach(Observer observer){
observers.remove(observer);
}
//通知
public void Notify(){
for (Observer observer : observers) {
observer.Update();
}
}
}
创建Observer类,它是抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。
/**
* 抽象观察者
* 作者:LKP
* 时间:2018/11/9
*/
public abstract class Observer {
public abstract void Update();
}
创建一个ConcreteSubject类,它可以叫做具体主题或具体通知者,将有关状态存入具体观察者对象。
/**
* 具体通知者
* 作者:LKP
* 时间:2018/11/9
*/
public class ConcreteSubject extends Subject {
private String subjectState;
//具体被观察者状态
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
}
创建ConcreteObserver类,具体观察者,实现抽象观察者角色所需要的更新接口,以便使本身的状态与主题的状态相协调。
/**
* 具体观察者
* 作者:LKP
* 时间:2018/11/9
*/
public class ConcreteObserver extends Observer {
private String name;
private String observerState;
private ConcreteSubject subject;
public ConcreteObserver(ConcreteSubject subject,String name){
this.subject = subject;
this.name = name;
}
@Override
public void Update() {
observerState = subject.getSubjectState();
System.out.println("观察者"+name+"的新状态是"+observerState);
}
public ConcreteSubject getSubject() {
return subject;
}
public void setSubject(ConcreteSubject subject) {
this.subject = subject;
}
}
客户端代码:
/**
* 客户端
* 作者:LKP
* 时间:2018/11/9
*/
public class Main {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
subject.Attch(new ConcreteObserver(subject,"X"));
subject.Attch(new ConcreteObserver(subject,"Y"));
subject.Attch(new ConcreteObserver(subject,"Z"));
subject.setSubjectState("ABC");
subject.Notify();
}
}
运行一下,打印结果为: