springboot项目中应用-观察者模式

观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

介绍

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

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

何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决:使用面向对象技术,可以将这种依赖关系弱化。

关键代码:在抽象类里有一个 ArrayList 存放观察者们。

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

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

例子:

需求:项目中要导出一个excl文件,耗时很长,大约在5分钟左右,前端做了一个进度条,如果是假象得进度条也不是很好,我们实现一个真实得进度条。我贴代码。

代码结构

访问层

/**
 * author zgy
 * date 2021/12/16 16:19
 * <p>
 * desc
 */
@RestController
public class ModeController {

    @Autowired
    private ExportReport b;
   	@Autowired
    private ExportReportImpl exportReport;


    /**
     * 这个方法是我们实际导出excl文件得方法
     *
     * @return
     */
    @GetMapping("/test")
    public String test(){
        return  b.export();
    }

    /**
     * 这个方法就是时时进度条
     * 
     * @return
     */
    @GetMapping("/progress")
    public String progress() {
       return exportReport.update();
    }
}

目标和抽象类

/**
 * author zgy
 * date 2021/12/16 16:22
 * <p>
 * desc 这个是观察类抽象类
 */
public abstract class Observer {
    protected Subject subject;
    public abstract String  update();
}
/**
 * author zgy
 * date 2021/12/16 16:23
 * <p>
 * desc 目标类
 */
@Component
public class Subject {
    private List<Observer> observers
            = new ArrayList<Observer>();
    private String state;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
        notifyAllObservers();
    }

    public void attach(Observer observer){
        observers.add(observer);
    }

    public void notifyAllObservers(){
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

service层

/**
 * author zgy
 * date 2021/12/16 16:19
 * <p>
 * desc 数据算法接口类
 */
public interface DataAlgorithm {
    int algorithm();
}
/**
 * author zgy
 * date 2021/12/16 16:20
 * <p>
 * desc 导出报表接口类
 */
public interface ExportReport {
  String export();
}

导出接口实现类

/**
 * author zgy
 * date 2021/12/16 16:21
 * <p>
 * desc 导出实现类,也是观察者,继承了Observer类
 */
@Component
public class ExportReportImpl extends Observer implements ExportReport {

    @Autowired
    private DataAlgorithm a;

    public ExportReportImpl(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public String export() {
        subject.setState("b类开始。。。。。");
        int a1 = a.algorithm();
        try {
            Thread.sleep(3000);
            subject.setState("52%");
            Thread.sleep(3000);
            subject.setState("55%");
            Thread.sleep(3000);
            subject.setState("58%");
            Thread.sleep(3000);
            subject.setState("60%");
            Thread.sleep(3000);
            subject.setState("65%");
            Thread.sleep(3000);
            subject.setState("70%");
            Thread.sleep(3000);
            subject.setState("75%");
            Thread.sleep(3000);
            subject.setState("80%");
            Thread.sleep(3000);
            subject.setState("85%");
            Thread.sleep(3000);
            subject.setState("90%");
            Thread.sleep(3000);
            subject.setState("100%");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (a1==0) {
            return "结果为 0";
        }
        return "结果为 1";
    }

    @Override
    public String update() {
        return  subject.getState();
    }
}

算法用算的接口实现类

/**
 * author zgy
 * date 2021/12/16 16:21
 * <p>
 * desc 算法实现类,也是观察着Observer
 */
@Component
public class DataAlgorithmImpl extends Observer implements DataAlgorithm {

    public DataAlgorithmImpl(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }


    @Override
    public int algorithm() {
        subject.setState("0%");
        try {
            Thread.sleep(3000);
            subject.setState("10%");
            Thread.sleep(3000);
            subject.setState("20%");
            Thread.sleep(3000);
            subject.setState("30%");
            Thread.sleep(3000);
            subject.setState("40%");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 0;
    }

    @Override
    public String update() {
        return subject.getState();
    }
}

导出按钮调用了:http://localhost:8080/test接口,

前端轮询调用进度条接口获取实时进度:http://localhost:8080/progress

测试结果:

总结:所有一切的设计模式都是关于多态的应用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值