
正文
观察者模式--java
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
写在前面
钩子函数、注册函数、回调函数,他们的概念其实是一样的。
观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察者知道情况,其实是由目标奖情况发送到观察者的。
观察者模式多用于实现订阅功能的场景,例如微博的订阅,当我们订阅了某个人的微博账号,当这个人发布了新的消息,就会通知我们。
观察者模式警匪电影版
观察者接口 (观察者可能是警察,也可能是线人)
public interface Observer {
void report(String message,String name);
}
观察者实现类 (警察)
public class Policeman implements Observer {
private String name;
Policeman(String name){this.name = name;}
@Override
public void report(String message, String name) {
System.out.println(this.name+"发现"+name+":"+message);
}
}
观察者实现类(线人)
public class Informers implements Observer {
private String name;
Informers(String name){this.name = name;}
@Override
public void report(String message, String name) {
System.out.println(this.name+"发现"+name+":"+message);
}
}
被观察者(坏人) 接口 (具体可能是 小偷,毒贩等。。。)
public interface BadGuy {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void doSomething(String message);
}
小偷
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Thief implements BadGuy {
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
private String name;
Thief(String name){this.name = name;}
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+" : "+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
毒贩
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Dealer implements BadGuy {
private String name;
Dealer(String name){this.name = name;}
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+":"+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
最后测试一下
public class ObserverDemo {
public static void main(String [] args){
Observer policeman = new Policeman("李警官");
Observer informers = new Informers("线人A");
BadGuy thief = new Thief("小偷甲");
BadGuy dealer = new Dealer("毒贩阿尔法");
thief.addObserver(policeman);
thief.addObserver(informers);
thief.doSomething("此处人傻钱多速来");
dealer.addObserver(policeman);
dealer.addObserver(informers);
dealer.doSomething("新货已到达...");
//线人被毒贩发现被干掉
dealer.removeObserver(informers);
dealer.doSomething("线人被干掉了!");
//警察被毒贩发现牺牲了
dealer.removeObserver(policeman);
dealer.doSomething("警察也牺牲了!");
dealer.doSomething("现在我可以无法无天了。。。哈哈哈哈!!!");
new Runnable() {
@Override
public void run() {
try{
Thread.sleep(1000);
System.out.println("天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。");
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}.run();
}
}
结果
小偷甲 : 此处人傻钱多速来
李警官发现小偷甲:此处人傻钱多速来
线人A发现小偷甲:此处人傻钱多速来
毒贩阿尔法:新货已到达...
李警官发现毒贩阿尔法:新货已到达...
线人A发现毒贩阿尔法:新货已到达...
毒贩阿尔法:线人被干掉了!
李警官发现毒贩阿尔法:线人被干掉了!
毒贩阿尔法:警察也被干掉了!
毒贩阿尔法:现在我可以无法无天了。。。哈哈哈哈!!!
天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。
总结
关键点:
1、针对观察者与被观察者分别定义接口,有利于分别进行扩展。
2、重点就在被观察者的实现中:
(1)定义观察者集合,并定义针对集合的添加、删除操作,用于增加、删除订阅者(观察者)
(2)定义通知方法,用于将新情况通知给观察者用户(订阅者用户)
3、观察者中需要有个接收被观察者通知的方法。
public interface Observer {
void report(String message,String name);
}
观察者实现类 (警察)
public class Policeman implements Observer {
private String name;
Policeman(String name){this.name = name;}
@Override
public void report(String message, String name) {
System.out.println(this.name+"发现"+name+":"+message);
}
}
观察者实现类(线人)
public class Informers implements Observer {
private String name;
Informers(String name){this.name = name;}
@Override
public void report(String message, String name) {
System.out.println(this.name+"发现"+name+":"+message);
}
}
被观察者(坏人) 接口 (具体可能是 小偷,毒贩等。。。)
public interface BadGuy {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void doSomething(String message);
}
小偷
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Thief implements BadGuy {
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
private String name;
Thief(String name){this.name = name;}
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+" : "+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
毒贩
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Dealer implements BadGuy {
private String name;
Dealer(String name){this.name = name;}
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+":"+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
最后测试一下
public class ObserverDemo {
public static void main(String [] args){
Observer policeman = new Policeman("李警官");
Observer informers = new Informers("线人A");
BadGuy thief = new Thief("小偷甲");
BadGuy dealer = new Dealer("毒贩阿尔法");
thief.addObserver(policeman);
thief.addObserver(informers);
thief.doSomething("此处人傻钱多速来");
dealer.addObserver(policeman);
dealer.addObserver(informers);
dealer.doSomething("新货已到达...");
//线人被毒贩发现被干掉
dealer.removeObserver(informers);
dealer.doSomething("线人被干掉了!");
//警察被毒贩发现牺牲了
dealer.removeObserver(policeman);
dealer.doSomething("警察也牺牲了!");
dealer.doSomething("现在我可以无法无天了。。。哈哈哈哈!!!");
new Runnable() {
@Override
public void run() {
try{
Thread.sleep(1000);
System.out.println("天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。");
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}.run();
}
}
结果
小偷甲 : 此处人傻钱多速来
李警官发现小偷甲:此处人傻钱多速来
线人A发现小偷甲:此处人傻钱多速来
毒贩阿尔法:新货已到达...
李警官发现毒贩阿尔法:新货已到达...
线人A发现毒贩阿尔法:新货已到达...
毒贩阿尔法:线人被干掉了!
李警官发现毒贩阿尔法:线人被干掉了!
毒贩阿尔法:警察也被干掉了!
毒贩阿尔法:现在我可以无法无天了。。。哈哈哈哈!!!
天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。
总结
关键点:
1、针对观察者与被观察者分别定义接口,有利于分别进行扩展。
2、重点就在被观察者的实现中:
(1)定义观察者集合,并定义针对集合的添加、删除操作,用于增加、删除订阅者(观察者)
(2)定义通知方法,用于将新情况通知给观察者用户(订阅者用户)
3、观察者中需要有个接收被观察者通知的方法。
public class Policeman implements Observer {
private String name;
Policeman(String name){this.name = name;}
@Override
public void report(String message, String name) {
System.out.println(this.name+"发现"+name+":"+message);
}
}
public class Informers implements Observer {
private String name;
Informers(String name){this.name = name;}
@Override
public void report(String message, String name) {
System.out.println(this.name+"发现"+name+":"+message);
}
}
被观察者(坏人) 接口 (具体可能是 小偷,毒贩等。。。)
public interface BadGuy {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void doSomething(String message);
}
小偷
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Thief implements BadGuy {
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
private String name;
Thief(String name){this.name = name;}
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+" : "+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
毒贩
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Dealer implements BadGuy {
private String name;
Dealer(String name){this.name = name;}
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+":"+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
最后测试一下
public class ObserverDemo {
public static void main(String [] args){
Observer policeman = new Policeman("李警官");
Observer informers = new Informers("线人A");
BadGuy thief = new Thief("小偷甲");
BadGuy dealer = new Dealer("毒贩阿尔法");
thief.addObserver(policeman);
thief.addObserver(informers);
thief.doSomething("此处人傻钱多速来");
dealer.addObserver(policeman);
dealer.addObserver(informers);
dealer.doSomething("新货已到达...");
//线人被毒贩发现被干掉
dealer.removeObserver(informers);
dealer.doSomething("线人被干掉了!");
//警察被毒贩发现牺牲了
dealer.removeObserver(policeman);
dealer.doSomething("警察也牺牲了!");
dealer.doSomething("现在我可以无法无天了。。。哈哈哈哈!!!");
new Runnable() {
@Override
public void run() {
try{
Thread.sleep(1000);
System.out.println("天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。");
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}.run();
}
}
结果
小偷甲 : 此处人傻钱多速来
李警官发现小偷甲:此处人傻钱多速来
线人A发现小偷甲:此处人傻钱多速来
毒贩阿尔法:新货已到达...
李警官发现毒贩阿尔法:新货已到达...
线人A发现毒贩阿尔法:新货已到达...
毒贩阿尔法:线人被干掉了!
李警官发现毒贩阿尔法:线人被干掉了!
毒贩阿尔法:警察也被干掉了!
毒贩阿尔法:现在我可以无法无天了。。。哈哈哈哈!!!
天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。
总结
关键点:
1、针对观察者与被观察者分别定义接口,有利于分别进行扩展。
2、重点就在被观察者的实现中:
(1)定义观察者集合,并定义针对集合的添加、删除操作,用于增加、删除订阅者(观察者)
(2)定义通知方法,用于将新情况通知给观察者用户(订阅者用户)
3、观察者中需要有个接收被观察者通知的方法。
public interface BadGuy {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void doSomething(String message);
}
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Thief implements BadGuy {
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
private String name;
Thief(String name){this.name = name;}
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+" : "+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
毒贩
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Dealer implements BadGuy {
private String name;
Dealer(String name){this.name = name;}
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+":"+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
最后测试一下
public class ObserverDemo {
public static void main(String [] args){
Observer policeman = new Policeman("李警官");
Observer informers = new Informers("线人A");
BadGuy thief = new Thief("小偷甲");
BadGuy dealer = new Dealer("毒贩阿尔法");
thief.addObserver(policeman);
thief.addObserver(informers);
thief.doSomething("此处人傻钱多速来");
dealer.addObserver(policeman);
dealer.addObserver(informers);
dealer.doSomething("新货已到达...");
//线人被毒贩发现被干掉
dealer.removeObserver(informers);
dealer.doSomething("线人被干掉了!");
//警察被毒贩发现牺牲了
dealer.removeObserver(policeman);
dealer.doSomething("警察也牺牲了!");
dealer.doSomething("现在我可以无法无天了。。。哈哈哈哈!!!");
new Runnable() {
@Override
public void run() {
try{
Thread.sleep(1000);
System.out.println("天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。");
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}.run();
}
}
结果
小偷甲 : 此处人傻钱多速来
李警官发现小偷甲:此处人傻钱多速来
线人A发现小偷甲:此处人傻钱多速来
毒贩阿尔法:新货已到达...
李警官发现毒贩阿尔法:新货已到达...
线人A发现毒贩阿尔法:新货已到达...
毒贩阿尔法:线人被干掉了!
李警官发现毒贩阿尔法:线人被干掉了!
毒贩阿尔法:警察也被干掉了!
毒贩阿尔法:现在我可以无法无天了。。。哈哈哈哈!!!
天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。
总结
关键点:
1、针对观察者与被观察者分别定义接口,有利于分别进行扩展。
2、重点就在被观察者的实现中:
(1)定义观察者集合,并定义针对集合的添加、删除操作,用于增加、删除订阅者(观察者)
(2)定义通知方法,用于将新情况通知给观察者用户(订阅者用户)
3、观察者中需要有个接收被观察者通知的方法。
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class Dealer implements BadGuy {
private String name;
Dealer(String name){this.name = name;}
Queue<Observer> queue = new LinkedBlockingQueue<Observer>();
@Override
public void addObserver(Observer observer) {
if(!queue.contains(observer)){
queue.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if(queue.contains(observer)){
queue.remove(observer);
}
}
@Override
public void doSomething(String message) {
System.out.println(this.name+":"+message);
for(Observer observer:queue){
observer.report(message,this.name);
}
}
}
public class ObserverDemo {
public static void main(String [] args){
Observer policeman = new Policeman("李警官");
Observer informers = new Informers("线人A");
BadGuy thief = new Thief("小偷甲");
BadGuy dealer = new Dealer("毒贩阿尔法");
thief.addObserver(policeman);
thief.addObserver(informers);
thief.doSomething("此处人傻钱多速来");
dealer.addObserver(policeman);
dealer.addObserver(informers);
dealer.doSomething("新货已到达...");
//线人被毒贩发现被干掉
dealer.removeObserver(informers);
dealer.doSomething("线人被干掉了!");
//警察被毒贩发现牺牲了
dealer.removeObserver(policeman);
dealer.doSomething("警察也牺牲了!");
dealer.doSomething("现在我可以无法无天了。。。哈哈哈哈!!!");
new Runnable() {
@Override
public void run() {
try{
Thread.sleep(1000);
System.out.println("天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。");
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}.run();
}
}
结果
小偷甲 : 此处人傻钱多速来
李警官发现小偷甲:此处人傻钱多速来
线人A发现小偷甲:此处人傻钱多速来
毒贩阿尔法:新货已到达...
李警官发现毒贩阿尔法:新货已到达...
线人A发现毒贩阿尔法:新货已到达...
毒贩阿尔法:线人被干掉了!
李警官发现毒贩阿尔法:线人被干掉了!
毒贩阿尔法:警察也被干掉了!
毒贩阿尔法:现在我可以无法无天了。。。哈哈哈哈!!!
天降正义!!! 毒贩被一位不愿意透露姓名的大佬带走。。。
总结
关键点:
1、针对观察者与被观察者分别定义接口,有利于分别进行扩展。
2、重点就在被观察者的实现中:
(1)定义观察者集合,并定义针对集合的添加、删除操作,用于增加、删除订阅者(观察者)
(2)定义通知方法,用于将新情况通知给观察者用户(订阅者用户)
3、观察者中需要有个接收被观察者通知的方法。







