设计模式——观察者模式(代码基本参考自《大话设计模式》)

参考:博客

public abstract class Subject {
	private List<Observer> observers = new LinkedList<Observer>();

	// 增加观察者
	public void attach(Observer observer) {
		observers.add(observer);
	}
	
	// 移除观察者
	public void detach(Observer observer) {
		observers.remove(observer);
	}
	// 通知
	public void notifys() {
		for(Observer observer : observers) {
			observer.update();
		}
	}
}
public class ConcreteSubject extends Subject{
	private String subjectState;

	public String getSubjectState() {
		return subjectState;
	}

	public void setSubjectState(String subjectState) {
		this.subjectState = subjectState;
	}
}
public abstract class Observer {
	public abstract void update(); 
}
public class ConcreteObserver extends Observer{
	private String name;
	private String observerState;
	private ConcreteSubject subject;
	
	public ConcreteObserver(ConcreteSubject subject , String name) {
		this.subject = subject;
		this.name = name;
	}
	
	@Override
	public void update() {
		observerState = subject.getSubjectState();
		System.out.println("观察者  :" + name+ " 的新状态是 "+observerState);
		
	}

	public ConcreteSubject getSubject() {
		return subject;
	}

	public void setSubject(ConcreteSubject subject) {
		this.subject = subject;
	}	
}

public class DemoEnter {
	public static void main(String[] args) {
		// 观察者
		ConcreteSubject s = new ConcreteSubject();
		s.attach(new ConcreteObserver(s, "张三"));
		s.attach(new ConcreteObserver(s, "李四"));
		s.attach(new ConcreteObserver(s, "王五"));
		
		s.setSubjectState("ABC");
		s.notifys();
		
		// 发布订阅
		SubscribePublish<String> subscribePublish = new SubscribePublish("订阅器");
		Publisher publisher1 = new PublisherImp("发布者");
		Subscriber subscriber1 = new SubscriberImp("订阅者1");
		Subscriber subscriber2 = new SubscriberImp("订阅者2");
		
		// 订阅者订阅消息
		subscriber1.subscribe(subscribePublish);
		subscriber2.subscribe(subscribePublish);
		// 发布者发布消息
		publisher1.publish(subscribePublish, "消息1", true);
		publisher1.publish(subscribePublish, "消息2", true);
		publisher1.publish(subscribePublish, "消息3", false);
	}
}

// 发布者接口
public interface Publisher {
	public void publish(SubscribePublish subscribePublish,String message, boolean isInstantMsg);
}

// 订阅者接口
public interface Subscriber {
	public void subscribe(SubscribePublish subscribePublish);
	public void unSubcribe(SubscribePublish subscribePublish);
	public void update(String publisher,String message);
}

// 消息
public class Msg {
	private String publisher;
	private String message;
	
	public Msg(String publisher,String message) {
		this.publisher = publisher;
		this.message = message;
	}

	public String getPublisher() {
		return publisher;
	}

	public void setPublisher(String publisher) {
		this.publisher = publisher;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}
public class SubscriberImp implements Subscriber{

	public String name;
	
	public SubscriberImp(String name) {
		this.name = name;
	}
	
	@Override
	public void subscribe(SubscribePublish subscribePublish) {
		subscribePublish.subscribe(this);
	}

	@Override
	public void unSubcribe(SubscribePublish subscribePublish) {
		subscribePublish.unSubscribe(this);
	}

	@Override
	public void update(String publisher, String message) {
		System.out.println(this.name + " 收到  "+publisher+ " 发来的消息 :"+message);
	}

}
public class PublisherImp implements Publisher{
	private String name;

	public PublisherImp(String name) {
		this.name = name;
	}
	
	@Override
	public void publish(SubscribePublish subscribePublish, String message, boolean isInstantMsg) {
		subscribePublish.publish(this.name, message, isInstantMsg);	
	}
}
public class SubscribePublish<M> {
	// 订阅器名称
	private String name;
	// 订阅器容量
	private final int CAPACITY = 20;
	// 存储队列
	private BlockingQueue<Msg> queue = new ArrayBlockingQueue<Msg>(CAPACITY);
	// 订阅者
	private List<Subscriber> subscribers = new LinkedList();
	
	public SubscribePublish(String name) {
		super();
		this.name = name;
	}
	
	public void publish(String publisher ,String message,boolean isInstantMsg) {
		if(isInstantMsg) {
			update(publisher,message);
			return ;
		}
		Msg m = new Msg(publisher,message);
		if(!queue.offer(m)) {
			update();
		}
	}
	
	public void subscribe(Subscriber subscriber) {
		subscribers.add(subscriber);
	}
	
	public void unSubscribe(Subscriber subscriber) {
		subscribers.remove(subscriber);
	}
	
	public void update() {
		Msg m = null;
		while((m = queue.peek())!=null) {
			this.update(m.getPublisher(),m.getMessage());
		}
	}
	
	public void update(String publisher,String msg) {
		for(Subscriber subscriber : subscribers) {
			subscriber.update(publisher, msg);
		}
	}
	
}

上面虽然说一个观察者一个发布订阅,其实两者本质上没太大区别,都维护了一个集合对象,执行更新方法时,都对集合对象进行了遍历,理解了这一点,这个模式基本没啥好说的了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值