2016-07-08 1 views
-2

Codebeispiele: https://sourcemaking.com/design_patterns/composite/php Ich habe etwas ähnliches gemacht, außer dass "OnTheBookShelf" über $ books (SeveralBooks) bekannt ist. Mein "Chef" sagt es ist schlecht, dass sie voneinander wissen. Aber warum?Zusammengesetztes Muster, warum ist es schlecht, wenn "Kinder" von "Eltern" wissen?

Allright, ich kann es bearbeiten:

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(); 
    } 
} 

ich ein paar //////////////// zu den problematischen Zeilen hinzugefügt. Und hier sagen sie, dass das Buch einen Bezug zum Regal hat.

+2

Bitte zeigen Sie ein konkretes Beispiel. In einem zusammengesetzten Muster gibt es normalerweise keine "Eltern/Kind" -Beziehung; Das bezieht sich auf die Klassenvererbung. Erweitert "Book Bookshelf" in Ihrem Fall * und "Bookshelf" besteht aus "Books", oder was ...? – deceze

+0

bearbeitet. Bearbeitet. –

Antwort

1

Sie sollten über ihre Schnittstellen wissen, damit sie geändert werden können.

Angenommen, Sie haben Klassen:

Bookshelf 
    private books: Book[] 

Book 
    public title: String 

Sie würden dann zugreifen books[i].title und Anzeige Titel des ein Buch.

Nun stell dir vor, dass der Programmierer verantwortlich für Book entscheidet, dass der Titel seine eigene Klasse merrits, so haben wir:

Book 
    public title: Title 

Title 
    private t: String 
    public toString() 

Jetzt ist der Programmierer, der Bookshelf wurde Codierung benötigt, ihren Code zu ändern.

Auf der anderen Seite, wenn wir haben:

Book 
    private title: String 
    public getTitleString() 

Dann könnten wir die Umsetzung der Book Klasse ändern, und alles, was wir tun mussten, ist die getTitleString() Funktion zu schreiben, die eine String-Darstellung zurückkehren eines Titels, und alles würde ohne zusätzliche Änderungen an Bookshelf weiter funktionieren.

1

Mein "Chef" sagen, es ist schlecht, dass sie voneinander wissen. Aber warum?

Das Problem ist kreisförmig Referenz zwischen Shelf und Book, die nicht so trivial und erfordert besondere Sorgfalt bei der Arbeit.

Zum Beispiel, wenn Sie einfach schreiben $oneBook->shelf = $this; innerhalb addBook Methode, was passiert, wenn Verbraucher diese Methode für ein Buch auf zwei verschiedenen Regalen ruft?

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

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

Book wird beiden Regale hinzugefügt werden, aber es wird nur auf das letzte Regal halten, was zu Inkonsistenzen und mögliche Laufzeit Fehlern führt.

Natürlich kann die Zirkularreferenz richtig ausgeführt werden, erfordert jedoch besondere Aufmerksamkeit und erhöht die Komplexität des Codes.

Verwandte Themen