觀察者模式:在對(duì)象之間定義一對(duì)多的依賴(lài),當(dāng)對(duì)象的狀態(tài)發(fā)生改變時(shí),依賴(lài)對(duì)象就會(huì)收到通知自動(dòng)更新锦溪。
我們先看看jdk提供的觀察者模式到底該如何使用减余。首先定義一個(gè)類(lèi)集成java.util.Observable,然后在狀態(tài)變化的時(shí)候調(diào)用setChanged方法改變觀察者內(nèi)部的標(biāo)志位综苔,最后發(fā)送通知讓觀察者進(jìn)行對(duì)應(yīng)的邏輯操作
public class Student extends Observable {
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
setChanged();
notifyObservers();
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
setChanged();
notifyObservers();
}
}
觀察者需要實(shí)現(xiàn)java.util.Observer接口,在update方法中接收變化后的新對(duì)象
public class StudentObserver implements java.util.Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println(o);
}
}
public class StudentMain {
public static void main(String[] args){
Student student = new Student();
student.addObserver(new StudentObserver());
student.setName("HELLO");
student.setSex("MALE");
}
}
以上是jdk提供的觀察者模式的實(shí)現(xiàn)位岔,但是了在使用的過(guò)程中卻不是那么方便休里,首先Observable是一個(gè)類(lèi),java中只能單繼承赃承,那么一旦被觀察的對(duì)象需要集成其他的父類(lèi)時(shí)妙黍,就顯得很累贅,那怎么辦了瞧剖,其實(shí)在了解該模式的原理后完全可以自己來(lái)實(shí)現(xiàn)拭嫁。
public interface Subject extends Serializable{
public List<Observer> observerList = new ArrayList<Observer>();
public void addObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObservers(String key);
}
public interface Observer<T> {
public void update(T current,String key);
}
public class Person implements Subject {
private String name;
private String sex;
private int age;
@Override
public void addObserver(Observer observer) {
observerList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observerList.remove(observer);
}
@Override
public void notifyObservers(String key) {
for (Observer item: observerList) {
item.update(this,key);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyObservers("name");
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
notifyObservers("sex");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyObservers("age");
}
}
public class PersonObserver implements Observer<Person> {
@Override
public void update(Person current,String key) {
System.out.println("changed"+" "+ key);
}
}
public class PersonMain {
public static void main(String[] args){
Person person = new Person();
person.addObserver(new PersonObserver());
person.setAge(20);
person.setName("張三");
person.setSex("男");
}
}
自己實(shí)現(xiàn)也不是那么麻煩,但跟jdk提供的實(shí)現(xiàn)方式一對(duì)比抓于,我們采用來(lái)接口的方式做粤,擴(kuò)展性要好很多,但是需要在被觀察的每個(gè)子類(lèi)中都要實(shí)現(xiàn)固定的邏輯捉撮,這也是為什么jdk提供的是類(lèi)而非接口了怕品,小伙伴可以根據(jù)自己的業(yè)務(wù)需要選擇具體的實(shí)現(xiàn)方式