假设有一个Page类,它表示对页面渲染器的一组指令。假设有一个Renderer知道如何在屏幕上呈现页面的类。可以通过两种不同的方式来构造代码:  
/*
 * 1) Page Uses Renderer internally,
 * or receives it explicitly
 */
$page->renderMe(); 
$page->renderMe($renderer); 
/*
 * 2) Page is passed to Renderer
 */
$renderer->renderPage($page);
每种方法的优缺点是什么?什么时候会更好?什么时候会更好?
背景
为了增加一些背景知识-我发现自己在同一代码中同时使用了这两种方法。我正在使用名为的第三方PDF库TCPDF。在我的代码中的某些地方,必须具备以下条件才能使PDF呈现工作:
$pdf = new TCPDF();
$html = "some text";
$pdf->writeHTML($html);
假设我希望创建页面的表示形式。我可以创建一个模板,其中包含用于呈现PDF页面摘要的说明,如下所示:
/*
 * 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)请注意,这里   $snippet 运行本身,如我的第一个代码示例所示。它还需要了解和熟悉$pdf,以及$data它的工作原理。
但是,我可以创建一个PdfRenderer像这样的类:
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);
    }
}
然后我的代码转向这个:
$renderer = new PdfRenderer(new TCPDF());
$renderer->runTemplate(new PageSnippet(), array('html' => 'some text'));
2)在这里,$renderer接收PageSnippet和$data工作所需的任何信息。这类似于我的第二个代码示例。
因此,即使渲染器收到页面片段,在渲染器内部,该片段仍会自行运行。也就是说,两种方法都在起作用。我不确定是否可以将OO使用限制为仅一种或另一种。即使您互相掩盖了对方,也可能两者都需要。