软件设计 观察者模式(high)Observer Pattern

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

在 Java 中,一个对象的状态发生改变,就可能会影响到其他的对象,与之相关的对象可能也会联动的进行改变。

比如监听器机制,当具体的事件触发时,可以在创建的监听器中执行相关的逻辑。

观察者模式可以实现这样的功能,当对象发生改变时,观察者能够立即观察到并进行一些联动操作。

 

代码实现:

 

这里以监听主体改变为例来介绍观察者模式:

1、定义观察者

/**
* 观察者
*/
public interface Observer {
   /**
    * 更新操作
    */
   void update();
}

2、定义观察者实现类

/**
* 观察者实现类
*/
public class ObserverImpl implements Observer {
   @Override
   public void update() {
       System.out.println("进行了修改");
  }
   // 或者写成lambda表达式
  ()->{System.out.println("进行了修改");}
}
3、定义主体

/**
* 主体
*/
public class Subject {
   /**
    * 观察者集合
    */
   private final Set<Observer> observerSet = new HashSet<>();
   /**
    * 添加观察者
    * @param observer 观察者
    */
   public void observe(Observer observer) {  
       observerSet.add(observer);
  }
   /**
    * 修改
    */
   public void modify() {
       // 当对象发生修改时,会通知所有的观察者,并进行方法回调
       // :: (Java 8 新增方法引用)
       observerSet.forEach(Observer::update);
  }
}
4、调用

// 主体
Subject subject = new Subject();
// 添加观察者
subject.observe(new ObserverImpl());
// 修改
subject.modify();
输出结果为:

进行了修改
可以发现,当主体调用修改方法时,添加的观察者观察到了变化,执行了操作。这就是观察者模式的自定义实现。

 

优缺点:

优点

1、观察者和被观察者是抽象耦合的。

2、建立一套触发机制。

缺点

1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

 

使用场景:

1、一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。

2、一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。

3、一个对象必须通知其他对象,而并不知道这些对象是谁。

4、需要在系统中创建一个触发链,A 对象的行为将影响 B 对象,B 对象的行为将影响 C 对象……,可以使用观察者模式创建一种链式触发机制。

 

注意:

1、Java 中已经有了对观察者模式的支持类。

2、避免循环引用。

3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

 
posted @ 2023-02-11 15:01  kuaiquxie  阅读(14)  评论(0编辑  收藏  举报