1. 程式人生 > >java設計模式之空物件模式

java設計模式之空物件模式

一、空物件模式簡介
在空物件模式中,一個空物件取代NULL物件的例項的檢查。NULL物件不是檢查空值,而是反映一個不做任何動作的關係。這樣的NULL物件也可以在資料不可用的時候提供預設的行為。
在空物件模式中,我們建立一個指定各種要執行的操作的抽象類和擴充套件該類的實體類,還建立一個未對該類做任何實現的空物件類,該空物件類將無縫地使用在需要檢查空值的地方。
空物件模式一般和策略模式或工廠模式結合使用。

二、示例演示
1、業務需求
假設這樣一個場景:
在一個圖書資訊查詢系統中,你呼叫一個方法,傳過去你要查詢圖書的ID,然後它返回給你,你要查詢的圖書物件,這樣你就可以呼叫物件的方法來輸出圖書的資訊。
下面,我們來實現以下具體的程式碼。
2、不使用空物件設計模式
首先,我們來看一下ConcreteBook類的程式碼(提供建構函式和展示圖書資訊的show()方法。)
public class ConcreteBook {
    private int ID;
    private String name;
    private String author;
 
    // 建構函式
    public ConcreteBook(int ID, String name, String author) {
        this.ID = ID;
        this.name = name;
        this.author = author;
    }
    //顯示圖示資訊
    public void show() {
        System.out.println(ID + "**" + name + "**" + author);
    }
 
}

再來看看建立圖書物件的圖書工廠的程式碼(主要提供一個獲得ConcreteBook的方法):
public class BookFactory {
    
    public ConcreteBook getBook(int ID) {
        ConcreteBook book = null;
        switch (ID) {
        case 1:
            book = new ConcreteBook(ID, "設計模式", "GoF");
            break;
        case 2:
            book = new ConcreteBook(ID, "我的設計模式", "空物件模式");
            break;
        default:
            book = null;// 其實這個可以省略,因為初始化已經賦值為null。
            break;
        }
 
        return book;
    }
}

最後,來看一下客戶端的程式碼:
public class Client {
 
    static void main(String[] args) {
        BookFactory bookFactory = new BookFactory();
        ConcreteBook book = bookFactory.getBook(1);
        book.show();
    }
 
}
執行結果:
1**設計模式**GoF
如果我們把ConcreteBook book = bookFactory.getBook(1);中的1改為-1則會出現空指標異常,因為我們通過bookFactory.getBook()方法獲取ConcreteBook物件的時候,如果我們傳入的引數,即圖書的ID,屬於非法值(如-1)或者不存在(如3)的話(其實這種情況是經常遇到的。),就會返回null,表示我們查詢的圖書資訊並不存在。這時,book為null.你再呼叫book.show()。當然要報空指標的錯誤了。那怎麼解決呢?我們可以使用空物件模式來解決這個問題。

3、使用空物件模式

首先定義一個抽象介面Book類
public interface Book {
    // 判斷Book物件是否為空物件(Null Object)
    public boolean isNull();
 
    // 展示Book物件的資訊內容。
    public void show();
}
然後新增一個空物件類NullBook類和一個非空物件類ConcreteBook類
public class NullBook implements Book {
    public boolean isNull() {
        return true;
    }
 
    public void show() {
        System.out.println("Sorry,未找到符合您輸入的ID的圖書資訊,請確認您輸入的不是非法值。");


    }
}
public class ConcreteBook implements Book{
    private int ID;
    private String name;
    private String author;
 
    // 建構函式
    public ConcreteBook(int ID, String name, String author) {
        this.ID = ID;
        this.name = name;
        this.author = author;
    }


    public void show() {
        System.out.println(ID + "**" + name + "**" + author);
    }
    public boolean isNull(){
        return false;
    }
}

定義工廠類(返回物件從ConcreteBook改為Book,並當ID屬於非法值或者不存在時,返回NullBook物件。)
public class BookFactory {
   
    public Book getBook(int ID) {
        Book book;//將原來的ConcreteBook改為Book
        switch (ID) {
        case 1:
            book = new ConcreteBook(ID, "設計模式", "GoF");
            break;
        case 2:
            book = new ConcreteBook(ID, "我的設計模式", "空物件模式");
            break;
        default:
            book = new NullBook();//建立一個NullBook物件
            break;
        }
 
        return book;
    }
}

測試程式碼
public static void main(String[] args) {
        BookFactory bookFactory = new BookFactory();
        Book book = bookFactory.getBook(-1);
        book.show();
}

這樣即使輸入的引數不合法,不會出現程式異常,但會提醒使用者輸入引數不合法。

三、總結
空物件模式的優點
1、它可以加強系統的穩固性,能有有效地防止空指標報錯對整個系統的影響,使系統更加穩定。
2、它能夠實現對空物件情況的定製化的控制,能夠掌握處理空物件的主動權。
3、它並不依靠Client來保證整個系統的穩定執行。
4、它通過isNull對==null的替換,顯得更加優雅,更加易懂。