JAVA观察者模式(转载)
通过本文将学习到
1、前言
2、观察者的概念
3、观察者的UM
4、观察者的实现
5、观察者的优缺点及使用场景
6、总结
1、前言
观察者模式可是大名鼎鼎,也许只听观察者不太清楚这是啥啊?但是说一手MVC肯定有人懂。MODEL-VIEW-CONTROLLER。我真的是打死不会忘记,面试的时候特别喜欢问。在软件中对象并不是单独存在的,一个对象的行为发生改变往往会导致一个或多个其他与之存在依赖关系的对象的行为发生改变。观察者模式就是用于描述对象之间的依赖关系,为实现多个对像之间的联动提供一种解决方案!
2、观察者的概念
观察者模式:定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时其相关依赖对象皆得到通知并被自动更新!
这个说起来好绕啊,应该找个例子!在交通规则中我们存在“红灯停,路灯行”这种基本套路。而这个规则的实现是通过汽车中的驾驶人(观察者),以及红绿灯(观察目标)来实现。观察者通过观察目标进行判断停车还是前进。这种概念大概就是观察者模式的理念。在软件中一个对象的概念也会被动的使其他对象的行为进行修改!定义的是一种一对多的依赖关系。
3、观察者的UML图
四个角色。
1、subject(目标):目标又称为主题,就是被观察者的对象。在目标类中可以定义N多个观察者(司机),同时也会提醒他们notify();在目标中有一个观察者的集合,可以通过定义的方法进行观察者的添加和删除。行人、司机、公交车司机。都是一种对象,可以加入红绿灯观察目标的范围中去。一般作为抽象类,或接口!
2、ConcreteSubject(具体目标):目标的子类,将目标类的方法进行实现。同时,具体目标类中一般含有改变的数据,当它的状态发生改变时将向它的各个观察者发通知。
3、Observer(观察者类):观察者类,是一个类的集合,这个通过目标类中如何定义来判断。所有的观察类中都有一个更新的操作,就是来通过观察,目标类来进行修改自身的状态。抽象观察者类。
4、ConcreteObserver(具体观察者类):为观察者的子类,是新观察的更新状态方法。同时,自身带有一个状态的属性,通过具体目标进行通知来是否进行update,进行自我状态的更新。
4、观察者的实现
1、战队类(AllyControlCenter),抽象目标类。核心类,有加队员的功能。
package observerPattern;
import java.util.ArrayList;
/**
*
* <p>Title: AllyControlCenter</p>
* <p>Description:指挥部类,当抽象目标类 </p>
* @author HAND_WEILI
* @date 2018年9月6日
*/
public abstract class AllyControlCenter {
protected String allyName; //战队名称
protected ArrayList<Observer> players = new ArrayList<Observer>(); //定义一个观察者的集合
public String getAllyName() {
return allyName;
}
public void setAllyName(String allyName) {
this.allyName = allyName;
}
//添加一个观察者
public void add(Observer obs) {
System.out.println(obs.getName()+"加入"+this.allyName+"战队");
players.add(obs);
}
//删除一个观察者
public void delete(Observer obs) {
System.out.println(obs.getName()+"退出"+this.allyName+"战队");
players.remove(obs);
}
//提醒更新
public abstract void notifyObserver(String name);
}
2、具体目标类(ConrecteAllyControlCenter ):将执行所有的操作,并给通知。
package observerPattern;
public class ConrecteAllyControlCenter extends AllyControlCenter {
public ConrecteAllyControlCenter(String name) {
System.out.println(name+"战队创建成功");
System.out.println("==================================================");
this.allyName=name;
}
@Override
public void notifyObserver(String name) {
// TODO Auto-generated method stub
//用来通知集合里所有的观察者,盟友。
System.out.println(this.allyName+"战队紧急通知,盟友"+name+"遭受敌人攻击");
for(Object obj:players) {
if(!((Observer)obj).getName().equalsIgnoreCase(name)) {
((Observer)obj).help();
}
}
}
}
3、抽象观察者类(Observer):有更新的方法,就是提出自己被打了。
package observerPattern;
/**
*
* <p>Title: Observer</p>
* <p>Description: 观察抽象类</p>
* @author HAND_WEILI
* @date 2018年9月6日
*/
public interface Observer {
public String getName();
public void setName(String name);
public void help();
public void beAttacked(AllyControlCenter acc);
}
4、具体的玩家(Player):加入战队,同时可以提出自己被打了然后请求支援。
package observerPattern;
public class Player implements Observer{
private String name;
public Player(String name) {
this.name=name;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return this.name;
}
@Override
public void setName(String name) {
// TODO Auto-generated method stub
this.name=name;
}
@Override
public void help() {
// TODO Auto-generated method stub
System.out.println("小伙子,"+name+"来救你了,别凉了");
}
@Override
public void beAttacked(AllyControlCenter acc) {
// TODO Auto-generated method stub
System.out.println(this.name+"被攻击");
acc.notifyObserver(name);
}
}
5、测试吧。
package observerPattern;
public class Client {
public static void main(String[] args) {
//定义观察目标
AllyControlCenter acc=new ConrecteAllyControlCenter("神奇四侠");
//定义观察者
Observer p1,p2,p3,p4;
p1=new Player("杨过");
p2=new Player("帅哥威");
p3=new Player("小倩倩");
p4=new Player("小木");
acc.add(p1);
acc.add(p2);
acc.add(p3);
acc.add(p4);
//一个成员受到攻击
p2.beAttacked(acc);
}
}
5、观察者的优缺点及使用场景
优点:
1、可以实现表示层和数据逻辑层的分离,定义了稳定的消息更新传值机制,并抽象了更新接口,使得可以有各种各样不同的表示层充当具体观察者角色。
2、在观察目标和观察者之间建立一个抽象的耦合。观察目标只需要维持一个抽象观察者的集合,无需了解具体观察者。由于观察者和观察目标紧密地耦合在一起,因此他们可属于不同层次的抽象化层次。
3、支持广播通信,观察者目标会向所有已注册的观察者对象发送通知,简化了一对多系统设计的难度。
缺点:
1、一个观察目标对象有很多直接和间接的观察者,将所有的观察者都通知到会很花时间。
2、如果在观察者和观察目标之间存在循环依赖,观察目标会触发他们之间循环调用,可能会死循环。
使用场景:
1、一个对象的改变将导致一个或多个其他对象也发生改变,而不知道具体改变了多少。也不知道改变了谁。
2、需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象将影响C以此类推。创建触发链条机制。
6、总结
还有一段关于JAVA中对于观察者模式的讲解并没有聊,MVC是架构模式,不是设计模式,不过就是通过观察者模式来的,还是非常的好用,这个是面试必备技能之一啊。当然,还要将代码发到GITHUB上。学着用。赶快把,这个东西搞完然后进行下一步学习。JUST FOR FUN。
原文链接:https://blog.csdn.net/qq_40709468/java/article/details/82468842