【问题标题】:Facade design pattern, get attribute from facade外观设计模式,从外观获取属性
【发布时间】:2011-07-04 10:10:10
【问题描述】:

我的应用程序中有类似外观设计模式的东西。我们可以这样开始: http://www.patternsforphp.org/doku.php?id=facade

来自示例:
门面 = 计算机
部件:CPU、内存...

这种情况的解决方案是什么:计算机有一个ID。大多数部分不需要知道计算机 ID,但有几个部分与 World 通信,例如。网卡,需要知道放置在哪的Computer ID。

怎么办 - 最好的解决方案是什么?
感谢您的回复。

【问题讨论】:

  • 如果我编写了这部分我不知道的代码,那就是门面——它自然而然地上升了。但是,如果代码应该仍然很好的可维护性和一致性问题,这就很复杂了。身份证换了怎么办?
  • 你能澄清一下这个问题吗,因为现在我完全不明白你在问什么。 Facade 定义了一个更高级别的接口,使子系统更易于使用。
  • 实际上:我有带有方法 Javascript::addVariable() 的静态类,它将变量从 php 传递到 javascript。外观的某些部分需要将一些变量传递给 javascript,但在 javascript 中我需要将这些值分配给计算机。
  • 我没有真正的门面。但是类的系统和上面的例子(url)是一样的。
  • 您确定计算机需要 ID 吗?是否应该将 ID 作为其 Mac 地址或其他类型移动到网卡?

标签: php design-patterns facade


【解决方案1】:

如果我知道你想要这样的东西: 当您创建特定部分并将其私有存储在对象中时,您需要将 computerId 发送到特定部分。就像在 NetworkDrive 中一样。 之后,您可以根据需要使用 computerId。

class CPU
{
    public function freeze() { /* ... */ }
    public function jump( $position ) { /* ... */ }
    public function execute() { /* ... */ }

}

class Memory
{
    public function load( $position, $data ) { /* ... */ }
}

class HardDrive
{
    public function read( $lba, $size ) { /* ... */ }
}

class NetworkDrive
{
     private $computerId;

     public function __construct($id)
     {
         $this->computerId = $id;
     }

     public function send() { echo $this->computerId; }

}

/* Facade */
class Computer
{
    protected $cpu = null;
    protected $memory = null;
    protected $hardDrive = null;
    protected $networkDrive = null;
    private $id = 534;

    public function __construct()
    {
        $this->cpu = new CPU();
        $this->memory = new Memory();
        $this->hardDrive = new HardDrive();
        $this->networkDrive = new NetworkDrive($this->id);
    }

    public function startComputer()
    {
        $this->cpu->freeze();
        $this->memory->load( BOOT_ADDRESS, $this->hardDrive->read( BOOT_SECTOR, SECTOR_SIZE ) );
        $this->cpu->jump( BOOT_ADDRESS );
        $this->cpu->execute();
        $this->networkDrive->send();
    }
}

/* Client */
$facade = new Computer();
$facade->startComputer();

您可以使用观察者模式来通知 networkDrive 对象,以便最终更改 computerId

【讨论】:

  • 是的,就是这样。但是......我有一种不好的感觉,将计算机的 ID“存储”在几个对象而不是一个对象中。 (一致性 - 更改计算机的 id 等)
  • 所以我认为,我需要类似指向 NetworkCard 中计算机实例的指针而不是 ID。 (我们可以假设计算机有 getId() 方法)。
  • 当你改变计算机id时,你可以使用观察者模式,并通知NetworkDrive对象改变存储的computerId。可以作为解决方案。您不能发送参考,因为您可以更改 networkDrive 中的值,这不太好。您可以发送整个对象计算机,并使用您需要使用的东西( $this->networkDrive = new NetworkDrive($this); )。我推荐使用观察者模式
  • 我明白了。它会起作用的。但是,我仍然有疑问 - 有没有更简单的方法可以从它的部分获取计算机 ID?无需更改构造函数。简单,类似于:((Computer) Computers::getComputerByPart(IPart $this))->getId(); 没有模式(或最佳实践)吗?
  • 这看起来更难实现,但我认为可以。