【设计模式总结】2、观察者模式

观察者模式是个非常常见的设计模式,窗体程序中、MVC等都大量使用了观察者模式。
观察者模式,可以理解为采用订阅、推送消息的方式实现一对多(其实还可以‘拉’消息,Java内置库中有相应实现,但‘推’更为巧妙,本文实现用的‘推’)。

概念
在对象之间定义一对多依赖,这样一来,当一个对象改变状态,依赖他的对象会收到通知,并自动更新。

主题与观察者
*《HeadFirst 设计模式》*一书中提到了订阅报纸,你想看报纸,可以向报社订阅,然后报社有新闻了便会给你发报纸,如果你不想看了,可以取消订阅。这其实就是观察者模式,我们将报社称作主题(Subject),你就是观察者(Observer)

以下是观察者模式类图
UML类图
优势:
让主题和观察者之间松耦合,主题只知道观察者实现了某个接口,不知道观察者的具体类是谁、做了什么或其他细节;有新类型观察者出现时,主题(Subject)的代码不需要修改;我们可以独立地复用主题或观察者;改变两者任意一方,不会互相影响。

代码实现:

Subject.java:

 public interface Subject{
        public void addObserver(Observer o);
        public void removeObserver(Observer o);
        public void notifyObservers();//推送
    }

Observer.java:

public interface Observer{
    public void update(Object object);
}

DisplayElement.java:

public interface DisplayElement{
    public void display();
        }

ConcreteSubject.java:

import java.util.ArrayList;

public class ConcreteSubject implements Subject{
    private ArrayList observers;//用于存储订阅的观察者
    private float data1;
    private float data2;
    public float getData1() {
        return data1;
    }
    public float getData2() {
        return data2;
    }

    public  ConcreteSubject()
    {
        observers=new ArrayList();
    }

    public void addObserver(Observer o)
    {
        observers.add(o);
    }

    public void removeObserver(Observer o)
    {
        int i = observers.indexOf(o);
        if(i >= 0){
            observers.remove(i);
        }
    }

    public  void  notifyObservers()
    {
        for (int i = 0; i < observers.size();i++)
        {
            Observer observer=(Observer)observers.get(i);

            observer.update(this);//更改消息
        }
    }

    public void setDatas(float data1,float data2)
    {
        this.data1=data1;
        this.data2=data2;
        notifyObservers();
    }
}

ConcreteObserver.java:

public class ConcreteObserver implements Observer, DisplayElement{
    private float data1;
    private float data2;
    private Subject concreteSubject;

    public ConcreteObserver(Subject concreteSubject)
    {
        this.concreteSubject=concreteSubject;
    }

    public void update(Object o)
    {
        this.data1=((ConcreteSubject)o).getData1();
        this.data2=((ConcreteSubject)o).getData2();
        display();
    }

    public void display()
    {
        System.out.println("data1:"+data1+","+"data2:"+data2);
    }
}

测试代码:

public class Main {

    public static void main(String[] args) {
        ConcreteSubject concreteSubject = new ConcreteSubject();

        ConcreteObserver concreteObserver=new ConcreteObserver(concreteSubject);
        concreteSubject.addObserver(concreteObserver);

        concreteSubject.setDatas(12,12);
        concreteSubject.setDatas(13,13);
        concreteSubject.setDatas(14,14);

    }
}

运行结果:
运行结果

总结:

OO原则:
为交互对象之间松耦合设计而努力

**封装变化:**在观察者模式中,会改变的是主题状态,以及观察者的数目和类型。用这个模式,你可以改变依赖于主题状态的对象,却不必改变主题。这就叫提前规划。

**针对接口,不针对实现:**主题与观察者都使用接口,观察者利用主题的接口向主题注册,而主题利用观察者接口进行通知(推送消息)。

**多组合,少继承:**观察者模式利用组合将许多观察者组合进主题中。即本文中的ArrayList

下一节,装饰者模式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值