2016-07-08 69 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將被添加到兩個貨架,但它只能容納最後貨架,從而導致矛盾和潛在的運行時錯誤引用。

因此,循環引用可以正確完成,但需要特別注意並增加了代碼的複雜性。