只有班級的主人可以調用registerMaster方法。在這個例子中,有哪些方式可以幫助我?
在PHP中沒有朋友類的概念,所以沒有辦法從另一個類隱藏公共方法。
你可以使用繼承和保護的可見
abstract class LinkedEntity {
protected $master;
protected $slave;
}
class Master extends LinkedEntity {
public function __construct(Slave $slave) {
$this->slave = $slave;
$this->slave->master = $this;
}
}
class Slave extends LinkedEntity {}
$slave = new Slave;
$master = new Master($slave);
由於Master和Slave現在延長相同的基類,受保護的屬性都可以訪問他們,而不是任何其他類。在LinkedEntity類中定義的受保護方法也是如此。所以你可以放一個protected registerMaster(Master $master)
方法並且通過它來代替直接分配屬性。我個人覺得不那麼漂亮,我想知道你是否真的需要雙向關聯,或者是否有足夠的單向關聯性,例如,從主站到從站,或反之亦然。
另一個,甚至更壞的選擇,將是檢查調用堆棧:
class Slave {
private $master;
public function registerMaster(Master $master)
{
if (debug_backtrace(null, 2)[1]["class"] === Master::class) {
throw new RuntimeException("Only Masters may call Slaves");
}
$this->master = $master;
}
}
的方法檢查調用堆棧(在一個沒有來電轉接到您registerMaster
以前的類實際上是一個大師。然而,當你的方法取決於誰是被叫方是信息,它通常是設計不良的徵兆。
第三種選擇是通過通過反射奴隸的方法的可見性突破,如
class Master {
private $slave;
public function __construct(Slave $slave) {
$this->slave = $slave;
$fn = new ReflectionMethod($slave, 'registerMaster');
$fn->setAccessible(true);
$fn->invoke($slave, $this);
}
}
class Slave {
private $master;
private function registerMaster(Master $master)
{
$this->master = $master;
}
}
同樣,這不是最優的,因爲OOP的核心原則是信息隱藏,我們在這裏打破它。我們正在突破指定的私人知名度並強制它向公衆公開。此外,這不會阻止任何其他對象執行相同的操作。
什麼是找你問題現在呢? – jmattheis
我想禁用registerMaster外面,以便用戶不能自己做這個。 – Mati
您的問題沒有意義 - 請清理並正確定義。我所看到的只是你只想讓'Master'能夠調用'registerMaster()'? – Darren