什么时候使用观察者模式?
当存在一对多关系的时候,一个对象发生变化时,统一通知其他对象完成对应工作。
主要解决:一个对象状态改变给其他对象统一通知的问题,期间保持低耦合,保证高度的协作关系。
关键代码: 被观察者类中有存放所有观察者的ArrayList<>;
优点:
观察者和被观察者之间耦合,方便通知协作。
缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
举例:
中午大儿子和二儿子跟妈妈说他们肚子饿了,妈妈说:”我现在做饭做好了叫你们!!“,饭做好了,妈妈叫一声:”吃饭了!!“大儿子二儿子马上就跑来吃饭了。
其中:
观察者:大儿子,二儿子。
被观察者:妈妈。
状态变化:妈妈没做好饭到做好饭。
观察者行为:来吃饭。
举例图解:
代码实现
package Observer;
import java.util.ArrayList;
import java.util.List;
public class ObserverPatternDemo {
public static void main(String[] args) {
Mother mother = new Mother();
new EldestSon(mother);
new SecondSon(mother);
mother.setState(0);
mother.setState(1);
}
static abstract class Son{
protected Mother mother;
public abstract void update();
}
static class Mother{
private List<Son> Sons = new ArrayList<>();
private int state;// 0表示做饭,1表示饭做好了
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
if(this.state==1){
notifyAllSon();
}else {
System.out.println("母亲:我去做饭!!");
}
}
//被通知对象
public void attach(Son son){
Sons.add(son);
}
//通知儿子们吃饭
public void notifyAllSon(){
System.out.println("母亲:"+"吃饭了!!");
for (Son son : Sons) {
son.update();
}
}
}
static class EldestSon extends Son{
public EldestSon(Mother mother){
System.out.println("大儿子肚子饿了!!");
this.mother = mother;
this.mother.attach(this);
}
@Override
public void update() {
System.out.println("大儿子来吃饭了!!");
}
}
static class SecondSon extends Son {
public SecondSon(Mother mother){
System.out.println("二儿子肚子饿了!!");
this.mother = mother;
this.mother.attach(this);
}
@Override
public void update() {
System.out.println("二儿子来吃饭了!!");
}
}
}
大儿子肚子饿了!!
二儿子肚子饿了!!
母亲:我去做饭!!
母亲:吃饭了!!
大儿子来吃饭了!!
二儿子来吃饭了!!