2012-02-17 34 views
2

工廠不是一般的單身人士嗎?或者工廠模式有時可能是Singleton? 假設我們有以下的工廠模式類:工廠模式可以是一個通用的單例模式嗎?

abstract class Factory { 

    /* This cache contains objects that has already been called. 
    ** It stores the class name, arguments and the object itself. 
    ** If an another call for the same class with the same arguments 
    ** is made we return the object. 
    */ 
    private static $cache; 

    public static function __callStatic($class, $args) { 
     // 1) we check if the class already exists in the cache 

      // 2) if it does then we return the object in the cache 

      // 3.1) otherwise we create a new object 
      // 3.2) we pass to the constructor of that object the arguments with ReflectionClass 
      // 3.3) we store the class name, arguments and object in the cache 
    } 

} 

而具體的類

class My extends Factory {} 

而且假設我們有一個類DontKnow($arg1, $arg2)接受參數$arg1$arg2的構造。假設我們有另一個類DoNot(),它不接受構造函數的任何參數。

現在,當我們調用

My::DontKnow('sample', 3); 

我們返回現在存儲在我們的工廠類的緩存中的對象。 如果我們再次調用它,我們的工廠類將不會實例化一個新對象,但會再次使用它。

因此,例如,如果我們設置了My::DontKnow('sample', 3)->setSomething('key', 'myvalue');,並在另一個範圍內,我們將其撥打My::DontKnow('sample', 3)->getSomething('key');,它將打印myvalue

但是,如果我們稱之爲My::DoNot()工廠類將返回類DONOT的「單」對象(),由於我們的工廠類My是靜態的,具有靜態的範圍,可以的話,到處叫。

這不是Singleton的另一個例子嗎?這是爲了避免Singleton模式?

+1

工廠並不一定,甚至是典型的,緩存它創建的對象,也不是工廠通常被稱爲靜態。你描述的是一個註冊表或Singleton,而不是工廠。 – deceze 2012-02-17 07:39:10

+0

@deceze,但這是一個工廠類。它只是靜態地產生對象。這是事實,沒有必要這樣做。但可能會發生。這不是一個單身人士。除了它是靜態的這一事實之外,它與單例無關。 – Shoe 2012-02-17 07:42:24

+2

僅僅因爲你叫*它'工廠'並不意味着它是一個。 :)你擁有的是一個靜態的Singleton Registry Factory服務定位器,而不僅僅是一個簡單的工廠。 – deceze 2012-02-17 07:55:49

回答

4

不,它不是。你所描述的將是工廠模式的特殊用例,或者根本不是工廠。一個簡單的工廠不會執行「實例管理」,它只是返回所需具體子類的新實例。

工廠方法本身是靜態的這一事實並不意味着返回的子類的方法是。正如名稱所述,工廠生產具有非靜態功能的具體對象。

http://sourcemaking.com/design_patterns/factory_method

+0

+1他說的。 – kingmaple 2012-02-17 08:00:55

+0

好的,應該避免使用它還是可以使用它? – Shoe 2012-02-17 08:20:18

+0

這是你的靜態Singleton Registry Factory服務定位器嗎?我不知道,這取決於...我認爲你應該避免,如果你能避免它。它是否讓單元測試更加困難?是。 – markus 2012-02-17 10:45:01