觀察者模式
-
什麼是觀察者模式
定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己.別名依賴(Dependents), 發佈-訂閱( publish - subscribe) -
什麼場景會用到命令模式
一個對象的改變需要同時改變其它對象的時候,而且不知道具體有多少個對象有待改變時。想想以前的報紙訂閱,如果我們定了人名日報,每到早上都會有送報的上門,不管你愛看不愛看這陣子的新聞,只要報紙一出版就會很快送達,如果訂閱者最近沒有時間看新聞來, 只要取消訂閱,接下來新出版的報紙就不會再送了。
我們擬定一個場景,辦公室的所有人都無所事事,程序員,PO和TEAMLEADER,但是當然大家都怕老闆過來查崗,所以就需要一個類似哨兵的幫忙來監視老闆的行徑,這時候前臺就起到很大的作用了,當老闆回來的時候肯定先經過前臺,這時候前臺再去通知所有人,告訴大家該做正經事了。
public interface Employee {
void update();
}
public interface Action {
void action();
}
public class Developer implements Employee, Action {
@Override
public void action() {
System.out.println("coding");
}
@Override
public void update() {
action();
}
}
public class ProductManager implements Employee, Action {
@Override
public void action() {
System.out.println("discuss requirements");
}
@Override
public void update() {
action();
}
}
public class TeamLeader implements Employee, Action {
@Override
public void action() {
System.out.println("writing document");
}
@Override
public void update() {
action();
}
}
前臺
public class Receptionist implements Employee{
List<Employee> employees = new ArrayList<>();
public void addEmployee(Employee employee) {
employees.add(employee);
}
public void cancelEmployee(Employee employee) {
Objects.requireNonNull(employees);
employees.remove(employee);
}
@Override
public void update() {
System.out.println("boss is coming");
notifyEmployees();
}
private void notifyEmployees() {
employees.forEach(Employee::update);
}
}
測試如下
public static void main(String[] args) {
Receptionist receptionist = new Receptionist();
receptionist.addEmployee(new Developer());
receptionist.addEmployee(new ProductManager());
Employee teamLeader = new TeamLeader();
receptionist.addEmployee(teamLeader);
receptionist.cancelEmployee(teamLeader);
receptionist.update();
}
-
適用性
-在以下任一情況下可以使用觀察者模式 :
• 當一個抽象模型有兩個方面 , 其中一個方面依賴於另一方面。將這二者封裝在獨立的對
象中以使它們可以各自獨立地改變和複用。
• 當對一個對象的改變需要同時改變其它對象 , 而不知道具體有多少對象有待改變。
• 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之 , 你不希望這些
對象是緊密耦合的。JDK裏面內置了觀察者模式的功能,在java.util包內的Observer接口和Observable類,基本上實現類似,就不一一講解了。有興趣的大家可以去查看它的源碼。
相關參考:
<大話設計模式>,<設計模式,可複用面向對象軟件的基礎>,<Head First 設計模式>
源碼在此