我有一個場景,我有幾個類從一個共同的祖先延伸出來,因爲它們都共享共同的屬性和方法。這些類中的一半(組A)包含一個不由另一半(組B)共享的屬性,因此組A中的每個類顯式聲明此屬性而不是父類。具有不合作類級別的多態性
例如
class parent
{
}
class child1 <and child2, and child3> extends parent
{
protected $specialProperty;
}
class child4 <and child5, and child5> extends parent
{
// no "$specialProperty"
}
我有一些行爲需要在$specialProperty
上實施該行爲。當然,我想把它放在父類中,只做一次,但$specialProperty
並不存在於所有的子類中。
一種選擇是創建聲明$specialProperty
並實現所需的行爲中間,抽象類,但我不願意這樣做有幾個原因:
- 此方案將是即將到來更快。那我該怎麼做?爲每個功能創建5或6個不同的中間人抽象類?
- 該類的層次結構已經比
parent
高5層左右。我是否真的應該創造越來越多的層面來彌補那些構思不夠理想的階級層次結構,而這種層次結構是以有限的需求來構思的? - 至少就PHP而言,不會有那麼多的繼承層最終導致性能問題?
另一種方法是做到以下幾點:
class parent
{
public function functionThatTheAppWillCallAutomatically()
{
if (property_exists($this, 'specialProperty'))
{
// do stuff with specialProperty
}
}
}
的「東西」會由有$specialProperty
和跳過那些不子類得到執行。我討厭這個解決方案,雖然因爲它只是對我來說似乎是錯誤和馬虎。在我看來,家長不應該根據孩子的特性決定做什麼(哎呀,它可能不應該知道孩子存在 - 這不是孩子班級的原因?)
總之,我不確定這兩個選項中哪一個最不好,或者是否有更好的可能性。我急於等待建議。
謝謝!
編輯:
最後我做了以下實施這一特殊的功能。
class archivalDecorator extends decoratorBase /* decoratorBase just has constructor and the object property */
{
public function archive()
{
if (!$this->object->archive())
{
return false;
}
if (property_exists($this->object, 'specialProperty'))
{
// do extra stuff here that involves "specialProperty"
}
return true;
}
}
這樣,我所有的對象執行相同的檔案工作流程,但需要特殊行爲的類仍然可以執行它沒有我需要實現在這些特殊情況的層級數十個子類。
儘管我仍然使用property_exists(...)
來確定是否需要特殊行爲,但我認爲現在可以,因爲我沒有在父類中做這件事。$specialProperty
是一個公共屬性,所以沒有理由讓外部類不應該知道它,但是對於使用$this
在子類中檢查該屬性的父類感覺錯誤。
我希望我沒有誤用這個概念。
如果我使用裝飾器,我仍然需要應用裝飾器的代碼來檢查對象是否需要裝飾。也就是說,如果它具有「$ specialProperty」,那麼我需要應用裝飾器並調用專門的方法,否則我會正常進行。 所以,我在技術上仍然需要有一些邏輯來研究子類,但是這裏的區別是我在外部而不是從父類進行。 我想這是什麼使它在結構上聽起來很健康。它是否正確? –
這不是裝飾模式的工作原理。如果你走了這條路線,你會重做你的整個班級樹。 –
@Peter Bailey:你能更具體地說我錯了嗎?我應該用調用decorator來替換對「functionThatTheAppWillCallAutomatically()」的調用(僅當「$ specialProperty」存在時),並讓修飾器根據是否聲明「$ specialProperty」決定如何執行操作在對象中?或者我完全離開這裏? –