设计模式系列3 观察者模式

Posted wenteryan

tags:

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

什么是观察者模式?/观察者模式的定义?

在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。说白了就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

为什么用观察者模式?/用观察者模式有什么好处?

一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

优点:

  • 1、观察者和被观察者是抽象耦合的。
  • 2、建立一套触发机制。

缺点:

  • 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项:

1、JAVA 中已经有了对观察者模式的支持类。

2、避免循环引用。

3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

具体例子如:

  • 气象站服务,天气发生改变,关注者可以收到推送消息,取消关注就收不到推送消息。(Head First设计模式经典例子)
  • 微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。
  • 博客服务,博客新增文章,关注者消息推送消息,取消关注就收不到推送消息。

例子(博客服务)

博客新增文章,关注者消息推送消息,取消关注就收不到推送消息。

编写博客主题接口BlogSubject

public interface BlogSubject 

    /**
     * 关注博客
     * @param follower
     */
    void addFollower(Follower follower);

    /**
     * 取消关注
     * @param follower
     */
    void removeFollower(Follower follower);

    /**
     * 主题状态发生改变时,通知所有的关注者
     */
    void notifyFollower();

编写BlogSubject的实现类

public class BlogSubjectData implements BlogSubject 

    /** 记录所有观察者 **/
    private ArrayList followers;
    private String article;

    public BlogSubjectData() 
        followers = new ArrayList();
    

    @Override
    public void addFollower(Follower follower) 
        followers.add(follower);
    

    @Override
    public void removeFollower(Follower follower) 
        followers.remove(follower);
    

    @Override
    public void notifyFollower() 
        for (int i = 0; i < followers.size(); i++) 
            Follower follower = (Follower)followers.get(i);
            follower.update(article);
        
    

    public void setArticle(String article) 
        this.article = article;
        // 更新博客,需要通知关注者
        notifyFollower();
    

定义关注者接口Follower

public interface Follower 
    void update(String article);

所有关注者都要实现关注者接口

编写FollowerFirst并实现Follower接口

public class FollowerFirst implements Follower 

    private BlogSubject blogSubject;

    /**
     * 构造器需要BlogSubject对象为了能够添加关注者
     * @param blogSubject
     */
    public FollowerFirst(BlogSubject blogSubject) 
        this.blogSubject = blogSubject;
        blogSubject.addFollower(this);
    

    @Override
    public void update(String article) 
        System.out.println("关注者NO1,你关注的博主有新文章啦,文章名:"+article);
    

编写FollowerSecond并实现Follower接口

public class FollowerSecond implements Follower 

    private BlogSubject blogSubject;
    /**
     * 构造器需要BlogSubject对象为了能够添加关注者
     * @param blogSubject
     */
    public FollowerSecond(BlogSubject blogSubject) 
        this.blogSubject = blogSubject;
        blogSubject.addFollower(this);
    

    @Override
    public void update(String article) 
        System.out.println("关注者NO2,你关注的博主有新文章啦,文章名:"+article);
    

编写测试类

public class BlogTest 
    public static void main(String[] args) 

        BlogSubjectData blogSubjectData = new BlogSubjectData();

        String article = "设计模式系列2 策略模式";
        FollowerFirst followerFirst = new FollowerFirst(blogSubjectData);
        FollowerSecond followerSecond = new FollowerSecond(blogSubjectData);
        blogSubjectData.setArticle(article);
        System.out.println("关注者NO2取消关注");
        blogSubjectData.removeFollower(followerSecond);
        article = "设计模式系列3 观察者模式";
        blogSubjectData.setArticle(article);
    

运行输出结果

关注者NO1,你关注的博主有新文章啦,文章名:设计模式系列2 策略模式
关注者NO2,你关注的博主有新文章啦,文章名:设计模式系列2 策略模式
关注者NO2取消关注
关注者NO1,你关注的博主有新文章啦,文章名:设计模式系列3 观察者模式

总结

观察者模式是关于多个对象想知道一个对象中数据变化情况的一种成熟的模式。观察者模式中有一个称作“主题”的对象和若干个称作“观察者”的对象,“主题”和“观察者”间是一种一对多的依赖关系,当“主题”的状态发生变化时,所有“观察者”都得到通知。

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

Observer 观察者模式

观察者设计模式

设计模式之观察者模式

观察者模式

23种设计模式之观察者模式

设计模式学习_气象站观察者模式