设计模式——观察者模式

作者:云都小生

推荐资料:
史上最全设计模式导学目录


前奏



各位小伙伴们,请想像一下,生活中是否有一种对象,它在状态在改变之后,其他的对象就会做出某些响应。

以前很火的穿越火线,是一款第一视角的射击游戏,在游戏中,玩家可以进行组队的游戏。游戏为每个玩家提供了雷达,上面显示了各个队友的位置情况。一旦某个队友被射杀,其他各个玩家都可以从雷达上看到一个“X”的标记。

这里写图片描述

这个时候,如果你是设计者,会怎么完成这个功能呢?一般程序员会这么设计:

这里写图片描述

每个玩家都持有其他玩家的所有引用,一旦状态发生了任何改变,就向各个玩家发送消息,其他玩家各自做出响应,如图。

这样就会使各个对象之前的引用关系变得非常复杂,不利于代码的维护等,所以,我们可以考虑一下观察者模式。


概述



设计模式是使用最为频繁的行为型设计模式之一, 定义了对象之间的一种低耦合的依赖关系,并且使得每一个对象状态发生改变的时候,其他对象都会被通知并自动更新。

这个模式可以用来设计广播通信,一旦某个节点发生了状态的改变,就通知其他的节点。

观察者模式一般有以下几种角色:Subject(目标)、ConcreteSubject(具体目标)、Observer(观察者)、ConcreteObserver(具体观察者)。

目标:目标是被观察的对象,这个对象中定义了一个观察者的集合,用来动态的增加多个观察者。同时,还提供了一系列的方法来对观察者对象进行操作。当它自身内部有一些状态进行改变的时候,就会通知相对应的观察者。

具体目标:具体目标是目标类的子类,定义了具体的业务逻辑。

观察者:观察者收到通知后,会通知其他的目标类。

具体观察者:在具体观察者中,需要维持一个对具体目标对象的引用,收到通知后就向具体目标对象进行响应。


简单模板


//抽象观察者
import java.util.ArrayList;

abstract class Subject
{  
    //定义一个观察者集合用于存储所有观察者对象  
    protected ArrayList<Observer> observers = new ArrayList();  

    //用于向观察者集合中增加一个观察者  
    public void attach(Observer observer)
    {  
        observers.add(observer);  
    }  

    //用于在观察者集合中删除一个观察者  
    public void detach(Observer observer)
    {  
        observers.remove(observer);  
    }  

    //声明抽象通知方法  
    public abstract void notice();  
}

//具体观察者
class ConcreteSubject extends Subject
{  
    //实现通知方法  
    public void notice()
    {  
        //遍历观察者集合,调用每一个观察者的响应方法  
        for(Object obs : observers)
        {  
            ((Observer)obs).update();  
        }  
    }     
}

//抽象目标类
interface Observer
{  
    //声明修改状态的方法
    public void update();  
}   

//具体目标类
public class ConcreteObserver implements Observer {  

    //实现响应方法  
    public void update()
    {
        System.out.println("响应!");
    }  
}

//测试类
public class Test
{
    public static void main(String[] args)
    {
        ConcreteObserver observer1 = new ConcreteObserver();
        ConcreteObserver observer2 = new ConcreteObserver();
        ConcreteObserver observer3 = new ConcreteObserver();

        ConcreteSubject subject = new ConcreteSubject();
        subject.attach(observer1);
        subject.attach(observer2);
        subject.attach(observer3);

        subject.notice();
    }
}

我看过网上的一些例子,观察者模式还可以别用来设计游戏中,盟友之间的相应。一旦盟友遭受攻击,其他盟友就会收到通知。


JDK支持



Java的util包中,提供了对观察者模式的支持——Observable类和Observer接口。

Observer接口,只声明了一个方法,它充当抽象观察者。

void update(Observable o, Object arg);

当观察目标的状态发生改变时,改方法就会被调用。

Observable,就是JDK提供的具体目标,这个目标类提供了一些关键的方法。

Observable() 构造方法 实例化存储观察者的向量
addObserver(Observer o) 增加一个观察者到向量中
deleteObserver(Observer o) 在向量中删除一个观察者对象
notifyObserver() 通知每一个观察者的update()方法

deleteObservers() 记住,这里结尾有个s,清空向量


总结



观察者模式提供了一种实现对象之间联动的解决方案,适用于一对多的对象交互场景。

优点:由于有了抽象层(观察者、目标类),建立了一个低耦合的关系,降低了复杂度和维护成本。符合“开闭”原则,可以随时增加观察者、目标类。

缺点:如果观察者目标对象太多,就会降低效率。

2018/3/13 20:00:57 @Author:Cloudking

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值