第九章 设计模式之观察者模式

观察者模式定义

观察者模式就当多个对象对一个对象存在依赖的时候,这个对象状态的改变需要通知到其他对象的时候,就会用到观察者模式。

观察者模式的好

观察者和被观察者是抽象耦合的

观察者模式主要的类

1.抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。

2.具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。

3.抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。

4.具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。


观察者模式的结构图

粉丝作为观察者,粉丝关注博主的博客,博主负责更新文章然后粉丝收到通知,实现:

/**
 * 
 * @ClassName: Observer
 * @Description: 抽象观察者
 * @author: ljx
 * @date: 2019年4月2日 上午10:22:47
 */
public interface Observer {
	//更新
	public void update(String article);
}
 
/**
 * 
 * @ClassName: Fans
 * @Description: 具体观察者:粉丝
 * @author: ljx
 * @date: 2019年4月2日 上午10:25:37
 */
public class Fans implements Observer {
	
	@Override
	public void update(String article) {
		System.out.println("你关注的博主更新文章了 !文章为 :" + article);
	}
}
 
/**
 * 
 * @ClassName: Fans
 * @Description: 具体观察者:粉丝2
 * @author: ljx
 * @date: 2019年4月2日 上午10:25:37
 */
public class Fans2 implements Observer{
 
	@Override
	public void update(String article) {
		System.out.println("你关注的博主更新文章了 !文章为 :" + article);
	}
 
}
 
/**
 * 
 * @ClassName: Subject
 * @Description: 抽象主题角色
 * @author: ljx
 * @date: 2019年4月2日 上午10:30:30
 */
public abstract class Subject {
	//存放所有观察者对象
	List<Observer> list = new ArrayList<Observer>();
	
	/**
	 * 
	 * @Title: addObserver
	 * @Description: 添加观察者
	 * @param observer
	 * @return: void
	 */
	public void addObserver(Observer observer){
		list.add(observer);
	}
	
	/**
	 * 
	 * @Title: removeObserver
	 * @Description: 移除观察者
	 * @param observer
	 * @return: void
	 */
	public void removeObserver(Observer observer){
		list.remove(observer);
	}
	
	/**
	 * 
	 * @Title: nodifyObserver
	 * @Description: 通知所有观察者
	 * @param article
	 * @return: void
	 */
	public void nodifyObserver(String article){
		for (Observer observer : list) {
			observer.update(article);
		}
	}
}
 
/**
 * 
 * @ClassName: Article
 * @Description: 具体主题角色:作者
 * @author: ljx
 * @date: 2019年4月2日 上午10:39:55
 */
public class Article extends Subject {
	private String article;
 
	public String getArticle() {
		return article;
	}
 
	public void setArticle(String article) {
		this.article = article;
		//通知观察者
		this.nodifyObserver(article);
	}
}
 
public class ObserverTest {
 
	public static void main(String[] args) {
		//创建主题
		Article article = new Article();
		//创建观察者
		Observer fans = new Fans();
		Observer fans2 = new Fans2();
		//创建观察者
		article.addObserver(fans);
		article.addObserver(fans2);
		
		article.setArticle("今天发微博");
 
	}
 
}

 输出结果

你关注的博主更新文章了 !文章为 :今天发微博

你关注的博主更新文章了 !文章为 :今天发微博

在Spring中也有事件发布和事件监听,这也是应用到了观察者,ApplicationContext 中事件处理是由 ApplicationEvent 类和 ApplicationListener 接口来提供的。如果一个Bean实现了 ApplicationListener 接口,并且已经发布到容器中去,每次 ApplicationContext 发布一个 ApplicationEvent 事件,这个Bean就会接到通知

ApplicationContext:事件源,其中的 publishEvent()方法用于触发容器事件
ApplicationEvent:事件本身,自定义事件需要继承该类,可以用来传递数据
ApplicationListener:事件监听器接口,事件的业务逻辑封装在监听器里面
 

@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringListennerTest {


    @Autowired
    private ApplicationContext ctx;


    @Test
    public  void test() {
        SpringExventStar springExventStar = new SpringExventStar(ctx,"王菲谢霆锋","世纪大复合");

        ctx.publishEvent(springExventStar);

    }


}

/**
 * 事件
 */

class SpringExventStar extends ApplicationEvent {
    private String name;
    private String event;
    public SpringExventStar(Object source,String name,String event){
        super(source);
        this.name=name;
        this.event=event;
    }

    public String getName() {
        return name;
    }

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

    public String getEvent() {
        return event;
    }

    public void setEvent(String event) {
        this.event = event;
    }
}


class SpringListennerStar implements ApplicationListener{
    @Override
    public void onApplicationEvent(ApplicationEvent var1){
         if(var1 instanceof SpringExventStar){
             SpringExventStar event = (SpringExventStar)var1;
             System.out.println("明星"+event.getName()+"发生了"+event.getEvent());
         }
    }
}

@Configuration
class SpringListennerConfiguration{

    @Bean
    public SpringListennerStar getSpringListennerStar(){
        return new SpringListennerStar();
    }
}

最后输出:

明星王菲谢霆锋发生了世纪大复合

这次也算弄清楚了spring中的事件监听机制,这个在springboot中被常用到。

参考文章:

https://blog.csdn.net/wwwdc1012/article/details/83317973?spm=1001.2014.3001.5501

https://blog.csdn.net/qq594913801/article/details/88964178?spm=1001.2014.3001.5501

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值