从抽象子项中删除重复的代码

时间:2014-08-12 16:06:40

标签: php abstract-class code-duplication

我正在为我们正在构建的软件创建模板引擎。我有一个抽象类Template,有3个扩展类HeaderBodyFooter。 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();

1 个答案:

答案 0 :(得分:1)

简单的解决方案是使用特质:


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