熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

觀察者模式 - 設計模式

2013-11-23 19:52:05  來源: Java高級技術 

  觀察者模式定義了一個一對多的對象關系一個主體對象對應多個觀察者對象當主體對象發生改變時所有它對應的觀察者對象都會自動得到通知並更新

  本文將給出一個相應的事例具體說明觀察者模式是如果工作的這個事例演示了一個當一個任務的信息改變時通知這個任務所涉及所有人員的事例任務信息包括任務狀態任務所采用的處理流程和任務完成後的checklist[用來確保任務完成所有預定需要完成的功能列表和避免一些常見的錯誤]

  先定義兩個接口主體對象接口和觀察者對象接口

   /** *//**
 * 主體對象接口定義了注冊觀察者取消觀察者和通知觀察者方法
 *
 */
public interface ISubject {

    /** *//**
     * 為該主體對象注冊一個觀察者
     */
    public void registerObserver(IObserver observer);

    /** *//**
     * 從該主體對象中取消一個觀察者的注冊
     */
    public void removeObserver(IObserver observer);

    /** *//**
     * 通知所有觀察者
     */
    public void notifyObserver();
}

   /** *//**
 * 觀察者接口簡單定義了一個用來更新觀察者信息的接口
 * 當主體對象被更新時這個接口方法會被自動調用並更新信息
 */
public interface IObserver {

    /** *//**
     * 接口方法用來更新觀察者的信息
     */
    public void remind(ITask taskSubject);
}

  這兩個接口只定義了主題對象和觀察者對象所需要的接口但是沒有實現任何任務相關的具體的方法和接口下面會再定義一個任務接口來規定任務應該具備的功能這樣分開定義的好處在於如果我們將不同的模塊分解開來如果一方需要更新另一方不會受到影響

   /** *//**
 * 這裡定義了一個任務應該具有的功能
 */
public interface ITask {

    public void setStatus(String status);
    public String getStatus();

    public void setProcess(String process);
    public String getProcess();

    public void setCheckList(String checkList);
    public String getCheckList();
}

  然後我們創建具體的任務主體這裡我們會實現ISubejct ITask兩個接口

   import javautilArrayList;
import javautilList;


public class TaskSubject implements ISubject ITask {
    // 在這裡對觀察者列表進行初始化因為是靜態初始化所以保證在這個運行過程中只有一個實例得到初始化
    static {
        _observers = new ArrayList<IObserver>();
    }

    @Override
    public void notifyObserver() {
        // 調用觀察者的方法通知並更新觀察者信息
        for(IObserver observer : _observers) {
            observerremind(this);
        }
    }

    @Override
    public void registerObserver(IObserver observer) {
        if(ntains(observer)) {
            Systemoutprintln( + observer +  > is already registed!);
        }

        // Register an observer
        _observersadd(observer);
        Systemoutprintln( + observer +  > is registed successfully!);
    }

    @Override
    public void removeObserver(IObserver observer) {
        if(!ntains(observer)) {
            Systemoutprintln( + observer +  > is never registed!);
        }

        // Remove an observer
        _observersremove(observer);
        Systemoutprintln( + observer +  > is removed successfully!);
    }

    @Override
    public String getCheckList() {
        return this_checkList;
    }

    @Override
    public String getProcess() {
        return this_process;
    }

    @Override
    public String getStatus() {
        return this_status;
    }

    @Override
    public void setCheckList(String checkList) {
        this_checkList = checkList;
    }

    @Override
    public void setProcess(String process) {
        this_process = process;
    }

    @Override
    public void setStatus(String status) {
        this_status = status;
    }

    // 這裡將觀察者列表定義為一個靜態的變量這樣可以保證自始至終只有一個變量列表便於系統的維護
    // 這裡用到了泛型這樣在對這個列表進行操作的時候無需再進行類型的轉換
    private static List<IObserver> _observers;
    private String _status;
    private String _process;
    private String _checkList;
}

  在這裡我們沒有給觀察者定義接口而是使用了一個抽象類因為所有的觀察者都必須從主體對象那裡獲取信息而且獲取信息的方法都是一樣的這樣可以避免重復編碼

   /** *//**
 * 這個抽象類繼承了Iobserver接口所以我們必須實現remind方法
 * 在remind方法中從主體對象中獲取所有需要的信息
 * 並調用sendEmail方法對觀察者實時進行更新
 */
