设计模式:5.观察者模式(发布订阅)

观察者模式

观察者模式属于行为型模式,又叫发布订阅模式

定义:

​ 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新

模式类图
在这里插入图片描述
角色:

  1. 被观察者:Subject定义一个被观察者必须实现职责,包括动态增加,删除,通知观察者
  2. 观察者:Observer接受到观察者修改消息,执行自身逻辑
  3. 具体观察者:ConctreteSubject继承Subject,拥有自己的业务逻辑,具有被观察者基本功能,对某些事件进行通知
  4. 具体的观察者:ConcreteObserver具体观察者,在接受到被观察者变更消息后,进行各自业务处理

优点

  1. 观察者和被观察者之间是抽象耦合,容易拓展

  2. 通过触发机制可以创建成一种链式触发机制,形成多级触发

    缺点

  3. 执行效率
    当通知观察者是顺序执行时,需要考虑整个观察者列表的数量,对整个通知事件执行效率的影响,可以考虑使用异步通知,同时尽量避免多级触发事件

  4. 循环依赖
    当观察者和被观察之间形成循环依赖,会导致循环调用,比如A改变通知B,B改变通知C,C改变通知A,注意避免循环依赖的发生

被观察者接口
Subjectable 定义被观察者基本功能

public interface Subjectable {

    /**
     * 增加观察者
     */
    void addObserver(Observerable observer);

    /**
     * 移除观察者
     */
    void removeObserver(Observerable observer);

    /**
     * 通知观察者
     */
    void notifyObserver(Object object);
}

被观察者抽象类
AbstractSubject被观察者类的公共父类,实现了被观察者基本功能的实现,使用Vector为观察者列表

public abstract class AbstractSubject implements Subjectable{

    /**
     * 观察者列表
     */
    private Vector<Observerable> observers = new Vector();

    @Override
    public void addObserver(Observerable observer){
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observerable observer){
        observers.add(observer);
    }

    @Override
    public void notifyObserver(Object object){
        observers.forEach(observer->{
            observer.update(object);
        });
    }
}

被观察者类
UserInfo实现AbstractSubject

@Data
public class UserInfo extends AbstractSubject{

    /**
     * 暱称
     */
    private String nickName;
    /**
     * 密码
     */
    private String password;

    /**
     * 修改密码
     * @param password
     */
    public void updatePassword(String password){
        this.password = password;
        this.notifyObserver(password);
    }

    public UserInfo(String nickName, String password) {
        this.nickName = nickName;
        this.password = password;
    }
}

观察者接口

public interface Observerable {

    /**
     * 被观察者变化触发事件
     */
    void update(Object object);
}

具体观察者
SmsObserver 接收到被观察者密码变更,发送短信提醒

public class SmsObserver implements Observerable {

    @Override
    public void update(Object object) {
        if(null == object){
            return;
        }
        System.out.println("短信观察者");
        System.out.println("短信发送提醒:密码更改为:"+object.toString());
    }
}

EmailObserver 接收到被观察者密码变更,发送邮件提醒

public class EmailObserver implements Observerable{

    @Override
    public void update(Object object) {
        if(null == object){
            return;
        }
        System.out.println("邮件观察者");
        System.out.println("邮件发送提醒:密码更改为:"+object.toString());
    }
}

验证

public static void main(String[] args) {

    UserInfo userInfo = new UserInfo("麻辣香锅","malaxiangguo");

    SmsObserver smsObserver = new SmsObserver();
    EmailObserver emailObserver = new EmailObserver();

    userInfo.addObserver(smsObserver);
    userInfo.addObserver(emailObserver);

    userInfo.updatePassword("mlxg");
}

输出

短信观察者
短信发送提醒:密码更改为:mlxg
邮件观察者
邮件发送提醒:密码更改为:mlxg

SmsObserver和EmailObserver观察到UserInfo用户麻辣香锅更改密码为mlxg

参考:设计模式之禅:https://www.kancloud.cn/sstd521/design/193589

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章