java设计模式之观察者模式

一:观察者模式定义

  1.1 定义

       观察者模式定义了对象间的一对多关系,当一个对象的行为发生变化时,订阅者能够收到相应的通知,其又称为发布/订阅模式。观察者模式一般有2种,一种推模式,一个拉模式,推模式即当被订阅者对象发生行为改变时,会主动将变化的消息推给订阅者,而不考虑每个订阅者当时的处理能力,另一种比较好的是拉模式,即订阅者持有被观察者的实例,当被订阅者的行为发生改变时,拉模式会主动的根据引用获取变化的相关数据。

 1.2 角色

   被观察者:抽象观察者接口,包括观察者的注册,删除,通知等方法。

   观察者 :定义观察者对象。

   抽象观察者:定义观察者通用接口,当监听的被观察者发现行为改变时,动态的实现相应的行为动作。

   具体观察者:定义具体的观察者对象

 1.3 使用场景

   1:当一个系统中某个对象的改变需要同时改变其他对象的时候

   2:当一个抽象模型中,其中一方面依赖于另一方面,需要分别封装到独立的对象中时,彼此独立于抽象模型中。

二:观察者模式实现

  2.1 产品接口,要通知什么?订阅什么?

import java.util.List;

//产品接口,发布者要发布什么给订阅者?,订阅者要订阅什么? 这中间需要一个产品对象
public interface Product {

	//添加产品
	void addProduct(String name);
	
	//获取所有产品
	List<String> getProducts();
}

 2.2 被观察者

 

//发布者
public interface Publisher {
	
	//添加订阅者
	void addSubScribe(SubScribe subscribe);
	
	//移除订阅者
	void removeSubScribe(SubScribe subscribe);
	
	//发布者通知所有的订阅者
	void notifyAllSubScribe();

}

 

 2.3 抽象被观察者

//抽象的被观察者
public abstract class AbstractPublisher implements Product,Publisher {

    private List<SubScribe> subs = Collections.synchronizedList(new ArrayList<SubScribe>());
	
	@Override
	public void addSubScribe(SubScribe subscribe) {
		if(subs.contains(subscribe)){
			System.out.println("已经存在这个订阅者,不需要重新注册");
		}else{
			subs.add(subscribe);
		}
	}

	@Override
	public void removeSubScribe(SubScribe subscribe) {
		if(null == subscribe || !subs.contains(subscribe)){
			System.out.println("不存在这个订阅者,不需要");
		}else{
			subs.remove(subscribe);
		}
	}
	@Override
	public void notifyAllSubScribe() {
		synchronized (subs) {
			for(final SubScribe subScribe : subs){
				//订阅者接收通知,接收到的是一个product产品对象
				subScribe.receive(this);
			}
		}
	}

}

 2.4 观察者接口

public interface SubScribe {

	//订阅者订阅产品
	void receive(Product product);
}

 2.5 抽象观察者实现

//抽象的观察者
public abstract class AbstractSubscribe implements SubScribe {

	private String name;

	public AbstractSubscribe(String name) {
		this.name = name;
	}
	
	protected void printProducts(List<String> products) {
		if (null != products && products.size() > 0) {
			for (String st : products) {
				System.out.println("产品:" + st);
			}
		}
	}

	public String getName() {
		return name;
	}

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

}

 2.6 被观察者实现

//被观察者具体实现
public class ProductPublisher extends AbstractPublisher {

	private List<String> products = new ArrayList<String>();

	//发布者每次添加一个产品都需要通知所有的订阅者
	@Override
	public void addProduct(String name) {
		products.add(name);
		super.notifyAllSubScribe();
	}

	@Override
	public List<String> getProducts() {
		return products;
	}

}

 2.7 观察者实现

//产品订阅,订阅者订阅的是产品
public class ProductSubscribe  extends AbstractSubscribe{
	
    public ProductSubscribe(String name) {
    	super(name);
	}

	@Override
	public void receive(Product product) {
		System.out.println("订阅者:"+super.getName()+"  收到发布者消息,产品列表为");
		for(String st : product.getProducts()){
			System.out.println(st);
		}
	}

}

 2.8 测试类

public class ObserverTest {

	public static void main(String[] args) {
		AbstractPublisher abstractPublisher = new ProductPublisher();
		abstractPublisher.addSubScribe(new ProductSubscribe("重庆程序员"));
		abstractPublisher.addSubScribe(new ProductSubscribe("北京程序员"));
		abstractPublisher.addSubScribe(new ProductSubscribe("广州程序员"));
		abstractPublisher.addProduct("重庆程序员使用戴尔笔记本电脑");
		abstractPublisher.addProduct("北京程序员使用惠普笔记本电脑");
		abstractPublisher.addProduct("广州程序员使用三星笔记本电脑");
         }
}

 2.9 实现效果

订阅者:重庆程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
订阅者:北京程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
订阅者:广州程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
订阅者:重庆程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
北京程序员使用惠普笔记本电脑
订阅者:北京程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
北京程序员使用惠普笔记本电脑
订阅者:广州程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
北京程序员使用惠普笔记本电脑
订阅者:重庆程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
北京程序员使用惠普笔记本电脑
广州程序员使用三星笔记本电脑
订阅者:北京程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
北京程序员使用惠普笔记本电脑
广州程序员使用三星笔记本电脑
订阅者:广州程序员  收到发布者消息,产品列表为
重庆程序员使用戴尔笔记本电脑
北京程序员使用惠普笔记本电脑
广州程序员使用三星笔记本电脑

你可能感兴趣的:(java,设计模式,观察者)