Java設計模式之空對象模式實現教程

1 Null Object Pattern 空對象模式

目的:當一個對象不存在的時候,用一個空對象取代 null ,以提供默認無任何行為的對象替代品;

實現:對於對象不存在的情況返回一個預定義的空對象,而不是null。

1.我們創建一個指定各種要執行的操作的抽象類和擴展該類的實體類,還創建一個未對該類做任何實現的空對象類,該空對象類將無縫地使用在需要檢查空值的地方;

2.一個對象需要一個協作對象,但並無具體的協作對象,而且協作對象不需要做任何事情的時候使用;

2 實現

代碼場景:手機賣場去富士康訂購多個品牌的手機,如果想要訂購的品牌富士康在生產,則進行訂購;

如果該品牌富士康不生產,富士康則會有一個官方的描述。

1. 程式中富士康生產的品牌就是具體對象角色

2. 程式中富士康不生產的品牌空對象角色

3. 因劇情需要代碼中還有兩個工廠類,這個場景不同,會有不同實現

2.1 代碼實現

抽象對象角色:AbstractPhone類

public abstract class AbstractPhone {
    protected String phoneName;
    public abstract boolean isNil();
    public abstract String getPhoneName();
}

具體對象角色:ExistingPhone類

public class ExistingPhone extends AbstractPhone {
    public ExistingPhone(String phoneName) {
        this.phoneName = phoneName;
    }
    @Override
    public boolean isNil() {
        return false;
    }
    @Override
    public String getPhoneName() {
        return phoneName;
    }
}

空對象角色:NonexistentPhone類

public class NonexistentPhone extends AbstractPhone {
    @Override
    public boolean isNil() {
        return true;
    }
    @Override
    public String getPhoneName() {

        return "後續會增加該廠商手機產線,生產其品牌手機~";
    }
}

使用瞭空對象的工廠類1:PhoneFactory類

public class PhoneFactory {
    public static final String[] phones = {"小米", "錘子", "蘋果"};

    public static AbstractPhone getPhone(String name) {
        for (String phoneName : phones) {
            if (phoneName.equals(name)) {
                return new ExistingPhone(name);
            }
        }
        // 空對象設計模式 關鍵之處
        return new NonexistentPhone();
    }
}

未使用空對象的工廠類2:PhoneFactoryWithoutNull類

public class PhoneFactoryWithoutNull {
    public static final String[] phones = {"小米", "錘子", "華為"};

    public static AbstractPhone getPhone(String name) {
        for (String phoneName : phones) {
            if (phoneName.equals(name)) {
                return new ExistingPhone(name);
            }
        }
        // 不使用空對象思想 一般在找不到的時候 返回一個null
        return null;
    }
}

2.2 涉及角色

空對象模式包含如下兩個角色:

(1) AbstractObject(抽象對象角色):聲明協作對象的接口,如果需要,可以實現默認行為。

(2) ConcreteObject(具體對象角色):具體的協作對象類,提供有意義的行為。

(3) NullObject(空對象角色):空對象類,繼承自 AbstractObject,但接口實現不做任何事情。

2.3 調用

調用者:

public class Client {
    public static void main(String[] args) {
        // 因為沒有這個品牌手機的存在,所以訂購的對象是ExistingPhone對象,而不是null
        AbstractPhone apple = PhoneFactory.getPhone("蘋果");
        AbstractPhone xiaoMi = PhoneFactory.getPhone("小米");
        AbstractPhone chuiZi = PhoneFactory.getPhone("錘子");
        AbstractPhone huaWei = PhoneFactory.getPhone("華為");

        System.out.println("--------------返回空對象--------------");
        System.out.println("可以從富士康訂購的手機:");
        System.out.println(xiaoMi.getPhoneName());
        System.out.println(chuiZi.getPhoneName());
        System.out.println(huaWei.getPhoneName());
        System.out.println(apple.getPhoneName());

        System.out.println("--------------返回null---------------");
        // 因為沒有這個品牌手機的存在,所以訂購的對象是ExistingPhone對象,而不是null
        AbstractPhone nokia = PhoneFactoryWithoutNull.getPhone("諾基亞");
        System.out.println("可以從富士康訂購的手機:");
        System.out.println(nokia.getPhoneName());

    }
}

結果:

--------------返回空對象--------------
可以從富士康訂購的手機:
小米
錘子
後續會增加該廠商手機產線,生產其品牌手機~
蘋果
--------------返回null---------------
可以從富士康訂購的手機:
Exception in thread "main" java.lang.NullPointerException
    at com.wxx.behavioral.nullobject.Client.main(Client.java:21)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。