【design pattern】行为型模式之—观察者模式(observer)

      原文 :  oodesign

产生的诱因

    我们在谈论 面向对象编程的时候,不得不考虑 对象状态的变化 。毕竟 面向对象编程 是  关于 对象 以及 对象之间的交互。

有这么一种业务情况,当 一个对象 发生改变时 ,某一类对象需要被通知 ,为了 解耦 可以采用 观察者模式,

观察者模式 用在   一个 对象需要 被 一个 或者 多个 观察者 观察的时候;


思路

在对象之间 定义 一个 一对多的依赖,当一个对象的状态改变时,所有他的依赖被自动 通知 和 更新

说明:

Observable  :接口 或者 抽象类 ,定义了向 客户端 添加 观察者 和 删除观察者 的 操作, 通知操作 ,该类也可以叫做 Subject;

ConcreteObservable: Observable 具体实现,定义了更新操作,该方法的执行会执行通知操作


Observer :接口 或者 抽象类 ,定义了 用来通知 该对象的操作;

ConcreteObserverA,ConcreteObserverB: Observer 的具体实现;

实现流程:

首先 实例化  ConcreteObservable(ConcreteSubject) 对象;

然后再实例化 Observer 的具体实现类 并使用  Observable 接口中定义的 attach  方法 将 Obserserver 实例 纳入其中;

每次 ConcreteObservable 状态改变,会使用 Observable 接口中定义的 notifyObservers  方法 调用 所有已管理的 Observer 的 update 方法;

当一个新的 Observer 被添加到应用中时,我们需要做的仅仅是实例化它,然后将它添加到 Observable 对象中

应用 和 实例

典型的 案例:

MVC (MOdel View Controller)模式 :观察者模式 被用在  MVC架构模式中,在MVC 模式中,观察者模式是用来 将 数据层(Model)从 视图层(View)解耦。 View 代表 Observer 对象, Model  代表 Observable 对象

事件管理:


应用:新闻订阅


NewsPublisher :抽象类,相当于一个  Observable 接口

package com.ycit.observer;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by xlch on 2017/3/16.
 */
public abstract class NewsPublisher {

    List<Subscriber> subscribers = new ArrayList<>();

    String latestNews;

    abstract void attach(Subscriber subscriber);

    abstract void detach(Subscriber subscriber);

    abstract void notifyObservers();

    abstract void publishNews(String news);

    public String getLatestNews() {
        return latestNews;
    }
}

SportNewsPublisher:具体实现类

package com.ycit.observer;

/**
 * Created by xlch on 2017/3/16.
 */
public class SportNewsPublisher extends NewsPublisher {

    private String name;

    public SportNewsPublisher(String name) {
        this.name = name;
    }

    @Override
    void attach(Subscriber subscriber) {
        subscribers.add(subscriber);
    }

    @Override
    void detach(Subscriber subscriber) {
        subscribers.remove(subscriber);
    }

    @Override
    void notifyObservers() {
        for (Subscriber subscriber:subscribers) {
            subscriber.update(this);
        }
    }

    /**
     * 发布新闻,代表 latestNews 状态改变,通知所有订阅者
     * @param news
     */
    @Override
    void publishNews(String news) {
        System.out.println(this.name + "  publish a news:" + news);
        latestNews = news;
        notifyObservers();
    }
}

Subscriber : 订阅者 ,即观察者

package com.ycit.observer;

/**
 * Created by xlch on 2017/3/16.
 */
public interface Subscriber {


    /**
     * 状态改变时执行的动作
     * @param newsPublisher
     */
    void update(NewsPublisher newsPublisher);


}

EmailSubscriber:邮件订阅者

package com.ycit.observer;

/**
 * Created by xlch on 2017/3/16.
 */
public class EmailSubscriber implements Subscriber {

    private String name;

    public String getName() {
        return name;
    }

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

    public EmailSubscriber(String name) {
        this.name = name;
    }

    private NewsPublisher newsPublisher;


    public void setNewsPublisher(NewsPublisher newsPublisher) {
        this.newsPublisher = newsPublisher;
    }

    public NewsPublisher getNewsPublisher() {
        return newsPublisher;
    }

    @Override
    public void update(NewsPublisher newsPublisher) {
        System.out.println(this.name + " receive a news :" + newsPublisher.getLatestNews());
    }
}


SMSSubscriber:sms 订阅者

package com.ycit.observer;

/**
 * Created by xlch on 2017/3/16.
 */
public class SMSSubscriber implements Subscriber {

    private String name;

    public String getName() {
        return name;
    }

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

    public SMSSubscriber(String name) {
        this.name = name;
    }

    private NewsPublisher newsPublisher;

    public void setNewsPublisher(NewsPublisher newsPublisher) {
        this.newsPublisher = newsPublisher;
    }

    public NewsPublisher getNewsPublisher() {
        return newsPublisher;
    }

    @Override
    public void update(NewsPublisher newsPublisher) {
        System.out.println(this.name + " receive a news :" + newsPublisher.getLatestNews());
    }
}

Main:测试类

package com.ycit.observer;

/**
 * Created by xlch on 2017/3/16.
 */
public class Main {

    public static void main(String [] args) {

        SportNewsPublisher sportNewsPublisher = new SportNewsPublisher("体育新闻发布者");

        EmailSubscriber emailSubscriber = new EmailSubscriber("邮件订阅者");
        SMSSubscriber smsSubscriber = new SMSSubscriber("sms 订阅者");

        sportNewsPublisher.attach(emailSubscriber);
        sportNewsPublisher.attach(smsSubscriber);

        sportNewsPublisher.publishNews("姚明退出NBA,火箭篮下恐不保");

    }

}

执行后 :

体育新闻发布者  publish a news:姚明退出NBA,火箭篮下恐不保
邮件订阅者 receive a news :姚明退出NBA,火箭篮下恐不保
sms 订阅者 receive a news :姚明退出NBA,火箭篮下恐不保















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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值