2016-07-08 29 views
-2

代码示例:https://sourcemaking.com/design_patterns/composite/php我做了类似的事情,但“OnTheBookShelf”知道大约$本书(SeveralBooks)。我的“老板”说他们知道彼此的不好。但为什么?复合模式,为什么“孩子”知道“父母”是不好的?

还好吧,我编辑:

abstract class OnTheBookShelf { 
    public $shelf; ///////////////////////////////////////////////// 
    abstract function getBookInfo($previousBook); 
    abstract function getBookCount(); 
    abstract function setBookCount($new_count); 
    abstract function addBook($oneBook); 
    abstract function removeBook($oneBook); 
} 

class OneBook extends OnTheBookShelf { 
    private $title; 
    private $author; 
    function __construct($title, $author) { 
     $this->title = $title; 
     $this->author = $author; 
    } 
    function getBookInfo($bookToGet) { 
     if (1 == $bookToGet) { 
     return $this->title." by ".$this->author; 
     } else { 
     return FALSE; 
     } 
    } 
    function getBookCount() { 
     return 1; 
    } 
    function setBookCount($newCount) { 
     return FALSE; 
    } 
    function addBook($oneBook) { 
     return FALSE; 
    } 
    function removeBook($oneBook) { 
     return FALSE; 
    } 
} 

class SeveralBooks extends OnTheBookShelf { 
    private $oneBooks = array(); 
    private $bookCount; 
    public function __construct() { 
     $this->setBookCount(0); 
    } 
    public function getBookCount() { 
     return $this->bookCount; 
    } 
    public function setBookCount($newCount) { 
     $this->bookCount = $newCount; 
    } 
    public function getBookInfo($bookToGet) { 
     if ($bookToGet <= $this->bookCount) { 
     return $this->oneBooks[$bookToGet]->getBookInfo(1); 
     } else { 
     return FALSE; 
     } 
    } 
    public function addBook($oneBook) { 
     $oneBook->shelf = $this; ////////////////////////////////////////////////// 
     $this->setBookCount($this->getBookCount() + 1); 
     $this->oneBooks[$this->getBookCount()] = $oneBook; 
     return $this->getBookCount(); 
    } 
    public function removeBook($oneBook) { 
     $counter = 0; 
     while (++$counter <= $this->getBookCount()) { 
     if ($oneBook->getBookInfo(1) == 
      $this->oneBooks[$counter]->getBookInfo(1)) { 
      for ($x = $counter; $x < $this->getBookCount(); $x++) { 
      $this->oneBooks[$x] = $this->oneBooks[$x + 1]; 
      } 
      $this->setBookCount($this->getBookCount() - 1); 
     } 
     } 
     return $this->getBookCount(); 
    } 
} 

我加了一堆////////////////有问题的线路。在这里他们说这本书有参考书架。

+2

请给出一些具体的例子。在复合模式中,通常不存在任何“父母/孩子”关系;这与类继承有关。在你的案例中,“书籍扩展书架”*和*“书架”是由“书籍”,还是......组成的? – deceze

+0

编辑。编辑。 –

回答

1

他们应该知道他们的接口,以便他们可以改变。

比方说,你有两类:

Bookshelf 
    private books: Book[] 

Book 
    public title: String 

你会然后访问books[i].title和一本书的标题显示。

现在想象一下,负责Book程序员决定标题merrits自己的类,所以我们有:

Book 
    public title: Title 

Title 
    private t: String 
    public toString() 

现在谁是编码Bookshelf程序员需要改变他们的代码。

在另一方面,如果我们将有:

Book 
    private title: String 
    public getTitleString() 

然后我们可以改变Book类的实现,而我们必须做的是编写getTitleString()函数会返回一个字符串表示的标题,并且所有内容都将继续运行,而无需对Bookshelf进行任何其他更改。

1

我的“老板”说他们知道彼此不好。但为什么?

问题是在ShelfBook之间的循环引用,这并非如此微不足道,需要特别小心才能使用。

例如,如果您只是在addBook方法内编写$oneBook->shelf = $this;方法,那么如果消费者在两个不同的货架上将该方法调用为一本书,会发生什么情况?

$book = new Book; 
$shelf1 = new Shelf; 
$shelf2 = new Shelf; 

$shelf1->addBook($book); 
$shelf2->addBook($book); 

Book将被添加到两个货架,但它只能容纳最后货架,从而导致矛盾和潜在的运行时错误引用。

因此,循环引用可以正确完成,但需要特别注意并增加了代码的复杂性。

相关问题