Yii2設計模式——靜態工廠模式

米粒人生發表於2018-12-28

應用舉例

yiidbActiveRecord

//獲取 Connection 例項
public static function getDb()
{
    return Yii::$app->getDb();
}

//獲取 ActiveQuery 例項 
public static function find()
{
    return Yii::createObject(ActiveQuery::className(), [get_called_class()]);
}

這裡用到了靜態工廠模式。

靜態工廠

利用靜態方法定義一個簡單工廠,這是很常見的技巧,常被稱為靜態工廠(Static Factory)。靜態工廠是 new 關鍵詞例項化的另一種替代,也更像是一種程式設計習慣而非一種設計模式。和簡單工廠相比,靜態工廠通過一個靜態方法去例項化物件。為何使用靜態方法?因為不需要建立工廠例項就可以直接獲取物件。

和Java不同,PHP的靜態方法可以被子類繼承。當子類靜態方法不存在,直接呼叫父類的靜態方法。不管是靜態方法還是靜態成員變數,都是針對的類而不是物件。因此,靜態方法是共用的,靜態成員變數是共享的。

程式碼實現

//靜態工廠
class StaticFactory
{
    //靜態方法
    public static function factory(string $type): FormatterInterface
    {
        if ($type == `number`) {
            return new FormatNumber();
        }

        if ($type == `string`) {
            return new FormatString();
        }

        throw new InvalidArgumentException(`Unknown format given`);
    }
}

//FormatString類
class FormatString implements FormatterInterface
{
}

//FormatNumber類
class FormatNumber implements FormatterInterface
{
}

interface FormatterInterface
{
}

使用:

//獲取FormatNumber物件
StaticFactory::factory(`number`);

//獲取FormatString物件
StaticFactory::factory(`string`);

//獲取不存在的物件
StaticFactory::factory(`object`);

Yii2中的靜態工廠

Yii2 使用靜態工廠的地方非常非常多,比簡單工廠還要多。關於靜態工廠的使用,我們可以再舉一例。

我們可通過過載靜態方法 ActiveRecord::find() 實現對where查詢條件的封裝:

//預設篩選已經稽核通過的記錄
public function checked($status = 1)
{
    return $this->where([`check_status` => $status]);
}

和where的鏈式操作:

Student::find()->checked()->where(...)->all();
Student::checked(2)->where(...)->all();

詳情請參考我的另一篇文章 Yii2 Scope 功能的改進

相關文章