观察者模式

简介: 观察者模式

在处理类之间的多对一的依赖关系时,观察者设计模式应运而生了,它的出现实现了代码的瘦身,类之间的解耦,本文分三部分:

  • 非观察者模式的多对一的依赖处理
  • 观察者模式对多对一依赖处理的优化
  • Java内置的观察者


假设场景: 前端用户向后端服务器发送不同的请求,后端的Selector区的分不同的请求,回调不同的Handler处理请求, 下面的示例代码


非观察者#


当Selector发现数据改变时,想要回调Handler的方法的前提是它要维护一个Handler的引用, 我们在构造函数中传递进去


@Data
public class Selector {
    private String username; 
    private String password; 
    private Handler1 currentConditions;
    public Selector(Handler1 currentConditions) {
        this.currentConditions = new Handler1();
    }
    public void datachange() {
        currentConditions.update(getUsername(),getPassword());
    }
    // 添加假数据
    public void setData(String username,String password){
        this.username=username;
        this.password=password;
        datachange();
    }
}


Handkler 的成员变量和Selector一样, 同时真正干活的人是handler, 它里面只有干活的方法以及承载数据的字段, 干活的方法会被回调, 字段由Selector负责初始化


public class Handler1 {
    private String  username;
    private String password;
    public void update( String  username, String  password){
        this.username=username;
        this.password=password;
        display();
    }
    public void display(){
        System.out.println("Handler1 : username"+ username);
        System.out.println("Handler1 : password"+username);
    }
}


测试:


public class text {
    public static void main(String[] args) {
        Handler1 currentConditions = new Handler1();
        Selector Data = new Selector(currentConditions);
        Data.setData("张三","123");
    }
}


上面的设计方法实现了,当Selector发现新的数据改变时,回调指定的handler的需求,但是缺点很快就暴露出来, Handler引用以构造方法的形式在Selector维护,如果有100个handler, 是不是意味着Selector的构造函数重载100份?


观察者模式#


观察者解决了上面的问题,在观察者模式中有两个角色的划分,1.SubJect 2.Observer, 其中 SubJect负责回调Observer提供的方法处理数据, Observer就是观察者,伺机而动, 它之所以能够实现两者的解耦,实现代码的瘦身,精华就是在Subject的构造函数不再维护单一的某一个Observer的引用,而是一个泛型是为Observer类型的集合, 为了防止把非观察者的对象添加到集合中, 故 在原有的基础上,向上进行了一层抽象,把Subject和Observer设计成接口,Subject提供了注册/移除/通知观察者的方法,通知哪个方法呢? 于是Observer接口中提供了需要被回调的抽象方法, 做完这层封装之后,就有了这个观察者体系, 所有的观察者必须实现Observer接口,重写它的方法,任何回调观察者的类,也必须实现Subject,重写它的方法


实例代码:


public interface Subject {
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();
}
public interface Observer {
    public void update(String m,String p);
}


Subject的实现类:


@Data
public class Selector implements Subject {
    private String username;
    private String password;
    private ArrayList<Observer> list;
    public Selector() {
      this.list = new ArrayList<Observer>();
    }
    // 添加假数据
    public void setData( String username, String password){
        this.username=username;
        this.password=password;
    }
    @Override
    public void registerObserver(Observer o) {
        list.add(o);
    }
    @Override
    public void removeObserver(Observer o) {
        list.remove(o);
    }
    @Override
    public void notifyObserver() {
        list.forEach(s->s.update(getPassword(),getUsername()));
    }
}


Observer的实现:


public class Handler1 implements Observer {
    private String username;
    private String password;
    @Override
    public void update( String username,String password){
        this.username=username;
        this.password=password;
        display();
    }
    public void display(){
        System.out.println("  Handler1    "+ username);
        System.out.println("  Handler1    "+password);
    }
}


测试:


public class text {
    public static void main(String[] args) {
        Handler1 secondConditions = new Handler1();
        Selector Data = new Selector();
        // 注册观察者
          Data.registerObserver(secondConditions);
          Data.setData("张三","123");
          Data.notifyObserver();
    }
}


我们自己实现的观察者函数回调的特性: : 虽然实现我们一开始的需求,但是可以看到,数据是在Subject端进行初始化的, 并没有传递到观察端,由观察者自主分配数据


java内置的观察者#


java内置的观察中同样分为两种角色,1.Obserable 2.Observer 其中Observer是观察者,同样不变的是,他是个接口


但是: Obserable是一个抽象类, java为我们实现了 注册/移除,通知的方法, 在不允许多继承的java中,抽象类是有缺点的,这使得当前类不能再继承其他类

此外: 相对于我们自定义的观察者, 它做到了把数据传递到 观察者客户端,任由观察者自主的分配这些数据


如何使用:

对于Obserable来说, 继承他

  • 由于java实现了主要的方法, 我们只关注如何使用这几个方法就行了
  • 1: 在回调之前 , 必须先使用 this.setChanged(); 否则信息不会通知到观察者
  • 2: 通知的方法this.notifyObservers(Object obj));


@Data
public class Selector extends Observable {
    private String username;
    private String  password;
    // 添加假数据
    public void setData( String username, String password) {
        this.username = username;
        this.password = password;
        datachange();
    }
    // 当信息更改, 就推送
    public void datachange() {
        // todo 加上这一条,当有信息改变时, 就执行
        this.setChanged();
        // 通知时,把信息同步推送给观察者
       this.notifyObservers(new Data(getUsername(),getPassword()));
    }
    @lombok.Data
    public class Data {
        private String username;
        private String  password;
        public Data( String username, String password) {
            this.username = username;
            this.password = password;
        }
    }
}


观察者: 继承Observer, 重写它被回调的方法


public class Handler1 implements Observer {
    private String username; 
    private String password;  
    @Override
    public void update(Observable observable, Object arg0) {
        this.password = ((Selector.Data) (arg0)).getPassword();
        this.username = ((Selector.Data) (arg0)).getUsername();
        display();
    }
    public void display() {
        System.out.println("Handler1 :    " + username);
        System.out.println("Handler1 : " + password);
    }
}


测试


public class text {
    public static void main(String[] args) {
        Handler1 handler1 = new Handler1();
        Selector weatherData = new Selector();
        // 先注册的观察者,后执行
        weatherData.addObserver(handler1);
        weatherData.setData("张三","123");
    }
}


相关文章
|
6月前
|
设计模式 消息中间件 Java
观察者模式
观察者模式
52 1
|
6月前
|
C++
【C++】—— 观察者模式
【C++】—— 观察者模式
|
6月前
|
设计模式 JavaScript 开发者
详细讲解什么是观察者模式
详细讲解什么是观察者模式
|
关系型数据库 API
观察者模式解读
观察者模式解读
|
6月前
|
设计模式 Java
【观察者模式】 ——每天一点小知识
【观察者模式】 ——每天一点小知识
5 # 观察者模式
5 # 观察者模式
36 0
|
设计模式 Java Spring
设计模式~观察者模式(Observer)-11
它属于行为型模式的一种。观察者模式定义了一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听。当这个主题对象状态变化时,会通知所有观察者对象并作出相应处理逻辑。 目录
71 0
|
设计模式
观察者模式(上)
观察者模式(上)
82 0
|
XML 设计模式 Java
观察者模式(下)
观察者模式(下)
61 0
|
设计模式
我学会了,观察者模式
观察者模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。
130 0
我学会了,观察者模式