Suppose there is a Page
class, which represents a set of instructions to a page renderer. And Suppose there is a Renderer
class that knows how to render a page on screen. It is possible to structure code in two different ways:
/*
* 1) Page Uses Renderer internally,
* or receives it explicitly
*/
$page->renderMe();
$page->renderMe($renderer);
/*
* 2) Page is passed to Renderer
*/
$renderer->renderPage($page);
What are the pros and cons of each approach? When will one be better? When will the other be better?
BACKGROUND
To add a little bit more background - I am finding myself using both approaches in the same code. I am using a 3rd party PDF library called TCPDF
. Somewhere in my code I have to have the following for PDF rendering to work:
$pdf = new TCPDF();
$html = "some text";
$pdf->writeHTML($html);
Say I wish to create a representation of the page. I could create a template that holds instructions to render a PDF page snippet like so:
/*
* A representation of the PDF page snippet:
* a template directing how to render a specific PDF page snippet
*/
class PageSnippet
{
function runTemplate(TCPDF $pdf, array $data = null): void
{
$pdf->writeHTML($data['html']);
}
}
/* To be used like so */
$pdf = new TCPDF();
$data['html'] = "some text";
$snippet = new PageSnippet();
$snippet->runTemplate($pdf, $data);
1) Notice here that $snippet
runs itself, as in my first code example. It also needs to know and be familiar with the $pdf
, and with any $data
for it to work.
But, I can create a PdfRenderer
class like so:
class PdfRenderer
{
/**@var TCPDF */
protected $pdf;
function __construct(TCPDF $pdf)
{
$this->pdf = $pdf;
}
function runTemplate(PageSnippet $template, array $data = null): void
{
$template->runTemplate($this->pdf, $data);
}
}
and then my code turns to this:
$renderer = new PdfRenderer(new TCPDF());
$renderer->runTemplate(new PageSnippet(), array('html' => 'some text'));
2) Here the $renderer
receives the PageSnippet
and any $data
required for it to work. This is similar to my second code example.
So, even though the renderer receives the page snippet, inside the renderer, the snippet still runs itself. That is to say that both approaches are in play. I am not sure if you can restrict your OO usage to only one or only the other. Both might be required, even if you mask one by the other.