由于blog各种垃圾评论太多,而且本人审核评论周期较长,所以懒得管理评论了,就把评论功能关闭,有问题可以直接qq骚扰我

设计模式—观察者模式

JAVA 西门飞冰 27℃

观察者模式Observer是⼀种⾏为设计模式, 允许你定义⼀种订阅机制, 可在对象事件发⽣时通知多个 “观察” 该对象的其他对象。

观察者结构

  • Subject被观察的⽬标
  • Observer观察者抽象类
  • 具体的观察者实现类
  • Client客户端

观察者模式通常目标只有一个,但是观察者会有多个,多个观察者会对这一个目标从不同角度进行观察

image-20220919222043869

案例代码:

模拟一个服务器被多个观察者监听的过程

Observer抽象观察者内部持有Subject对象

// 观察者接口,有观察者来实现
public abstract class Observer {
   //内部持有目标类
   protected Server subject;
   //观察者的更新方法:定义真正在运行时具体的观察者做什么事情
   public abstract void update();
}

Subject⽬标:Subject内部持有观察者对象集合,在合适的时机触发事件

public class Server {
    //观察者集合
    private List<Observer> observers = new ArrayList<Observer>();
    //服务器的基础指标
    private int cpu;
    private int memory;

    //当有更新时,就调用changeState,进行指标状态的变更
    public void changeState(int cpu,int memory){
        this.cpu = cpu;
        this.memory = memory;
        System.out.println("CPU:" + cpu + "%,内存占用:" + memory + "%");
        notifyAllObservers();
    }
    public int getCpu() {
        return cpu;
    }

    public int getMemory() {
        return memory;
    }

    //当外部传入观察者,就向观察者集合添加观察者
    public void addObserver(Observer observer){
        observers.add(observer);      
    }
    //对当前所有目标类 持有的observer对象的update方法进行调用
    public void notifyAllObservers(){
        for (Observer observer : observers) {
            // 不同的观察者执行不同的update方法
            observer.update();
        }
    }  
}

CPU监听器-观察者:Observer内部持有subject⽬标

//cpu运行时监听器
public class CpuObserver extends Observer{

   //在构造方法时从外部传入目标类:观察者和目标类双向绑定关系,就是在每一个Observer初始化时完成的
   public CpuObserver(Server subject){
      this.subject = subject;
      this.subject.addObserver(this);
   }
 
   @Override
   public void update() {
      //监听CPU运行时特性
      if(subject.getCpu() >= 80){
         System.out.println("警报:CPU当前" + subject.getCpu()+ "%即将满载,请速查明原因");
      }
   }
}

内存监听器-观察者

//内存运行时监听器
public class MemoryObserver extends Observer{
 
   public MemoryObserver(Server subject){
      this.subject = subject;
      this.subject.addObserver(this);
   }
 
   @Override
   public void update() {
      //监听内存运行时特性
      if(subject.getMemory() >= 80){
         System.out.println("警报:服务器内存已占用超过" + subject.getMemory() + "%,请速查明原因");
      }
   }
}

客户端根据需要组织observer,在调⽤changeState()⽅法时触发观察者

public class Client {
   public static void main(String[] args) throws InterruptedException {
      // 实例化目标类
      Server subject = new Server();

      // 增加两个观察者:将目标类传入观察者中
      new CpuObserver(subject);
      new MemoryObserver(subject);

      //遍历所有观察者,并通知
      while(true) {
         int cpu = new Random().nextInt(100);
         int memory = new Random().nextInt(100);
         subject.changeState(cpu, memory);
         Thread.sleep(5000);
      }
   }
}

观察者模式优点:

开闭原则。 你⽆需修改发布者代码就能引⼊新的订阅者类 (如果是发布者接⼝则可轻松引⼊发布者类)。

你可以在运⾏时建⽴对象之间的联系。

观察者模式适合应⽤场景:

所有的发布订阅模式

构建事件监听机制,⽐如按下按钮触发click事件

转载请注明:西门飞冰的博客 » 设计模式—观察者模式

喜欢 (0)or分享 (0)