java设计模式 第二章:观察者模式

84 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

观察者模式

一方发生改变时通知多放进行相应的操作

比如: 商人进货了,通知村民商品进货 微信公众号发文章了,通知所有关注者最新的消息

为什么使用观察者模式

  1. 降低代码耦合度
  2. 增强扩展性

我认为设计模式是死的但是业务是灵活的,我们需要根据业务灵活使用设计模式,心中无模式代码有模式

观察者模式实践

实现业务: 良民: 张三 李四 劫匪: 张麻子 观察卖大米商人的信息 张三 李四 监听到大米进货前去买大米 张麻子 监听到大米进货带着枪前去零元购

两个接口

/**
 * 观察者接口
 *
 * @author shenc
 * @date 2021-11-27 14:23
 **/
public interface IObserver {

    /**
     * 观察者名称
     *
     * @return
     */
    void setName(String name);

    /**
     * 接收通知接口
     *
     * @param name 名称
     * @param msg  消息
     */
    void receive(String name, String msg);
}

/**
 * 被观察对象接口
 *
 * @author shenc
 * @date 2021-11-27 14:19
 **/
public interface ISubject {

    /**
     * 被观察对象名称
     *
     * @return
     */
    void setName(String name);

    /**
     * 添加一个观察者
     * @param observer
     */
    void addObserver(IObserver observer);

    /**
     * 通知所有观察者
     */
    void notifyAllObservers(String msg);
}

三个实现类


/**
 * 卖大米商人
 *
 * @author shenc
 * @date 2021-11-27 14:56
 **/
public class Merchant implements ISubject {

    List<IObserver> observerList = new ArrayList<>();

    private String name;

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

    @Override
    public void addObserver(IObserver observer) {
        observerList.add(observer);
    }

    public void addGoods(){
        this.notifyAllObservers("大米进货了");
    }

    @Override
    public void notifyAllObservers(String msg) {
        for (IObserver iObserver : observerList) {
            iObserver.receive(name,msg);
        }

    }
}
/**
 * 买大米的人
 *
 * @author shenc
 * @date 2021-11-27 15:00
 **/
public class People implements IObserver {

    /**
     * 监听者名称
     */
    private String peopleName;

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

    public void setObsName(String obsName) {
        this.peopleName = obsName;
    }

    @Override
    public void receive(String name, String msg) {
        // 接收到通知
        System.out.println("良民: " + this.peopleName + "接收到" + name + "的消息: " + msg);
        // 张三行动
        System.out.println(this.peopleName + ": 带钱去买大米");
    }
}

/**
 * 劫匪
 *
 * @author shenc
 * @date 2021-11-27 15:16
 **/
public class Robber implements IObserver {

    /**
     * 劫匪名称
     */
    private String robberName;

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

    @Override
    public void receive(String name, String msg) {
        // 接收到通知
        System.out.println("劫匪: " + this.robberName + "接收到" + name + "的消息: " + msg);
        // 张三行动
        System.out.println(this.robberName + ": 带着枪前去零元购");
    }
}

进行单元测试

	/**
     * 测试场景:
     * 良民: 张三 李四 劫匪: 张麻子 观察卖大米商人的信息
     * 张三 李四 监听到大米进货前去买大米
     * 张麻子 监听到大米进货带着枪前去零元购
     */
    @Test
    public void test1() {

        Merchant m = new Merchant();
        m.setName("卖大米的");

        IObserver zhangSan = new People();
        zhangSan.setName("张三");
        m.addObserver(zhangSan);
        IObserver liSi = new People();
        liSi.setName("李四");
        m.addObserver(liSi);

        IObserver maZi = new Robber();
        maZi.setName("张麻子");
        m.addObserver(maZi);

        m.addGoods();
    }

输出结果:

良民: 张三接收到卖大米的的消息: 大米进货了
张三: 带钱去买大米
良民: 李四接收到卖大米的的消息: 大米进货了
李四: 带钱去买大米
劫匪: 张麻子接收到卖大米的的消息: 大米进货了
张麻子: 带着枪前去零元购

代码地址: giee