Home 科技 Java設計模式_(行為型...

Java設計模式_(行為型)_觀察者模式


引用百科

觀察者模式(有時又被稱為發布( publish )-訂閱(Subscribe)模式、模型-視圖(View)模式、源-收聽者(Listener)模式或從屬者模式)是 軟件設計模式 的一種。在此種模式中,一個目標物件管理所有相依於它的觀察者物件,並且在它本身的狀態改變時主動發出通知。這通常透過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。

相關角色

觀察者模式主要包括以下角色:

1、抽象主題(Subject)角色:抽象主題角色把所有對觀察者對象的引用保存在一個聚集(比如ArrayList對象)裡,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象,抽象主題角色又叫做抽像被觀察者(Observable)角色。
2、具體主題(RealSubject)角色:將有關狀態存入具體觀察者對象;在具體主題的內部狀態改變時,給所有登記過的觀察者發出通知。具體主題角色又叫做具體被觀察者(Concrete Observable)角色。
3、抽象觀察者(Observer)角色:為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己,這個接口叫做更新接口。
具體觀察者(RealObserver)角色:存儲與主題的狀態自恰的狀態。具體觀察者角色實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題的狀態像協調。如果需要,具體觀察者角色可以保持一個指向具體主題對象的引用。

具體實現


具體代碼

1、抽象主題類

//抽象主題類public abstract class Subject {
        // 觀察者集合private List<Observer> list = new ArrayList<Observer>();

        // 添加觀察者public void register(Observer observer) {
                list.add(observer);
        }
        //刪除public void remove(Observer observer) {
                if (list.contains(observer)) {
                        list.remove(observer);
                }
        }

        public void change(String status) {
                this.notifyObserver(status);
        }
        //通知所有觀察者private void notifyObserver(String status) {
                for (Observer observer : list) {
                        observer.update(status);
                }
        }
}

2、主題具體實現類

//具體主題角色類public class RealSubject extends Subject {

        private String status;

        public String getStatus() {
                return status;
        }

        public void setStatus(String status) {
                this.status = status;
        }

        public void change(String status) {
                System.out.println("當前主題狀態:" + status);
                super.change(status);
        }
}

3、觀察者接口

//觀察者接口public interface Observer {

        public void update(String status);
}

4、具體觀察者接口實現

//具體觀察者類public class RealObserver implements Observer {

        private String name;
        private String innerStatus;

        public RealObserver(String name) {
                super();
                this.name = name;
        }

        @Override
        public void update(String status) {
                this.innerStatus = status;
                System.out.println("觀察者" + name + ",狀態:" + innerStatus);
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }
}

5、客戶端Client測試

public class Client {

        public static void main(String[] args) {
                // 創建主題RealSubject subject = new RealSubject();

                // 創建觀察者Observer observerA = new RealObserver("張三");
                Observer observerB = new RealObserver("李四");
                // 給主題添加觀察者subject.register(observerA);
                subject.register(observerB);

                // 改變主題內容狀態subject.change("start");
        }
}


以上通過簡單的代碼實現了觀察者模式,運行輸出:

當前主題狀態:start

觀察者張三,狀態:start

觀察者李四,狀態:start

在運行時,這個客戶端首先創建了具體主題類的實例,以及一個觀察者對象。然後,它調用主題對象的register()方法,將這個觀察者對象向主題對象登記,也就是將它加入到主題對象的聚集中去。這時,客戶端調用主題的change()方法,改變了主題對象的內部狀態。主題對像在狀態發生變化時,調用超類的notifyObservers()方法,通知所有登記過的觀察者對象。



文章來源