Php 从抽象子级中删除重复代码

Php 从抽象子级中删除重复代码,php,abstract-class,code-duplication,Php,Abstract Class,Code Duplication,我正在为我们正在构建的软件创建模板引擎。我有一个抽象类,Template,有3个扩展类Header,Body,Footer。这3个子项中的每一个子项都包含相同的构造函数代码,这让我很困扰,只要看看代码中的重复,构造函数都有以下内容: public function __construct($file, array $kvp) { $this->templates[] = array( 'context' => $this->get

我正在为我们正在构建的软件创建模板引擎。我有一个抽象类,
Template
,有3个扩展类
Header
Body
Footer
。这3个子项中的每一个子项都包含相同的构造函数代码,这让我很困扰,只要看看代码中的重复,构造函数都有以下内容:

public function __construct($file, array $kvp)
    {
        $this->templates[] = array(
            'context' => $this->getClass($this),
            'file' => $file,
            'kvp' => $kvp
        );
    }
有没有办法将这段代码移到父类中或减少重复? 以下是完整代码:

<?php

Interface iTemplate
{   
    protected function add(Template $template);
    protected function remove(Template $template);
}

abstract class Template implements iTemplate
{
    protected $html = array();
    protected $templates = array();

    public function add($template)
    {
        array_push($this->templates, $template);
    }

    public function remove($template)
    {
        if(in_array($template, $this->templates))  {
            $key = array_search($template, $this->templates);
            $this->templates[$key] = null;
            $this->templates = array_filter($this->templates);
        }
    }

    protected function getClass($context)
    {
        return get_class($context);
    }

    public function render()
    {
        foreach($this->templates as $template)
        {
            $output = file_get_contents($template->file);

            foreach ($this->template->kvp as $key => $value) {
                $tagToReplace = "[@$key]";
                $output = str_replace($tagToReplace, $value, $output);
            }

            $html[] = $output;
        }

        return implode("\n", $html);
    }
}

class Header extends Template
{   
    public function __construct($file, array $kvp)
    {
        $this->templates[] = array(
            'context' => $this->getClass($this),
            'file' => $file,
            'kvp' => $kvp
        );
    }
}

class Body extends Template
{   
    public function __construct($file, array $kvp)
    {
        $this->templates[] = array(
            'context' => $this->getClass($this),
            'file' => $file,
            'kvp' => $kvp
        );
    }
}

class Footer extends Template
{   
    public function __construct($file, array $kvp)
    {
        $this->templates[] = array(
            'context' => $this->getClass($this),
            'file' => $file,
            'kvp' => $kvp
        );
    }
}


/* Example */

$Template = new Template();
$Template->add(new Header($header_file, $header_kvp));
$Template->add(new Body($body_file, $body_kvp));
$Template->add(new Footer($footer_file, $footer_kvp));
echo $Template->render();

简单的解决方案是使用trait:


interface iTemplate
{   
    public function add(Template $template);
    public function remove(Template $template);
}

class Template implements iTemplate
{
    protected $html = array();
    protected $templates = array();

    public function add(Template $template)
    {
        //...
    }

    public function remove(Template $template)
    {
        //...
    }

    protected function getClass()
    {
        return get_class($this);
    }

    public function render()
    {
        //...
    }
}

class Header extends Template
{   use ConstructTrait;
}

class Body extends Template
{   use ConstructTrait;
}

class Footer extends Template
{   use ConstructTrait;
}

trait ConstructTrait
{
  public function __construct($file, $kvp)
  {
    $this->templates[] = array(
      'context' => $this->getClass(),
      'file' => $file,
      'kvp' => $kvp
      );
  }
}

您可以使用以下命令调用父构造函数:parent::construct($file,$kvp);如果子类中未提供构造函数,则会自动调用父构造函数。