观察者模式

观察者模式

  • 办公时间做与工作无关的事情
  • 在老板到来时,前台负责通知好友进入工作状态
  • 注意开放-封闭原则,依赖倒转原则,降低耦合性。
import java.util.ArrayList;

class Secretary{//前台秘书类
	private ArrayList<StockObserver>observers=new ArrayList<StockObserver>();
	private String action;
	public void Attach(StockObserver observer) {
		observers.add(observer);
	}
	public void Notify() {
		for(int i=0;i<observers.size();i++) {
			observers.get(i).Update();
		}
	}
	public String getAction() {
		return action;
	}
	public void setAction(String action) {
		this.action=action;
	}
}
class StockObserver{//看股票同事类
	private String name;
	private Secretary sub;
	public StockObserver(String name,Secretary sub) {
		this.name=name;
		this.sub=sub;
	}
	public void Update() {//得到前台通知
		System.out.println(sub.getAction()+name+"关闭股票行情,继续工作!");
	}
}
 
public  class Main{
	public static void main(String[] args){
	Secretary tongzhizhe=new Secretary();
	StockObserver tongshi1=new StockObserver("小王",tongzhizhe);
	StockObserver tongshi2=new StockObserver("小李",tongzhizhe);
	tongzhizhe.Attach(tongshi1);
	tongzhizhe.Attach(tongshi2);
	tongzhizhe.setAction("老板回来了");
	tongzhizhe.Notify();
	
	}
}

问题:前台类要增加观察者,观察者类需要前台的状态, 前台类和为股票者类之间互相耦合。如见观察者中还有人想看NBA直播,前台类代码就需要更改。因为前台类和StockObserver都是具体类,依赖具体使得类与类之间产生了紧密联系(耦合),以后假如出现变化,则变一次就要改一次,违背了开放-封闭原则。
解决办法:依赖倒转原则–依赖于抽象,而不是相互依赖,依赖抽象才能应对变化,避免耦合。

import java.util.ArrayList;
abstract class Subject{//抽象通知者
	abstract void Attach(Observer observer);//添加观察者
	abstract void Detach(Observer observer);//删除观察者
	abstract void Notify();//通知观察者
	String action;
	public String getAction() {//老板状态
		return action;
	}
	public void setAction(String action) {
		this.action=action;
	}
}
class Boss extends Subject{//同事列表
	private ArrayList<Observer>observers=new ArrayList<Observer>();
 
@Override
void Attach(Observer observer) {
	// TODO Auto-generated method stub
	observers.add(observer);
}
 
@Override
void Detach(Observer observer) {
	// TODO Auto-generated method stub
	observers.remove(observer);
}
 
@Override
void Notify() {
	// TODO Auto-generated method stub
	for(int i=0;i<observers.size();i++) {
		observers.get(i).Update();
	}
}
	
}
class Secretary extends Subject{//同事列表
	private ArrayList<Observer>observers=new ArrayList<Observer>();
 
@Override
void Attach(Observer observer) {
	// TODO Auto-generated method stub
	observers.add(observer);
}
 
@Override
void Detach(Observer observer) {
	// TODO Auto-generated method stub
	observers.remove(observer);
}
 
@Override
void Notify() {
	// TODO Auto-generated method stub
	for(int i=0;i<observers.size();i++) {
		observers.get(i).Update();
	}
}
	
}
abstract class Observer{
	protected String name;
	protected Subject sub;
	public Observer(String name,Subject sub) {
		this.name=name;
		this.sub=sub;
	}
	public abstract void Update();
}
class StockObserver extends Observer{
	public StockObserver(String name,Subject sub) {
		super(name,sub);
	}
 
	@Override
	public void Update() {
		// TODO Auto-generated method stub
		System.out.println(sub.getAction()+name+"关闭股票行情,继续工作!");
	}
 
}
class NBAObserver extends Observer{
	public NBAObserver(String name,Subject sub) {
		super(name,sub);
	}
 
