2012-12-11 77 views
0

如何確保只有通過另一個特定對象才能實例化對象?如何確保特定對象僅由另一個對象實例化?

例如,假設我有一個Registry對象來存儲Mappers。當客戶端代碼在註冊表中調用get()方法時,它懶惰地加載並返回請求的映射器。這很好,除了沒有什麼可以阻止客戶端代碼使用new運算符創建映射器的重複實例。

我能想到的唯一選擇是我的Mappers需要一個Registry對象作爲參數。還有其他選擇嗎?

你是做什麼的?我是否應該避免這種重複?

+0

也許我沒有得到你的問題,但爲什麼你不宣佈Mapper靜態? –

回答

1

也許你不應該試圖阻止人們自己創建實例嗎?如果你不相信你自己或你的同事不要在不應該​​實例化它們的地方實例化對象,那你就有問題。

如果映射器不需要註冊表來運行,則不應該通過構造函數來對其進行反對。將它傳遞給一些靜態方法似乎很奇怪,並且使得你的代碼因爲使用靜態而變得更加靈活。你將如何單元測試映射器,而無需編寫一些黑客程序,通過註冊表正確地實例化它們,這些測試中不需要這些註冊表?好的帖子在這裏:http://kore-nordmann.de/blog/0103_static_considered_harmful.html

0

您無法保護new運營商。你可以做的是,你的類中有一個get()方法來創建你的類/對象單例(或者像你一樣使用註冊表)。

class clTest { 
private static $oInstance; 

public static function get() { 
    if(!self::$oInstance) { 
    self::$oInstance = new clText; 
    } 

    return self::$oInstance; 
} 
} 
0

,如果你想防止外界實例你只需要聲明__construct私營然後用調用一個靜態方法來獲取映射類的一個實例。然後,您可以傳入註冊表類的實例,並且只有在參數是註冊表類的實例時才返回新實例。

class Mapper{ 
    private __construct(){} 

    public static function getInstance($registry){ 
    if($registry instanceof Registry){ 
     return new Mapper(); 
    } 
    } 
} 

$registry = new Registry(); 
$mapper = Mapper::getInstance($registry);