在前面的博文中,小编介绍设计模式中的撩妹模式,不知道小伙伴们有没有从中get到技巧呢?今天这篇博文,咱们继续来学习设计模式的相关知识,今天小编向大家介绍的模式是观察者模式,还请小伙伴多多指教,小编会从什么是原型观察者模式、观察者模式的结构图、观察者模式的demo以及观察者模式的特点和应用场景等方面一一进行介绍,希望对有需要的小伙伴有帮助。
什么是观察者模式?
观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。观察者模式的英文名称叫Observer,属于行为型模式,她的作用是当一个对象的状态发生变化时,能够自动通知其她关联对象,自动刷新对象状态。Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖她的其她对象之间保持状态同步,我们来看一下观察者模式的结构图,如下所示:
观察者模式的结构图
简单的来解释一下观察者模式的角色和职责
a、Subject(被观察者)
被观察的对象,当需要被观察的状态发生变化时,需要通知队列中所有观察者对象,Subject需要维持(添加、删除、通知)一个观察者对象的队列列表。
b、ConcreteSubject
被观察者的具体实现,包含一些基本的属性状态及其她操作。
c、Observer(观察者)
接口或抽象类,当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。
d、ConcreteObserver
观察者的具体实现,得到通知后将完成一些具体的业务逻辑处理。
观察者模式demo
新建项目Observer,新建类Person,白那些相关代码部分,如下所示:
import java.util.Observable;
public class Person extends Observable {
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
如果这个时候,我们设置了名字,我们就需要通知一下,给相应的set方法加上通知和改变的方法,代码如下所示:
import java.util.Observable;
public class Person extends Observable {
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
this.setChanged();
this.notifyObservers();
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
this.setChanged();
this.notifyObservers();
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
this.setChanged();
this.notifyObservers();
}
}
有了被观察者,我们还需要一个观察者,新建类MyObServer,编写相关代码,如下所示:
import java.util.Observable;
import java.util.Observer;
public class MyObServer implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("对象发生变化");
}
}
新建MainClass,编写里面的代码,如下所示:
public class MainClass {
public static void main(String[] args) {
Person person = new Person();
//注册观察者
person.addObserver(new MyObServer());
person.setName("dingguohua");
person.setAge(22);
person.setSex("女");
}
}
运行,如下所示:
这个时候,如果我们在注册一个,完善代码,如下所示:
public class MainClass {
public static void main(String[] args) {
Person person = new Person();
//注册观察者
person.addObserver(new MyObServer());
person.addObserver(new MyObServer());
person.setName("dingguohua");
person.setAge(22);
person.setSex("女");
}
}
运行如下所示:
从运行结果我们就能看出来,有六个对象,因为我们注册了两个观察者,同时observer还提供了删除的方法,编写相关代码如下所示:
public class MainClass {
public static void main(String[] args) {
Person person = new Person();
//注册观察者
person.addObserver(new MyObServer());
person.addObserver(new MyObServer());
person.deleteObservers();
person.setName("dingguohua");
person.setAge(22);
person.setSex("女");
}
}
我们还可以添加数目,完善代码,如下所示:
public class MainClass {
public static void main(String[] args) {
Person person = new Person();
//注册观察者
person.addObserver(new MyObServer());
person.addObserver(new MyObServer());
System.out.println(person.countObservers());
person.setName("dingguohua");
person.setAge(22);
person.setSex("女");
}
}
运行效果如下所示:
观察者模式的典型应用
a、侦听时间驱动程序设计中的外部事件;
b、侦听/监视某个对象的状态变化;
c、发布者/订阅者模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者。
小伙伴们都知道,博客我们是可以订阅的,当我们订阅某个博主的文章,等到博文有更新的时候,就会收到提醒,我们以这个为例,再来举例说明,帮助我们更好的理解观察者模式,新建包和类Article,编写相关代码,如下所示:
package com.shejimoshi.news;
public class Article {
private String articleTitel;
private String articleContent;
public String getArticleTitel() {
return articleTitel;
}
public void setArticleTitel(String articleTitel) {
this.articleTitel = articleTitel;
}
public String getArticleContent() {
return articleContent;
}
public void setArticleContent(String articleContent) {
this.articleContent = articleContent;
}
}
这个博文是被博主来进行发表的,so我们需要创建一个类BlogUser,编写相关代码,如下所示:
package com.shejimoshi.news;
import java.util.Observable;
public class BlogUser extends Observable {
public void publishBlog(String articleTitle,String articleContent) {
System.out.println("博主:发表新文章,文章标题:" + articleTitle + ",文章内容:" + articleContent);
this.setChanged();
this.notifyObservers();
}
}
被观察者ok了,我们来新建一个观察者的类,编写相关的代码部分,如下所示:
package com.shejimoshi.news;
public class MainClass {
public static void main(String[] args) {
BlogUser user = new BlogUser();
user.addObserver(new MyObServer());
user.publishBlog("博客上线啦","欢迎大家来访问" );
}
}
运行,如下所示:
我们还可以把Article进行封装,如下所示:
package com.shejimoshi.news;
import java.util.Observable;
public class BlogUser extends Observable {
public void publishBlog(String articleTitle,String articleContent) {
Article art = new Article();
art.setArticleTitel(articleTitle);
art.setArticleContent(articleContent);
System.out.println("博主:发表新文章,文章标题:" + articleTitle + ",文章内容:" + articleContent);
this.setChanged();
this.notifyObservers(art);
}
}
编写MyObeServer的代码部分,如下所示:
package com.shejimoshi.news;
import java.util.Observable;
import java.util.Observer;
public class MyObServer implements Observer {
@Override
public void update(Observable o, Object arg) {
Article art = (Article)arg;
System.out.println("博主发表了新的文章,快去看吧");
System.out.println("博客标题为:"+art.getArticleTitel());
System.out.println("博客标题为:"+art.getArticleContent());
}
}
运行,如下所示:
观察者模式的优缺点
优点:
a、当两个对象之间送耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间送耦合。主题所知道只是一个具体的观察者列表,每一个具体观察者都符合一个抽象观察者的接口。主题并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口。
b、观察者模式支持“广播通信”。主题会向所有的观察者发出通知。
c、观察者模式符合“开闭原则”的要求。
缺点:
a、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
b、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进 行循环调用,可能导致系统崩溃。
c、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
小编寄语:该博文,小编主要介绍了观察者模式,从什么是观察者模式、观察者模式的结构图、观察者模式的场景、优缺点以及观察者模式Demo,希望可以帮助有需要的小伙伴,请小伙伴们多多指教`(*∩_∩*)′,观察者模式是一种通知变化的模式,一般认为只在对象发生变化感兴趣的场合有用。主题对象知道有观察者存在,设置会维护观察者的一个队列;而从广义的角度看,观察者模式是中传递变化数据的模式,需要查看对象属性时就会使用的一种模式,主题对象不知道观察者的存在,更像是围观者。需要知道主题对象的状态,所以即使在主题对象没有发生改变的时候,观察者也可能会去访问主题对象。换句话说广义观察者模式,是在不同的对象之间传递数据的一种模式。