【设计模式】观察者模式的实现及Java中的观察者模式--------Java

23 篇文章 0 订阅
22 篇文章 0 订阅

观察者模式(Observer):
一种通知依赖关系:一个对象的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。
这种依赖关系过于紧密,为了将这种依赖关系弱化,松耦合,有了观察者模式。

1.问题引入:
同事上班炒股票,老板回来的时候前台通知同事停止。

package computer;

import java.util.ArrayList;

public class Test {
	public static void main(String[] args) {
		//前台童子喆
		Secretary tongzizhe=new Secretary();
		
		//两个同事,(同时设置名字及负责的前台)
		StockObserver tongshi1=new StockObserver("魏关侘", tongzizhe);
		StockObserver tongshi2=new StockObserver("易家扬", tongzizhe);
		
		//前台记下负责的同事
		tongzizhe.Attach(tongshi1);
		tongzizhe.Attach(tongshi2);
		
		//发现老板回来了
		tongzizhe.setAction("老板回来了!");
		//通知两个同事
		tongzizhe.Notify();
	}
}

//前台秘书类(前台类依赖同事类)
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+",关闭股票行情,继续工作!");
	}
}

缺点:不符合开放封闭原则。

2.改进:
根据依赖倒转原则,依赖于抽象,而不是相互依赖。

package computer;

import java.util.ArrayList;

public class Test {
	public static void main(String[] args) {
		//前台
		Secretary tongzizhe=new Secretary();
		
		//看股票的同事
		StockObserver tongshi1=new StockObserver("薇薇",tongzizhe);
		//看NBA的同事
		NBAObserver tongshi2=new NBAObserver("熠熠",tongzizhe);
		
		tongzizhe.attach(tongshi1);
		tongzizhe.attach(tongshi2);
		
		tongzizhe.setAction("老板回来了!");
		tongzizhe.Notify();
	}
}

//抽象通知者
abstract class Subject{
	
	//老板的状态
	private String action;
	
	//添加观察者的方法
	abstract void attach(Observer observer);
	//删除观察者的方法
	abstract void detach(Observer observer);
	
	//通知观察者
	abstract void Notify();
	
	//设置获取老板状态
	public String getAction() {
		return action;
	}
	public void setAction(String action) {
		this.action = action;
	}
}

//具体通知者(老板)
class Boss extends Subject{
	//同事列表
	private ArrayList<Observer> observers=new ArrayList<Observer>();

	//添加观察者
	void attach(Observer observer) {
		observers.add(observer);
	}

	//删除观察者
	void detach(Observer observer) {
		observers.remove(observer);
	}

	//通知观察者
	void Notify() {
		for(int i=0;i<observers.size();i++) {
			observers.get(i).update();
		}
	}
}

//具体通知者(前台秘书类)
class Secretary extends Subject{
	//同事列表
	private ArrayList<Observer> observers=new ArrayList<Observer>();

	//添加观察者
	void attach(Observer observer) {
		observers.add(observer);
	}

	//删除观察者
	void detach(Observer observer) {
		observers.remove(observer);
	}

	//通知观察者
	void Notify() {
		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);
	}

	//做出行动
	public void update() {
		System.out.println(sub.getAction()+name+",关闭股票行情,继续工作!");
	}
}

//看NBA的同事(具体观察者)
class NBAObserver extends Observer{

	public NBAObserver(String name, Subject sub) {
		super(name, sub);
	}

	//做出行动
	public void update() {
		System.out.println(sub.getAction()+name+",关闭NBA直播,继续工作!");
	}
}

观察者模式适用于:一个对象的状态发生变化的时候,某些其他的对象能做出相应的改变。且耦合度较低。

3.观察者模式:

package computer;

import java.util.ArrayList;

public class Test {
	public static void main(String[] args) {
		//具体的观察者
		ConcreteSubject s=new ConcreteSubject();
		
		//具体的被观察者
		ConcreteObserver c1=new ConcreteObserver("X",s);
		ConcreteObserver c2=new ConcreteObserver("Y",s);
		ConcreteObserver c3=new ConcreteObserver("Z",s);
		
		s.attach(c1);
		s.attach(c2);
		s.attach(c3);
		
		s.setSubjectState("ABC");
		s.Notify();
	}
}

//抽象通知者
//(增加、删除观察者对象,通知观察者)
abstract class Subject{
	//观察者们
	private ArrayList<Observer> observers=new ArrayList<Observer>();
	
	//增加观察者
	public void attach(Observer observer) {
		observers.add(observer);
	}
	
	//删除观察者
	public void detach(Observer observer) {
		observers.remove(observer);
	}
	
	//通知每个同事
	public 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(String name, ConcreteSubject subject) {
		this.name = name;
		this.subject = subject;
	}
	
	//更新状态
	public void update() {
		//获取被观察者的状态
		observerState=subject.getSubjectState();
		System.out.println("观察者"+name+"的新状态是:"+observerState);
	}
}

观察者模式的特点:
被观察者不需要知道谁是它的观察者,任何一个观察者也不需要知道其他观察者的存在。
什么时候用观察者模式:
当一个对象的改变需要同时改变其他的对象,而它不知道具体有多少个对象有待改变的时候。

只有观察者依赖于目标,而目标不依赖于观察者。它们之间的主动权掌握在目标手中,只有目标知道什么时候需要通知观察者,观察者始终是被动的。

观察者模式的不足:抽象通知者依赖于抽象观察者。

4.java中的观察者模式:
(以狼和羊为例)

package computer;

import java.util.Observable;
import java.util.Observer;

public class Test {
	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 wolfState="hungry";
		
		//狼叫
		wolf.shout(wolfState);
		//该方法中的notifyObservers(state)方法会自动调用各个观察者的update()方法
	}
}

//狼(被观察者)
class Wolf extends Observable{
	//狼名字
	private String name;

	public Wolf(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	//狼叫(参数为notifyObservers()方法要用的参数)
	public void shout(String state) {
		System.out.println("狼 "+name+" shouting!");
		//被观察者状态改变
		this.setChanged();
		//通知所有观察者(参数为要改变的属性)
		this.notifyObservers(state);
	}
}

//羊(观察者)
class Sheep implements Observer{
	//羊的状态
	private String state="eating";
	//羊的名字
	private String name;
	
	public Sheep(String name) {
		super();
		this.name = name;
	}

	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 void update(Observable o, Object arg) {
		Wolf wolf=(Wolf) o;
		System.out.println("狼 "+wolf.getName()+" shouting and "+arg+". "+name+"running.......");
		//重新设置观察者的状态
		setState("running");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值