这个模式的定义:
定义对象间的一种一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都能得到通知并被自动更新
使用场景如下:
- 有一种短信服务,比如天气预报服务,一旦你订阅该服务,你只需按月付费,付完费后,每天一旦有天气信息更新,它就会及时向你发送最新的天气信息。
- 杂志的订阅,你只需向邮局订阅杂志,缴纳一定的费用,当有新的杂志时,邮局会自动将杂志送至你预留的地址。
观察上面两个情景,有一个共同点,就是我们无需每时每刻关注我们感兴趣的东西,我们只需做的就是订阅感兴趣的事物,比如天气预报服务,杂志等,一旦我们订阅的事物发生变化,比如有新的天气预报信息,新的杂志等,被订阅的事物就会即时通知到订阅者,即我们。而这些被订阅的事物可以拥有多个订阅者,也就是一对多的关系。当然,严格意义上讲,这个一对多可以包含一对一,因为一对一是一对多的特例,没有特殊说明,本文的一对多包含了一对一。
然后我们看一下观察者模式的几个重要组成。
- 观察者,我们称它为Observer,有时候我们也称它为订阅者,即Subscriber
- 被观察者,我们称它为Observable,即可以被观察的东西,有时候还会称之为主题,即Subject
在观察者模式中有如下角色。
• Subject:抽象主题(抽象被观察者)。抽象主题角色把所有观察者对象保存在一个集合里,每个主题
都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
• ConcreteSubject:具体主题(具体被观察者)。该角色将有关状态存入具体观察者对象,在具体主题
的内部状态发生改变时,给所有注册过的观察者发送通知。
• Observer:抽象观察者,是观察者的抽象类。它定义了一个更新接口,使得在得到主题更改通知时更
新自己。
• ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新
自身的状态。
下面是我们的实例运行:
一个按钮订阅一个观察者,发布消息后,订阅过的即可接收到消息:
具体实现:
1.一个抽象主题(被观察者Subject)public interface Subject {
void addObserver(Observer observer);
void notifyObserver(MessageBean message);
void removeObserver(Observer observer);
void clearObserver();
}
2.抽象主题的具体实现类(ConcreteSSubject)
public class ConcreteSubject implements Subject {
private List userList = new ArrayList();
private static ConcreteSubject instance = new ConcreteSubject();
public ConcreteSubject(){}
public static ConcreteSubject getInstance() {
return instance;
}
@Override
public void addObserver(Observer observer) {
userList.add(observer);
Log.d("########",userList.size() +"");
}
@Override
public void notifyObserver(MessageBean message) {
for (Observer observer : userList) {
observer.update(message);
}
}
@Override
public void removeObserver(Observer observer) {
userList.remove(observer);
}
@Override
public void clearObserver() {
userList.clear();
}
}
3.抽象观察者(Observer)
public interface Observer {
void update(MessageBean message);
}
4.抽象观察者的实现类(ConcreteObserver)
1.自己的类中需要implement Observer
2.
@Override
public void update(MessageBean message) {
if (message.getFromOne() == true) {
txt1.setText(message.getMessage());
}
if (message.getFromTwo() == true) {
txt2.setText(message.getMessage());
}
if (messageBean.getFromOne() == true && messageBean.getFromTwo() == true) {
txt1.setText(message.getMessage());
txt2.setText(message.getMessage());
}
}
5.使用类(和第四步抽象观察者的实现类是一个地方)
public class MainActivity extends AppCompatActivity implements View.OnClickListener, Observer {
Button btn1;
Button btn2;
TextView txt1;
TextView txt2;
Button notifyBtn;
Button cancelBtn;
ConcreteObserver observer1;
ConcreteObserver observer2;
Subject subject;
int messageNumber = 1;
StringBuilder message = new StringBuilder("发送消息");
MessageBean messageBean = new MessageBean();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = findViewById(R.id.observer1);
btn2 = findViewById(R.id.observer2);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
txt1 = findViewById(R.id.text1);
txt2 = findViewById(R.id.text2);
notifyBtn = findViewById(R.id.subject);
notifyBtn.setOnClickListener(this);
cancelBtn = findViewById(R.id.remove_subject);
cancelBtn.setOnClickListener(this);
observer1 = new ConcreteObserver();
observer2 = new ConcreteObserver();
subject = new ConcreteSubject();
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.observer1) {
// subject.addObserver(observer1);
messageBean.setFromOne(true);
ConcreteSubject.getInstance().addObserver(this);
} else if (id == R.id.observer2) {
// subject.addObserver(observer2);
messageBean.setFromTwo(true);
ConcreteSubject.getInstance().addObserver(this);
} else if (id == R.id.subject) {
// subject.notifyObserver(messageBean);
messageBean.setMessage(message.append(messageNumber++) + "");
ConcreteSubject.getInstance().notifyObserver(messageBean);
} else if (id == R.id.remove_subject) {
messageBean.setFromOne(false);
messageBean.setFromTwo(false);
ConcreteSubject.getInstance().clearObserver();
}
}
@Override
public void update(MessageBean message) {
if (message.getFromOne() == true) {
txt1.setText(message.getMessage());
}
if (message.getFromTwo() == true) {
txt2.setText(message.getMessage());
}
if (messageBean.getFromOne() == true && messageBean.getFromTwo() == true) {
txt1.setText(message.getMessage());
txt2.setText(message.getMessage());
}
}
}
以上就是一个观察者模式的具体实现,其中的MessageBean实体类和布局文件如下:
public class MessageBean {
boolean fromOne;
boolean fromTwo;
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public boolean getFromOne() {
return fromOne;
}
public void setFromOne(boolean fromOne) {
this.fromOne = fromOne;
}
public boolean getFromTwo() {
return fromTwo;
}
public void setFromTwo(boolean fromTwo) {
this.fromTwo = fromTwo;
}
}
整个项目实例:https://github.com/buder-cp/base_component_learn/tree/master/observermodel