这次要介绍的是观察者模式,个人认为它相当于一对多的接口回调,主要用在需要在多处(观察者)监听一处(被观察者)的数据改变或者状态改变时,下面是百度百科的解释:
观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。
面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
听起来是不是很有用?那我们就来看看如何落实在代码上吧。
1.自定义观察者模式
首先要明确的是我们需要让观察者与被观察者发生联系,那么我们就需要两个方法,一个添加观察者,一个删除观察者。
同时被观察者需要一个集合来存放它的观察者,同时在自身发生变化时要去通知观察者,怎么通知呢?当然是去调用观察者的方法了,所以观察者需要实现一个方法来让被观察者调用,那么总共就是四个方法,两个接口了。
下面我们已抢购手机为例,商城当然是被观察者了,当手机到货时,它会放出消息表明手机有货了,然后顾客们就是观察者了,他们会关注商城的消息。
首先定义被观察者和观察者的接口,这里是把关系建立放在了被观察者里,当然你也可以放在被观察者里
/**
* 被观察者实现的接口
*/
public interface Shop {
void addCustomers(Customer customer);
void deleteCustomer(Customer customer);
void notifyCustomer();
}
/**
*
* @author com.亚东
*观察者实现的接口
*/
public interface Customer {
void getInformation();
}
public class Store implements Shop{
List<Customer> customers=new ArrayList<>();
@Override
public void addCustomers(Customer customer) {
// TODO Auto-generated method stub
customers.add(customer);
}
@Override
public void deleteCustomer(Customer customer) {
// TODO Auto-generated method stub
int index=customers.indexOf(customer);
if(index>=0){
customers.remove(index);
}
}
@Override
public void notifyCustomer() {
// TODO Auto-generated method stub
for (int i = 0; i < customers.size(); i++) {
customers.get(i).getInformation();
}
}
}
/**
* 顾客类
* @author com.亚东
*
*/
public class Client implements Customer{
String name;
public Client(String name) {
// TODO Auto-generated constructor stub
this.name=name;
}
@Override
public void getInformation(String message) {
// TODO Auto-generated method stub
System.out.println("我是:"+name+message);
}
}
下面我们来测试下:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Store store=new Store();
Client zhangSan=new Client("张三");
Client liSi=new Client("李四");
store.addCustomers(zhangSan);
store.addCustomers(liSi);
store.notifyCustomer("小米5有货了!!");
}
}
输出:
我是:张三小米5有货了!!
我是:李四小米5有货了!!
果然,顾客收到了消息。其实Java中已经为我们实现了观察者模式,我们只需要去使用java.util.Observable和java.util.Observer就可以轻松的实现观察者模式
public class JavaClient implements Observer{
String name;
public JavaClient(String name){
this.name=name;
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if(o instanceof JavaStore){
System.out.println("我是:"+name+arg.toString());
}
}
}
public class JavaStore extends Observable{
public void sendMesg(Object s){
setChanged();
notifyObservers(s);
}
}
public class Testt {
public static void main(String[] args) {
JavaClient zhangSan=new JavaClient("张三");
JavaClient liSi=new JavaClient("李四");
JavaStore javaStore=new JavaStore();
javaStore.addObserver(liSi);
javaStore.addObserver(zhangSan);
javaStore.sendMesg("小米5s有货了!!");
}
}
输出:
我是:张三小米5s有货了!!
我是:李四小米5s有货了!!
下面是一些方法说明:
addObserver(Observer o) //添加观察者
deleteObserver(Observer o) // 删除观察者
notifyObservers()// 通知观察者, 回调 观察者的 update()方法
notifyObservers(Object arg)
setChanged()//表明数据发生了变化,这个方法非常重要,如果你要传递数据,那么必须要在notifyObservers(Object arg)前调用该方法,否则是不会回调观察者的update()方法的