	@Override
	public void Update() {
		// TODO Auto-generated method stub
		System.out.println(sub.getAction()+name+"关闭NBA直播,继续工作!");
	}
 
}
public  class Main{
	public static void main(String[] args){
		Secretary tongzhizhe=new Secretary();
		StockObserver tongzhizhe1=new StockObserver("小李",tongzhizhe);
		NBAObserver tongzhizhe2=new NBAObserver("小张",tongzhizhe);
		tongzhizhe.Attach(tongzhizhe1);
		tongzhizhe.Attach(tongzhizhe2);
		tongzhizhe.setAction("老板回来了");
		tongzhizhe.Notify();
	}
}

观察者模式基本代码

import java.util.ArrayList;
 
abstract class Subject{
	private ArrayList<Observer>observers=new ArrayList<Observer>();
	public void attach(Observer observer) {
		observers.add(observer);
	}
	public void detach(Observer onserver) {
		observers.remove(observer);
	}
	void Notify() {
		for(int i=0;i<observers.size();i++) {
			observers.get(i).update();
		}
	}
}
abstract class Observer{
	public abstract void update();
}
class ConcreteSubject extends Subject{
	private String subjectState;
 
	public String getSubjectState() {
		return subjectState;
	}
 
	public void setSubjectState(String subjectState) {
		this.subjectState = subjectState;
	}
	
}
class ConcreteObserver extends Observer{
 
	private String name;
	private String observerState;
	private ConcreteSubject subject;
	public ConcreteObserver(ConcreteSubject subject,String name) {
		this.name=name;
		this.subject=subject;
	}
	@Override
	public void update() {
		// TODO Auto-generated method stub
		observerState=subject.getSubjectState();
		System.out.println("观察者"+name+"的新状态是"+observerState);
	}
	
}
public  class Main{
	public static void main(String[] args){
		ConcreteSubject s=new ConcreteSubject();
		s.attach(new ConcreteObserver(s,"X"));
		s.attach(new ConcreteObserver(s,"Y"));
		s.attach(new ConcreteObserver(s,"Z"));
		s.setSubjectState("ABC");
		s.Notify();
	}
}

优点:

  • 观察者模式实现了观察者和目标之间的抽象耦合。
  • 观察者模式实现了动态联动
  • 观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。

缺点:

  • 尽管已经用了依赖倒转原则,但是‘抽象通知者’还是依赖‘抽象观察者’,也就是说,万一没有了抽象观察者这样的接口,通知的功能就完成不了。
  • 被观察者会向所有的登记过的观察者发出通知,不管观察者需不需要,每个观察者都会被调用update方法。

本质:触发联动
Java中的观察者模式
例题:观察者为羊,被观察者为狼。模仿的场景为狼叫羊跑。

import java.util.Observable;
import java.util.Observer;
 
class Wolf extends Observable{
	private String name;
	Wolf(String name){
		this.name=name;
	}
	public void shout(String state) {
		System.out.println(this.getName()+"shouting");
		this.setChanged();
		this.notifyObservers(state);
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}
class Sheep implements Observer{
	private String state="eating";
	private String name;
	public Sheep(String name) {
		this.name=name;
	}
	public void update(Observable o,Object arg) {
		Wolf wolf=(Wolf)o;
		System.out.println(wolf.getName()+"shouting and"+arg+""+this.getName()+"running");
		setState("runing");
	}
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}
public  class Main{
	public static void main(String[] args){
		Wolf wolf=new Wolf("wolf1");
		Sheep sheep1=new Sheep("sheep1");
		Sheep sheep2=new Sheep("sheep2");
		Sheep sheep3=new Sheep("sheep3");
		wolf.addObserver(sheep1);
		wolf.addObserver(sheep2);
		String wolfstat="hungry";
		wolf.shout(wolfstat);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值