2012-02-14 77 views
1

另一位開發人員和我正在構建網站的過程中,我們實現了我們自己的OOP模型,我們進行了很多討論,但似乎我遇到了一堵磚牆。 請多多包涵OOP繼承

我們所有的類擴展對象,它有一個構造函數,它使用get_called_class()獲取類,然後get_class_vars()等加載列名,這意味着我們可以有一個savedeletedisplayExisting,getAll,以及默認情況下類中的其他幾個方法,這消除了很多代碼。這很好。現在,我有一個類InboundData,這有3個班擴展超出自身,稱爲VisitEnquiryBrochureRequest,他們有一個「inbound_data_id」,然後InboundData有一個重載的構造看起來像這樣:

function __construct($id = '') 
{ 
    $this->className = get_called_class(); 
    $this->id = (int)$id; 
    $this->tableName = strtolower($this->className); 
    $this->setDbFields(); 
    $this->loadData(); 

    $this->contact = new Contact($this->contact_id); 
    $this->address = new Address($this->address_id); 
    $this->domain = new Domain($this->domain_id); 
    $this->park = new Park($this->park_id); 
} 

問題是,contact,address,domainpark都是受保護的,以阻止Object的方法將它們作爲列名/類變量進行拾取。這是我們對所有非分貝成員所採用的方法,如:

protected $contact; 
protected $address; 
protected $domain; 
protected $park; 

我們沒有遇到任何問題,直到寫前端代碼中,我發現,我顯然不能填$formObj->contact->var等,更不用說我沒有寫入任何保存代碼的入站數據擴展對象,這將需要保存所有附加的表。

請OOP大師讓我們知道我們出錯的地方,以及完成這個的最好方法是什麼。隨意提出任何問題,我知道這聽起來應該讓人感到困惑。

+0

你有沒有嘗試寫一個getter? '函數get($ field){return $ this - > $ field; }'並使用'get(「contact」)'提取聯繫人 – 2012-02-14 15:04:45

+0

順便說一句,'get_called_class'是多餘的,因爲'__CLASS__'魔術常數的行爲起始於PHP 5 – rdlowrey 2012-02-14 15:33:08

+0

@rdlowrey謝謝,將來會使用Eugen什麼即時使用現在,但它並沒有幫助保存:(此擴展業務已經搞砸了我:/ – 2012-02-14 15:37:36

回答

1

我不知道如果我明白你正在嘗試做的,但它聽起來像你有某種顯示頁面的Template對象,你想要得到的Enquiry(例如)contact價值將其應用於模板。我建議做這樣的事情:

class TemplateBuilder { 
    public static function addDataToTemplate(Template $tpl, Object $enq) { 
     $enq->addToTemplate($tpl); 
    } 
} 

這不是完全必要的,但接下來的步驟是:

class Enquiry extends Object { 
    ... 
    public function addToTemplate(Template $tpl) { 
     $tpl->contact->var = $this->contact; 
    } 
} 

這樣可以使受保護的只是你希望它像Enquiry -only數據,以及您可以非常明確地控制要添加到哪些對象的數據。

這是一個有點偏離的話題,但我建議不要使用擴展和所有這些魔法。如果你有很多實用的方法可以使用Object的類,你可以用Object(或者其他所謂的)作爲成員來構建它們,然後通過合成來使用它。

1

通常從Object中擴展一切並不是一個好主意。它在你的模型中增加了許多不屬於的方法。它也打破了基本的關係 - 你通常會從一個好的對象模型中期待一種關係。

在不考慮前端的情況下構建後端也不是什麼好主意。它導致了浪費的努力。

就設置屬性而言。你不能簡單地添加getters/setters來訪問你需要的東西嗎?你有沒有考慮過使用__get()和__set()魔術方法?

跟蹤需要保存的修改的常用方法是使用isDirty標誌。下一個問題是跟蹤從數據庫加載的對象。這通常通過使用實體管理器來解決。

如果遇到無法解析的對象設置屬性的問題,可以使用Reflection API強制設置一些屬性。 ReflectionProperty :: setAccessible()可以讓你在私有/受保護的屬性上設置一個值。

+0

這個效果非常好,謝謝,除了當試圖保存inbounddata對象,當前正在save()'d visit,然後在那個重載的save )有一個對parent :: save()的調用;不知何故,它不僅從inbounddata中返回變量,而且還從visit中返回變量,所有變量都使用Object中的get_class_vars。 – 2012-02-14 15:31:29