行为型设计模式-观察者模式

Posted 风流 少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了行为型设计模式-观察者模式相关的知识,希望对你有一定的参考价值。

一:定义

观察者模式又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知素有的观察者对象,使他们能够自动更新自己。

二:案例

微信公众号有新内容推送时,会通知所有的关注着。

/**
 * 抽象观察者类
 */
public interface Observer 
    void update(String message);

public interface Subject 
    void addObserver(Observer observer);
    void removeObserver(Observer observer);

    void notify(String message);


public class WeiXinUser implements Observer 
    private String name;

    public WeiXinUser(String name) 
        this.name = name;
    

    @Override
    public void update(String message) 
        System.out.println(name + ":" + message);
    

/**
 * 具体主题类
 */
public class SubscriptionSubject implements Subject 
    private List<Observer> weixinUserList = new ArrayList<>();
    @Override
    public void addObserver(Observer observer) 
        weixinUserList.add(observer);
    

    @Override
    public void removeObserver(Observer observer) 
        weixinUserList.remove(observer);
    

    @Override
    public void notify(String message) 
        weixinUserList.forEach(observer -> observer.update(message));
    

public class Client 
    public static void main(String[] args) 
        SubscriptionSubject subject = new SubscriptionSubject();
        subject.addObserver(new WeiXinUser("孙悟空"));
        subject.addObserver(new WeiXinUser("猪八戒"));

        subject.notify("发布一条新消息");
    

优缺点

优点:

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 被观察者发送通知,所有注册的观察者都会收到消息,可以实现广播机制。
    缺点:
  • 如果观察者非常多的话,那么所有的观察者收到被观察者发送通知会耗时。
  • 如果被贯彻着有循环依赖的话,那么被贯彻着发送通知会使用观察者循环调用,会导致系统崩溃。

使用场景

  • 对象间存在一对多关系,一个对象的状态发生改变会影响其它对象。
  • 对一个抽象模型有两个方面,其中一个方面依赖于另一个面时。

JDK中的提供实现

package java.util;

public class Observable 
	private boolean changed = false;
	
    // 集合保存所有观察者
    private Vector<Observer> obs;

    public Observable() 
        obs = new Vector<>();
    
	protected synchronized void setChanged() 
        changed = true;
    
    protected synchronized void clearChanged() 
        changed = false;
    
    

	public synchronized void addObserver(Observer o) 
        if (!obs.contains(o)) 
            obs.addElement(o);
        
    
	
	public void notifyObservers(Object arg) 
		if (!changed) return;
        Object[] arrLocal = obs.toArray();
        clearChanged();
        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    

package java.util;
public interface Observer 
    void update(Observable o, Object arg);

案例

警察抓小偷:警察是观察者,小偷是被观察者。

/**
 * 小偷
 */
public class Thief extends Observable 
    private String name;
    public Thief(String name) 
        this.name = name;
    


    public void steal() 
        System.out.println("小偷:我偷东西了,有没有人来抓我啊");
        super.setChanged();
        super.notifyObservers();
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

public class PoliceMan implements Observer 
    private String name;
    public PoliceMan(String name) 
        this.name = name;
    


    @Override
    public void update(Observable o, Object arg) 
        System.out.println("警察:" + ((Thief)o).getName() + ", 我已经叮你很久了,你可以保持沉默,但你所说的将成为呈堂供词");
    


public class Main 
    public static void main(String[] args) 
        Thief thief = new Thief("隔壁老王");
        PoliceMan policeMan = new PoliceMan("Sir");
        thief.addObserver(policeMan);
        // 开始偷东西
        thief.steal();
    

以上是关于行为型设计模式-观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

手撸golang 行为型设计模式 观察者模式

行为型设计模式 - 观察者模式详解

设计模式-行为型模式,观察者模式(13)

Java设计模式之十一种行为型模式(附实例和详解)

设计模式-行为型模式讲解三(观察者状态中介者)

行为型模式--观察者模式