天天看点

(1)观察者模式

使用场景:举个书籍订阅的例子。杂志社提供数据订阅服务,有数学老师,英语老师在杂志社订阅了书籍。当快递员把书籍送到学校保卫处的时候就告诉位老师。说某老师,你订阅的XX给你送到了保卫处,你可以去取了。对应起来看快递员(Subject), 老师(Observer)。

实现:我们来看看这个模式是怎么实现的。快递员怎么会给这两位老师送书呢,要订阅登记啊(register注册)。书送到了要干什么呀(notice通知),几个月之后英语老师说我不订了(remove移除)。这事谁在干,快递员,OK这三个方法就放在Subject接口了。老师干什么呀,老师收到书之后回家看(read)呗。这个方法就在Observer了。

在实际开发中获取数据的方式需要我们根据具体的业务逻辑进行合适的处理,可Subject主动推送,也可由Observer主动获取。当然还有种内置模式

下面我看代码:

1.被观察对象(Subject)

public interface Subject {
	
	void register(Observer o);
	
	void notice(Book book);
	
	void remove(Observer o);
	
	Book bookChange(String bookname, float price, int state);
}
           

2.观察者(Observer)

public interface Observer {
	
	void read(Book book);
	
}
           

3.快递员(Postman)

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Postman implements Subject{
	
	private static List<Observer> list;
	
	public Postman(){
		if(null == list) list = new ArrayList<Observer>();
	}

	/**
	 * 注册观测者
	 */
	@Override
	public void register(Observer o) {
		list.add(o);
	}
	
	/**
	 * 通知观察者
	 */
	@Override
	public void notice(Book book) {
		for (Iterator<Observer> iterator = list.iterator(); iterator.hasNext();) {
			Observer observer = (Observer) iterator.next();
			observer.read(book);
			
		}
	}

	/**
	 * 移除观察者
	 */
	@Override
	public void remove(Observer o) {
		if(list.contains(o)) list.remove(o);
	}
	
	/**
	 * 模拟书籍发生变化
	 * @param bookname
	 * @param price
	 * @param state
	 * @return
	 */
	public Book bookChange(String bookname, float price, int state){
		return  new Book(bookname, price, state);
	}

}

           

4.数学老师

public class MathTeacher implements Observer{

	/**
	 * 观察者收到通知后,所做的业务逻辑
	 * 此处应该是具体的业务逻辑
	 */
	@Override
	public void read(Book book) {
		System.out.println("*************英语老师收到通知:"+book.getBookname()+"************");
		System.out.println("*************英语老师收到通知:"+book.getPrice()+"************");
		System.out.println("*************英语老师收到通知:"+book.getState()+"************");
	}
	
}

           

5.英语老师

public class EnglishTeacher implements Observer{

	/**
	 * 观察者收到通知后,所做的业务逻辑
	 * 此处应该是具体的业务逻辑
	 */
	@Override
	public void read(Book book) {
		System.out.println("*************数学老师收到通知:"+book.getBookname()+"************");
		System.out.println("*************数学老师收到通知:"+book.getPrice()+"************");
		System.out.println("*************数学老师收到通知:"+book.getState()+"************");
	}

}
           

6.书籍

public class Book {
	
	private String bookname;
	private float price;
	private int state;
	
	public Book(String bookname, float price, int state) {
		this.bookname = bookname;
		this.price = price;
		this.state = state;
	}
	
	public String getBookname() {
		return bookname;
	}
	public void setBookname(String bookname) {
		this.bookname = bookname;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	public int getState() {
		return state;
	}
	public void setState(int state) {
		this.state = state;
	}
	
}
           

7.测试类

public class Test {

	public static void main(String[] args) {
		Subject sub = new Postman();
		Observer mathTeacher = new MathTeacher();
		Observer englishTeacher = new EnglishTeacher();
		
		//注册观察者
		sub.register(mathTeacher);
		sub.register(englishTeacher);
		
		//业务数据发生变化
		Book book = sub.bookChange("科学周刊", 23.0f, 0);
		
		//通知观察者
		sub.notice(book);
		
		//移除观察者
		sub.remove(englishTeacher);
		System.out.println("===================================================");
		//通知观察者
		sub.notice(book);
	}
	
}