首页 > 其他 > 详细

观察者模式

时间:2021-02-21 23:43:10      阅读:28      评论:0      收藏:0      [点我收藏+]

一、前言

设计模式是软件设计中常见问题的典型解决方案。它们就像能根据需求进行调整的预制蓝图,可用于解决代码中反复出现的设计问题。

设计模式与方法或库的使用方式不同,你很难直接在自己的程序中套用某个设计模式。模式并不是一段特定的代码,而是解决特定问题的一般性概念。你可以根据模式来实现符合自己程序实际所需的解决方案。

模式像是蓝图,你可以看到最终的结果和模式的功能,但需要自己确定实现步骤。

在了解什么是观察者模式之前,首先要明白接口和抽象类之间的区别,设计模式当中大量使用了它们来抽象现实中的事物,我认为计算机编程就是一个抽象化的过程。

问题:人属于一种抽象的集合,那就可以把人给变成抽象类,至于具体到哪一个人就extend抽象类。人都有公共的动作,比如吃饭、睡觉等,但是不同的人有不一样的能力,比如小明会制作工艺品,小红会绘画。那这些特定的方法写在抽象类就不合适了,因为一旦extend了抽象类,所有人就都具备了这些特定的能力,显然是不合适的。因此,需要单独把这些特定的方法给抽取到interface中。小明会制作工艺品就implements即可。

public abstract class Human {

    private String name;

    private int age;

    public abstract void eat();

    public abstract void sleep();
}

public interface Draw {

    void paint();
}

public interface Make {

    void makeFlower();
}

public class XiaoHong extends Human implements Make {

    @Override
    public void eat() {
        System.out.println("eat");
    }
    
    @Override
    public void sleep() {
        System.out.println("sleep");
    }

    @Override
    public void makeFlower() {
        System.out.println("make flower");
    }
}

public class XiaoMing extends Human implements Draw{

    @Override
    public void eat() {
        System.out.println("eat");
    }

    @Override
    public void sleep() {
        System.out.println("sleep");
    }
    
     @Override
    public void paint() {
        System.out.println("paint");
    }
}

技术分享图片

二、原理与案例

我们利用微信公众号的现实例子来实现观察者模式,首先订阅者要先订阅公众号,如果公众号要对每一个订阅者群发消息,就需要挨个挨个地发送给他们。问题来了,订阅者如何订阅公众号,公众号如何对每一个订阅者群发消息?在代码层面上考虑就是,在公众号中创建一个集合来存储每一个订阅者对象,然后遍历循环集合并调用订阅者的update方法。订阅者在创建之初,可以使用构造器来添加公众号对象进去,就实现了订阅者监听公众号是否有群发消息,如果群发了,不仅我能收到,其他人也能收到。


技术分享图片

现在需要两个对象,一个是Observer抽象类,另一个是Subject类(理解为公众号),其他具体观察者就继承Observer抽象类。

Subject内存储每一个Observer,在notifyAllObserver方法内部循环集合并调用Observer的update方法来群发消息。观察者执行update方法获取群发消息。

三、代码实现

public class Subject {

    // 公众号存储所有订阅者
    public List<Observer> observers = new ArrayList<>();
    // 公众号的名称
    private String name;
    // 公众号的消息
    private String content;

    // 添加订阅
    public void attach(Observer observer) {
        if (observer != null) observers.add(observer);
    }

    // 删除订阅
    public void detach(Observer observer) {
        if (observers.indexOf(observer) > 0) observers.remove(observer);
    }

    // 对每一个订阅者群发消息
    public void notifyAllObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
    
    public void setName(String name) {
        this.name = name;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getName() {
        return name;
    }

    public String getContent() {
        return content;
    }

}
public abstract class Observer {

    // 公众号对象
    protected Subject subject;
    
    // 更新消息
    public abstract void update();

}
public class SubscribeObserver extends Observer {

    // 观察公众号
    public SubscribeObserver(Subject subject) {
        this.subject = subject;
        subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("[ " + subject.getName() + " ] 群发了一条消息:" + subject.getContent());
    }
}
public class Test {

    public static void main(String[] args) {
        Subject subject = new Subject();
        subject.setContent("恭喜kongsam用户中了一等奖!");
        subject.setName("XX公众号");
        subject.notifyAllObservers();
        SubscribeObserver xiaoming = new SubscribeObserver(subject);
        xiaoming.update();
        SubscribeObserver xiaohong = new SubscribeObserver(subject);
        xiaohong.update();
        SubscribeObserver xiaowang = new SubscribeObserver(subject);
        xiaowang.update();
    }

}
[ XX公众号 ] 群发了一条消息:恭喜kongsam用户中了一等奖!
[ XX公众号 ] 群发了一条消息:恭喜kongsam用户中了一等奖!
[ XX公众号 ] 群发了一条消息:恭喜kongsam用户中了一等奖!

参考文献:

【1】Refactoring.Guru

【2】Design Patterns - Observer Pattern

观察者模式

原文:https://www.cnblogs.com/kongsam/p/14426757.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!