I'm developping an application in PHP in which the ( jQuery-like) style of chaining methods is extremely convienent. I'm not talking about inheritance chains, but about a taxonomy of instances of classes that are 'embedded' inside each other. Now I wonder how I can refer to a higher level instance from a lower level.
This sounds all very abstract, so let me give an example. Let's say I want to write a book (proze) in PHP (just for the sake of arguement). It's very conveniently if I could code this like
$myBestseller = new Book();
$myBestseller
->setAuthor("Jean-Saul Partre")
->addChapter()
->addParagraph("How the Rabit lost its wings.")
->addWords("On a beautiful wintes day, the rabit flew over the … ")
->addWords("Bla bla")
->addWords("Bla bla");
So far, I got it working. (Should I include the actual class definions?) Now what if I would like to refer to a property of an object higher in the hierarchy? Let's say I'd like to include the name of the author in a the title of a chapter:
$myBestseller = new Book();
$myBestseller
->setAuthor("Jean-Saul Partre")
->addChapter()
->addParagrapWithAuthor("How "," fell out of the window.");
->addWords("Bla bla")
->addWords("Bla bla")
->addWords("Bla bla")
var_dump($myBestseller);
Let's just add the Chapter class definition here as well:
class Chapter{
private $_paragraphs = array();
public function addParagraph($title){
return $this->_pages[] = new Paragraph($title);
}
public function addParagrapWithAuthor($prefix, $suffix){
$author = "Ideo Gram";
return $this->_pages[] = new Paragraph($prefix.$author.$suffix);
}
}
So, instead of $author = "Ideo Gram" I'd want to use the definition of the author of the book. The title with this code would be
How Ideo Gram fell out of the window
Instead, I would like it to say
How Jean-Saul Patre fell out of the window
Can this be done? The only solution so far I found is passing a reference to descendents 'under the table', but that feels like contaminating the classes.
Maybe the answer is very straight forward, but I can't find it. I might not know the right terms. ::parent, for example, works on extended classes.
There is no magic. If you need a bidirectionnal relationship between 2 entities, they need to reference each other.
So your method addChapter
could do this :
public function addChapter() {
return $this->chapters[] = new Chapter($this);
}
So your chapter becomes :
class Chapter {
protected $book;
public function __construct(Book $book) {
$this->book = $book;
}
....
public function addParagrapWithAuthor($prefix, $suffix){
$author = $this->book->getAuthor()->getFullName();
return $this->_pages[] = new Paragraph($prefix.$author.$suffix);
}
}