設計模式之觀察者模式

你們上學時最懼怕的是什麼?是否是還被「班主任忽然出如今你後面」的恐懼支配着?時不時就得往窗口、門口望一望,老師沒過來就接着看小說,老師一過來固然得僞裝着寫做業。萬一咱們坐在靠近裏面的,不方便觀察,這時候咱們就只能讓坐在窗邊的王XX代勞了,王XX一看到老師來了,就喊一聲,這時咱們就明白怎麼回事了。java

1、定義

定義:觀察者模式是軟件設計模式的一種。在此種模式中,一個目標物件管理全部相依於它的觀察者物件,而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。此種模式一般被用來實現事件處理系統。
編程

注意點:設計模式

一、被觀察者管理觀察者bash

二、被觀察者狀態改變時主動發出通知markdown

2、UML類圖

在文章開頭的描述中,「王XX」看到老師來了就給其餘同窗發個信號,通知一下。「王XX」是被其餘同窗觀察,即爲被觀察者。其餘同窗則爲觀察者。ide

咱們定義了一個oop

Oberable接口,被觀察者接口,接口中定義了四個方法:測試

(1)teacherLeave()           用來發出消息,表示老師離開了spa

(2)teacherComeBack()   用來發出消息,表示老師回來了設計

(3)addNotificationStudent()   「王XX」同窗不可能通知全部同窗啊,須要通知的同窗須要事先跟「王XX」同窗說下。

(4)deleteNotificationStudent()  "小丫"同窗,如今不須要通知了,經過這個方法讓「王XX」同窗再也不通知她

WangStudent類,表示「王XX」,保存須要通知的同窗名單,老師來了就通知這些同窗。

IObservor觀察者接口,有個方法用來接收「王XX」同窗發來的通知。

ObersorStuLi、ObersorStuZhang,李同窗、張同窗,具體的觀察類。


3、代碼實現

被觀察者接口

package com.design.observor;

public interface Observable {

    public void teacherLeave();

    public void teacherComeBack();

    public void addNotificationStudent(IObservor observor);

    public void deleteNotificationStudent(IObservor observor);

}複製代碼

被觀察者「王XX」同窗

package com.design.observor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class WangStudent implements Observable {

    private int state;
    //須要通知的名單。管理觀察者,對應定義注意點1
    private List<IObservor> obserbors;

    public WangStudent(){
        obserbors = new ArrayList<>();
    }

    //通知須要通知的同窗,老師走了
    @Override
    public void teacherLeave() {
        state = 1;
        //被觀察者,主動發出通知,對應定義注意點2
        Iterator<IObservor> iterator = obserbors.listIterator();
        while (iterator.hasNext()){
            iterator.next().updateOperation(state);
        }
    }

    //通知須要通知的同窗,老師來了
    @Override
    public void teacherComeBack() {
        state = 0;
        Iterator<IObservor> iterator = obserbors.listIterator();
        while (iterator.hasNext()){
            iterator.next().updateOperation(state);
        }
    }
    //增長鬚要通知的同窗
    @Override
    public void addNotificationStudent(IObservor observor) {
        obserbors.add(observor);
    }
    //刪除不須要通知的同窗
    @Override
    public void deleteNotificationStudent(IObservor observor) {
        obserbors.remove(obserbors);
    }
}複製代碼

觀察者接口

package com.design.observor;

public interface IObservor {

    public void updateOperation(int state);
}複製代碼

觀察者同窗,「李同窗」、「張同窗」

package com.design.observor;

public class ObservorStuLi implements IObservor{

    @Override
    public void updateOperation(int state) {
        if(state == 0){
            System.out.println("LiXX:老師來了,把小說收了,僞裝作題!!");
        }else{
            System.out.println("LiXX:老師走了,繼續看小說!!");
        }
    }
}
複製代碼

package com.design.observor;

public class IObservorStuZhang implements IObservor {
    @Override
    public void updateOperation(int state) {
        if(state == 0){
            System.out.println("ZhangXX:老師來了,中止跟XX調情,僞裝作題!!");
        }else{
            System.out.println("ZhangXX:老師走了,繼續跟XX調情!!");
        }
    }
}複製代碼

測試類

package com.design.observor;

public class TestMain {

    public static void main(String[] args) {
        Observable wangStu = new WangStudent();

        IObservor liStu = new ObservorStuLi();
        IObservor zhangStu = new IObservorStuZhang();
        //李同窗、張同窗增長到須要通知的名單中
        wangStu.addNotificationStudent(liStu);
        wangStu.addNotificationStudent(zhangStu);
        //老師來了
        wangStu.teacherComeBack();
        //老師走了
        wangStu.teacherLeave();

    }
}複製代碼

測試結果


好了,咱們完成了這個場景的編程,老師來了、走了,「王XX」同窗都通知了張同窗,還有李同窗,這時張同窗、李同窗就能夠放心玩他們想玩的了。

4、總結

使用場景:當一個對象的改變須要同時改變其餘對象,且不知道具體有多少對象待改變時(咱們例子中須要通知的同窗是經過addNotificationStudent方法動態增長進去的),能夠考慮使用觀察者模式(來自《大話設計模式》

(一)、優勢

 一、觀察者和被觀察者是抽象耦合的。

(二)、缺點

一、若是在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,致使死循環。(A通知B,B通知A,A通知B,B通知A ......) 

相關文章
相關標籤/搜索