public abstract class TaskObserver implements IObserver {

    @Override
    public void remind(ITask taskSubject) {
        this_status = taskSubjectgetStatus();
        this_process = taskSubjectgetProcess();
        this_checkList = taskSubjectgetCheckList();

        // 更新觀察者對象
        thissendEmail();
    }

    public abstract void sendEmail();

    // 工具類方法減少編碼數量增加可讀性
    public void print(String msg) {
        Systemoutprintln(msg);
    }

    // 在父類中定義參數減少重復編碼
    protected String _status;
    protected String _process;
    protected String _checkList;
}

  然後定義任務受托人[assignee]檢查者報告者他們都繼承TaskObserver類這樣減少了代碼的重復而且方便了代碼的維護

   public class Assignee extends TaskObserver {

    @Override
    public void sendEmail() {
        print([Assignee] The current status is : < + this_status + >);
        print([Assignee] The current process is : < + this_process + >);
        print([Assignee] The current checklist is : < + this_checkList + >);
    }

    public String toString() {
        return Assignee;
    }
}



public class Reviewer extends TaskObserver {

    @Override
    public void sendEmail() {
        print([Reviewer] The current status is : < + this_status + >);
        print([Reviewer] The current process is : < + this_process + >);
        print([Reviewer] The current checklist is : < + this_checkList + >);
    }

    public String toString() {
        return Reviewer;
    }
}


public class Reporter extends TaskObserver {

    @Override
    public void sendEmail() {
        print([Reporter] The current status is : < + this_status + >);
        print([Reporter] The current process is : < + this_process + >);
        print([Reporter] The current checklist is : < + this_checkList + >);
    }

    public String toString() {
        return Reporter;
    }
}

  然後我們需要編寫一個類用來演示觀察者模式在這個類中會演示注冊觀察者取消特定觀察者更改主體對象信息然後觀察者自動得到通知並更新信息

   public class TaskManager {

    public static void main(String[] args) {
        // Create subject
        TaskSubject taskSubject = new TaskSubject();

        // Create observers
        IObserver assignee = new Assignee();
        IObserver reviewer = new Reviewer();
        IObserver reporter = new Reporter();

        // 注冊觀察者[因為我們使用的是一個列表所以在通知觀察者的時候是按照添加的順序通知的]
        taskSubjectregisterObserver(assignee);
        taskSubjectregisterObserver(reviewer);
        taskSubjectregisterObserver(reporter);

        // 更新主體對象的信息
        taskSubjectsetStatus(Assigned);
        taskSubjectsetProcess(No Process Attacted);
        taskSubjectsetCheckList(CheckList Version );

        // 通知所有觀察者
        taskSubjectnotifyObserver();

        // 更新主體對象信息
        taskSubjectsetStatus(In Progress);
        taskSubjectsetProcess(Process Attached);
        taskSubjectsetCheckList(CheckList Version Final Version);

        // 取消報告者的注冊並通知剩余所有觀察者
        taskSubjectremoveObserver(reporter);
        taskSubjectnotifyObserver();
    }
}

  輸出的信息如下

   < Assignee > is registed successfully!
< Reviewer > is registed successfully!
< Reporter > is registed successfully!

[Assignee] The current status is : <Assigned>
[Assignee] The current process is : <No Process Attacted>
[Assignee] The current checklist is : <CheckList Version >

[Reviewer] The current status is : <Assigned>
[Reviewer] The current process is : <No Process Attacted>
[Reviewer] The current checklist is : <CheckList Version >

[Reporter] The current status is : <Assigned>
[Reporter] The current process is : <No Process Attacted>
[Reporter] The current checklist is : <CheckList Version >

< Reporter > is removed successfully!

[Assignee] The current status is : <In Progress>
[Assignee] The current process is : <Process Attached>
[Assignee] The current checklist is : <CheckList Version Final Version>

[Reviewer] The current status is : <In Progress>
[Reviewer] The current process is : <Process Attached>
[Reviewer] The current checklist is : <CheckList Version Final Version>


From:http://tw.wingwit.com/Article/program/Java/gj/201311/27595.html
  • 上一篇文章:

  • 下一篇文章:
  • Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.