Java设计模式之观察者模式

1,881 阅读5分钟

个人简介:荡不羁,一生所爱。Java耕耘者(微信公众号ID:Java耕耘者),欢迎关注。可获得2000G详细的2020面试题的资料

设计模式:设计模式是解决问题的方案,学习现有的设计模式可以做到经验复用。拥有设计模式词汇,在沟通时就能用更少的词汇来讨论,并且不需要了解底层细节。

观察者设计模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

当我们在打团队游戏时,当你受到攻击需要队友帮忙时该怎么办?

这时候就需要给你所有的队友发送一条你正在被攻击的消息。所有的队友会根据你发送的消息作出相应的动作。比如有团队意识来帮你,或者不帮你继续玩自己的。

这里面的队员就是该设计模式名字中的观察者。那么受到攻击的自己的是什么呢。被观察者?不,准确的我们称之为目标或者主题。

所以整个流程大概就是:当目标(主题)的状态发送改变时就会通知观察者,观察者根据自己的情况做出相应的动作。

import java.util.Observable;
/** 
* @Author gaotian 
* @Description 具体目标类 Subject 继承抽象类并实现通知观察者的方法
 * 它拥有自己的状态,当它的状态的改变时就会通知各个观察者。 
* @Date 9:01 2020/6/23 
**/
public class Subject extends Observable {    
/**     
* Observable 它是指被观察的对象。我们在主题中定义一个观察者集合。     
* 一个观察者对象可以接收任意多个观察者。同时提供了一系列的方法管理这些观察者。    
 **/   
 /**     
* @Author gaotian     
* @Description //开启改变状态     
* @Date 15:45 2020/6/23     
**/    
@Override   
 protected synchronized void setChanged() 
{       
 super.setChanged();    
}
}



import java.util.Observable;
import java.util.Observer;
/** 
* @Author gaotian 
* @Description 
* 具体观察者中会维护一个指向具体目标对象的引用,它存储了具体观察者的状态,这些状态和具体目标的状态要保持一致。
 * 
* 它实现了抽象观察者对象的updata方法。
 * 
* 通常在实现时,可以调用具体目标的attach和detach方法将自己加入到集合中或者从集合中剔除。 
* @Date 9:06 2020/6/23 
**/
public class ConcreteObserver implements Observer {   
 private String observerName;    
public ConcreteObserver(String observerName) {        
this.observerName = observerName;    
}   
 @Override    
public void update(Observable o, Object arg) {        
System.out.println(observerName + "我要更新一下我的状态了......");        
System.out.println("目标类为:" + o);       
 System.out.println("参数为 = " + arg);   
 }
}



import java.util.Observable;
import java.util.Observer;
/** 
* @Author gaotian 
* @Description 第二个具体的观察者,测试是否能够同时收到消息并更新状态 
* @Date 9:09 2020/6/23 
**/
public class ConcreteOberverOther implements Observer 
{   
 private String observerName;   
 public ConcreteOberverOther(String observerName)
 {        
this.observerName = observerName;    
}    
@Override   
 public void update(Observable o, Object arg) 
{        
System.out.println(observerName + "我要更新一下我的状态了......");       
 System.out.println("目标类为:" + o);        
System.out.println("参数为 = " + arg);    
}
}



import java.util.Observer;
public class NotifyMain
 {   
 public static void main(String[] args) 
{        
Subject subject = new Subject();        
subject.setChanged();       
 Observer observer = new ConcreteObserver("观察者一号");       
 Observer observer2 = new ConcreteOberverOther("观察者二号");        
//将观察者都加入观察者列表中        
subject.addObserver(observer);        
subject.addObserver(observer2);        
//通知观察者        
boolean hasChanged = subject.hasChanged();       
 System.out.println("hasChanged = " + hasChanged);       
 subject.notifyObservers("123");    
}   
 /**     
* 1.主要优点    
 *    
 * (1)观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息传递机制,并抽象了更新接口,使得可以有各种各样的表示层充当具体的观察者角色。    
 *    
 * (2)观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察者对象只需要维持一个抽象观察者的集合,无需了解其具体观察者。    
 *     
* (3)观察者模式支持广播通信,观察目标会向所有已注册的观察者发送通知,降低了一对多系统的设计难度。    
 *     
* (4)观察者模式满足开闭原则的要求,增加新的具体观察者无须修改原有的系统代码。   
  *    
 * 2.主要缺点     *     
* (1)如果一个观察目标对象有很多的直接观察者和间接观察者,那么所有的观察者接收到消息会耗费大量的时间。   
  *    
 * (2)如果观察者和被观察者之间存在循环依赖,那么观察目标会触发它们之间进行循环调用,可能导致系统崩溃。     
*     
* (3)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道目标观察对象发生了变化。    
**/
}

1.主要优点

(1)观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息传递机制,并抽象了更新接口,使得可以有各种各样的表示层充当具体的观察者角色。
(2)观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察者对象只需要维持一个抽象观察者的集合,无需了解其具体观察者。
(3)观察者模式支持广播通信,观察目标会向所有已注册的观察者发送通知,降低了一对多系统的设计难度。
(4)观察者模式满足开闭原则的要求,增加新的具体观察者无须修改原有的系统代码。
2.主要缺点
(1)如果一个观察目标对象有很多的直接观察者和间接观察者,那么所有的观察者接收到消息会耗费大量的时间。
(2)如果观察者和被观察者之间存在循环依赖,那么观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
(3)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道目标观察对象发生了变化。