情況:我正在構建自定義PHP應用程序框架。我已經實現了一個複合模式,所以我可以構建一個表示要呈現的頁面的對象樹。例如:限制使用複合圖案可以相互添加的對象類型
abstract class \Block\BlockAbstract {
protected _blocks = array();
public function __construct($properties);
public function getBlocks();
public function addBlock($block);
...
}
我所有的「塊」對象,通過它的工作了巨大的和渲染這個抽象類繼承一直是一點點遞推的幫助下輕而易舉。
的問題: 我需要一種方法來驗證哪些塊類可以被添加到其他塊。例如,我有4個不同的塊類型,我必須考慮。請記住,所有的塊從單一的塊抽象繼承,這些都是具體類的行爲的分類,而不是額外的摘要混淆:
通用 - 泛型可以添加到任何其他塊類型
最終 - 不能添加任何子塊。
父母 - 父母是塊只能有一個特定類型的孩子加入到 ,但可以添加到任何通用
兒童 - 只能添加到特定的父。該模塊還可以共享一個通用的,家長的性質或Final
總結了進球最多的:給出一個混凝土砌塊類的名稱,生成可被添加到它的所有混凝土砌塊類的列表。
解決方案建議到目前爲止:
一個名爲「blockClassification」屬性添加到塊抽象,它定義爲一個通用的,最終,父母或子女和硬編碼的邏輯放到一個驗證功能從addBlock($ block)方法中調用該方法。
由於種種原因,我不喜歡這個解決方案,但主要是它仍然沒有給我一個明確的路徑來定義具體的父母和孩子是什麼可以被允許的。例如,我有一個具體的類\ Block \ Tabs這是一個父類。它只能添加\ Block \ Tabs \ Panel塊,並且\ Block \ Tabs \ Panel只能添加到\ Block \ Tabs。必須添加其他屬性才能建立這些關係,並且可以檢查這些屬性以導出「塊分類」,從而使這種方法變得不切實際。
將allowedChildTypes屬性添加到定義可添加的具體類列表的塊中。爲了便於使用,2個值具有特定含義,表示所有塊類型的*,以及表示不能添加塊的NULL值。對於所有其他情況,提供了一個以逗號分隔的類名稱字符串,並且只允許那些從它們繼承的類或類允許使用
我傾向於這個方向,因爲PHP給了我InstaceOf運算符。我可以用它來做檢查,當我有新的擴展基本集合的具體類時,該檢查將返回與其父類相同的結果。我唯一猶豫的是,雖然這種方法明確地解決了「給定一個具體的塊類名稱,生成一個列表」的問題,但我覺得它在未來限制了我,因爲我只能在樹上搜索而不是返回向上。即「給定一個子塊類的名稱,生成一個父塊的列表,它可以添加到」
我敢肯定,我不是唯一一個遇到過這個問題,所以我對羣衆的質疑是:解決這個問題的最好方法是什麼?
附加信息:
如果你想知道在那裏我如何在第一時間獲得所有類的列表,該框架實現PSR-0,所以我掃描目錄樹中派生的所有類的名稱,然後動態實例化它們。
$allClassNames = scanDirectories(); // Returns array of strings ex: array('\Block\Classname1','\Block\Classname2');
foreach($allClassNames as $className){
$object = new $className();
}