【设计模式】观察者模式

观察者模式,也叫发布-订阅模式,定义了一种一对多的关系,多个观察者可以同时监听某一个主题,这个主题的对象的状态发生变化时,会通知所有的观察者对象

类图

在这里插入图片描述

工程目录

在这里插入图片描述

代码

AbstractSubject.java

package com.company.pattern.demo10;

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

/**
 * 主题、抽象通知者
 * @author blazar
 */
public abstract class AbstractSubject {
    private List<MyObserver> myObservers = new ArrayList<>();

    /**
     * 增加观察者
     * @param myObserver
     */
    public void attach(MyObserver myObserver){
        myObservers.add(myObserver);
    }

    /**
     * 移除观察者
     * @param myObserver
     */
    public void detach(MyObserver myObserver){
        myObservers.remove(myObserver);
    }

    public void myNotify(){
        for(MyObserver myObserver : myObservers){
            myObserver.update();
        }
    }
}

MyObserver.java

package com.company.pattern.demo10;

/**
 * 观察者接口
 * @author blazar
 */
public interface MyObserver {
    /**
     * 更新方法
     */
    void update();
}

ConcreteSubject.java

package com.company.pattern.demo10;

/**
 * 具体主题、具体通知者
 * @author blazar
 */
public class ConcreteSubject extends AbstractSubject{
    /**
     * 具体被观察者状态
     */
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
    }
}

ConcreteObserver.java

package com.company.pattern.demo10;

/**
 * 具体观察者
 * @author blazar
 */
public class ConcreteObserver implements MyObserver {
    private String name;
    private String observerState;
    private ConcreteSubject subject;

    public ConcreteObserver(String name, ConcreteSubject subject) {
        this.name = name;
        this.subject = subject;
    }

    @Override
    public void update() {
        observerState = subject.getSubjectState();
        System.out.println(String.format("观察者%s的新状态是%s", name, observerState));
    }

    public String getName() {
        return name;
    }

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

    public String getObserverState() {
        return observerState;
    }

    public void setObserverState(String observerState) {
        this.observerState = observerState;
    }

    public ConcreteSubject getSubject() {
        return subject;
    }

    public void setSubject(ConcreteSubject subject) {
        this.subject = subject;
    }
}

测试类 Main.java

package com.company.pattern.demo10;

/**
 * 测试类
 * @author blazar
 */
public class Main {
    public static void main(String[] args) {
        ConcreteSubject concreteSubject = new ConcreteSubject();

        concreteSubject.attach(new ConcreteObserver("X", concreteSubject));
        concreteSubject.attach(new ConcreteObserver("Y", concreteSubject));

        concreteSubject.setSubjectState("ABC");

        concreteSubject.myNotify();
    }
}

在这里插入图片描述

使用场景

  1. 观察者模式是为了维护不同类的相关对象的一致性而产生的;我们不希望为维持一致性而使各类紧密耦合,这样会给维护、扩展和重用带来麻烦;
  2. 观察者模式让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化不会直接影响到另一边;

缺陷

上边说过,观察者模式是将原来对象之间的直接耦合改成了对象所实现的接口之间的耦合;接口之间依然是需要耦合的;但是如果一些类没有实现抽象观察者的接口,就没法被通知到了啊。

改进方法

不同的语言引入了不同的机制解决这个问题,如:C#中的委托机制,这里涉及到语言细节,暂不做描述。

参考《大话设计模式》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值