探测器-观察者模式

探测器:探头可灵活组装;安装不同探头组合,可组装出不同的探测器;

策略模式通过条件选择适合的处理过程(其中条件判断比较简单,逻辑主要在处理过程里),观察者模式则是通过一些因素判断是否满足条件(其中所有的逻辑都是为了作出判定,得到判定结果即结束),两者可认为是相辅相成的

复杂情景下的 策略+观察者模式:
一、使用观察者模式进行条件判定
二、使用策略模式进行数据的具体逻辑处理

探测器接口

package pers.zuo.component.detector;

import com.sun.istack.internal.NotNull;
import pers.zuo.component.detector.probe.IProbe;

import java.util.Set;

/**
 * @author zuojingang
 * @Title: IDetector
 * @Description: 探测器统一接口
 * @date 2019-08-08 15:20
 */
public interface IDetector {

    /**
     * 安装探头
     *
     * @param probes
     */
    void install(@NotNull IProbe... probes);

    /**
     * 卸载探头
     *
     * @param probe
     */
    void uninstall(@NotNull IProbe probe);

    /**
     * 执行检测
     *
     * @return
     */
    Boolean detect();

    /**
     * 亮灯,将检测成功的探头放入命中列表
     *
     * @param probe
     */
    void lightUp(@NotNull IProbe probe);

    /**
     * 命中的探头列表
     *
     * @return
     */
    Set<IProbe> signalProbes();
}

探头接口

package pers.zuo.component.detector.probe;

import pers.zuo.component.detector.IDetector;

/**
 * @author zuojingang
 * @Title: Probe
 * @Description: 探头统一接口
 * @date 2019-08-08 15:31
 */
public interface IProbe {

    /**
     * 安装探测器
     *
     * @param detector
     */
    void setDetector(IDetector detector);

    /**
     * 执行探测
     *
     * @return
     */
    Boolean detect();

    /**
     * 执行亮灯探测
     */
    void detectWithLight();
}

判定器接口

package pers.zuo.component.detector.probe.judge;

/**
 * @author zuojingang
 * @Title: IJudge
 * @Description: 判定器
 * @date 2019-08-12 09:29
 */
public interface IJudge {
    /**
     * 判定逻辑
     *
     * @return
     */
    Boolean doJudgment();
}

探测器快照

package pers.zuo.component.detector.snapshot;

import pers.zuo.component.detector.probe.IProbe;

import java.util.Set;

/**
 * @author zuojingang
 * @Title: DetectorSnapshot
 * @Description: 探测器快照,包含每次使用探测器的状态
 * @date 2019-08-09 09:48
 */
public class DetectorSnapshot {

    private Set<IProbe> installedProbes;
    private Set<IProbe> signalProbes;

    public Set<IProbe> getInstalledProbes() {
        return installedProbes;
    }

    public void setInstalledProbes(Set<IProbe> installedProbes) {
        this.installedProbes = installedProbes;
    }

    public Set<IProbe> getSignalProbes() {
        return signalProbes;
    }

    public void setSignalProbes(Set<IProbe> signalProbes) {
        this.signalProbes = signalProbes;
    }
}

探测器实现

package pers.zuo.component.detector.impl;

import com.sun.istack.internal.NotNull;
import pers.zuo.component.detector.IDetector;
import pers.zuo.component.detector.probe.IProbe;
import pers.zuo.component.detector.snapshot.DetectorSnapshot;

import java.util.HashSet;
import java.util.Set;

/**
 * @author zuojingang
 * @Title: Detector
 * @Description: 探测器的实现类
 * @date 2019-08-08 15:23
 */
public class Detector implements IDetector {

    private ThreadLocal<DetectorSnapshot> snapshot = ThreadLocal.withInitial(() -> {
        DetectorSnapshot snapshot = new DetectorSnapshot();
        snapshot.setInstalledProbes(new HashSet<>());
        snapshot.setSignalProbes(new HashSet<>());
        return snapshot;
    });

    @Override
    public void install(@NotNull IProbe... probes) {
        if (0 == probes.length) {
            return;
        }
        for (IProbe probe : probes) {
            snapshot.get().getInstalledProbes().add(probe);
            probe.setDetector(this);
        }
    }

    @Override
    public void uninstall(@NotNull IProbe probe) {
        snapshot.get().getInstalledProbes().remove(probe);
        probe.setDetector(null);
    }

    @Override
    public Boolean detect() {
        if (snapshot.get().getInstalledProbes().isEmpty()) {
            return false;
        }
        snapshot.get().getInstalledProbes().forEach(IProbe::detectWithLight);
        return !snapshot.get().getSignalProbes().isEmpty();
    }

    @Override
    public void lightUp(@NotNull IProbe probe) {
        if (!snapshot.get().getInstalledProbes().contains(probe)) {
            return;
        }
        snapshot.get().getSignalProbes().add(probe);
    }

    @Override
    public Set<IProbe> signalProbes() {
        return snapshot.get().getSignalProbes();
    }
}

探头快照

package pers.zuo.component.detector.probe.snapshot;

import pers.zuo.component.detector.IDetector;

/**
 * @author zuojingang
 * @Title: ProbeSnapshot
 * @Description: 探头快照,包含每次使用探头的状态
 * @date 2019-08-09 10:20
 */
public class ProbeSnapshot {

    private IDetector detector;

    public IDetector getDetector() {
        return detector;
    }

    public void setDetector(IDetector detector) {
        this.detector = detector;
    }
}

探头实现

package pers.zuo.component.detector.probe.impl;

import com.sun.istack.internal.NotNull;
import pers.zuo.component.detector.IDetector;
import pers.zuo.component.detector.probe.IProbe;
import pers.zuo.component.detector.probe.judge.IJudge;
import pers.zuo.component.detector.probe.snapshot.ProbeSnapshot;

import java.util.Objects;

/**
 * @author zuojingang
 * @Title: Probe
 * @Description: 探头实现
 * @date 2019-08-08 15:53
 */
public class Probe implements IProbe {

    private ThreadLocal<ProbeSnapshot> snapshot = ThreadLocal.withInitial(ProbeSnapshot::new);
    private IJudge judge;

    /**
     * 一个探头有且仅有一个判定逻辑
     *
     * @param judge
     */
    public Probe(@NotNull IJudge judge) {
        this.judge = judge;
    }

    @Override
    public void setDetector(IDetector detector) {
        snapshot.get().setDetector(detector);
    }

    @Override
    public Boolean detect() {
        return judge.doJudgment();
    }

    @Override
    public void detectWithLight() {
        IDetector detector = snapshot.get().getDetector();
        if (Objects.isNull(detector)) {
            return;
        }
        Boolean detect = this.detect();
        if (Objects.isNull(detect) || !detect) {
            return;
        }
        detector.lightUp(this);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值