23种设计模式-观察者模式

111 阅读2分钟

什么是观察者模式?

观察者模式 (Observer Pattern) 是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,它的所有依赖者 (观察者) 都会收到通知并自动更新。 在观察者模式中,有两个核心角色:Subject(主题) 和 Observer(观察者)。Subject 对象维护一组观察者,并负责通知它们状态变化的情况。Observer 对象订阅 Subject 对象的状态,并在 Subject 发生状态变化时被通知,并更新自身的状态。

观察者模式的作用

观察者模式的关键是解耦,使得 Subject 和 Observer 之间不直接相互依赖,而是通过抽象接口进行交互。这样,当 Subject 对象的状态发生变化时,Observer 对象不需要知道具体的变化细节,只需要接收通知并做出相应的响应即可。

观察者模式的案例

public class  Child{
        Boolean cry;

        public Child(Boolean cry) {
            this.cry = cry;
        }

        public void  wakeUp(){
            cry =true;
            System.out.println("child 哭醒了");
            Dad dad = new Dad();
            dad.wake();
        }
    }
package com.mult.strategy.observer;

public class Dad {

    public void wake() {
        System.out.println("dad 起床哄孩子");
    }
}

public class Observer1 {

    public static void main(String[] args) {
       Child child = new Child(false);
        child.wakeUp();
    }
}

上面案列中child属于被观察对象,dad属于观察者,当child触发wakeup()方法之后,就会调起观察者的wakeUp()方法。这种就是属于简单的观察者模式的实现,但是有一些问题。 首先每个观察者都需要在被观察对象里面创建,这就导致扩展观察者的时候,变得很繁琐。我们可以通过下面的方案做实现。

package com.mult.strategy.observer;

/**
 * @author mult
 */
public class Mom implements Observer{

    @Override
    public void wakeUp() {
        System.out.println("mom醒来 喂吃的");
    }
}
package com.mult.strategy.observer;

import java.util.ArrayList;
import java.util.List;

public class Child2 {
        Boolean cry;
        List<Observer> observers = new ArrayList<>();
        
        public Child2(Boolean cry) {
            this.cry = cry;
        }

        public void  wakeUp(){
            cry =true;
            for (Observer observer : observers) {
                observer.wakeUp();
            }
        }
    }
package com.mult.strategy.observer;
public class Observer2 {

    public static void main(String[] args) {
       Child2 child = new Child2(false);
        List<Observer> observers = new ArrayList<>();
        observers.add(new Mom());
       child.observers = observers;
        child.wakeUp();
    }
}

这个形式目前解决了观察者对象扩展的问题,只需要在集合中添加观察对象就可以完成扩展。 但是还有一个数据传递的问题需要解决。观察者有的时候是需要被观察对象的某些数据,这个时候我们就要传递数据了。

package com.mult.strategy.observer;

import java.time.LocalDateTime;
public class CryMsg<T> {
    T t;
    Boolean cry;

    public CryMsg(T t,Boolean cry, LocalDateTime cryTime) {
        this.t = t;
        this.cry = cry;
        this.cryTime = cryTime;
    }

    LocalDateTime cryTime;
}
public interface ObserverMsg {
    void wakeUp(CryMsg cryMsg);
}
package com.mult.strategy.observer;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class Child3 {
        Boolean cry;
        List<ObserverMsg> observers = new ArrayList<>();

        public Child3(Boolean cry) {
            this.cry = cry;
        }

        public void  wakeUp(){
            cry =true;
            for (ObserverMsg observer : observers) {
                observer.wakeUp(new CryMsg<Child3>(this,this.cry, LocalDateTime.now()));
            }
        }
    }
package com.mult.strategy.observer;

import java.util.ArrayList;
import java.util.List;

public class Observer3 {

    public static void main(String[] args) {
       Child3 child = new Child3(false);
        List<ObserverMsg> observers = new ArrayList<>();
        observers.add(new GrandMom());
       child.observers = observers;
        child.wakeUp();
    }
}

现在的方案就是我们所见到的最终的观察者模式的形态了。