本文已参与「新人创作礼」活动,一起开启掘金创作之路。
观察者模式
一方发生改变时通知多放进行相应的操作
比如: 商人进货了,通知村民商品进货 微信公众号发文章了,通知所有关注者最新的消息
为什么使用观察者模式
- 降低代码耦合度
- 增强扩展性
我认为设计模式是死的但是业务是灵活的,我们需要根据业务灵活使用设计模式,心中无模式代码有模式
观察者模式实践
实现业务: 良民: 张三 李四 劫匪: 张麻子 观察卖大米商人的信息 张三 李四 监听到大米进货前去买大米 张麻子 监听到大米进货带着枪前去零元购
两个接口
/**
* 观察者接口
*
* @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