2011-05-09 35 views
4

在我的应用程序子类的构造我有一个数字,呈现不同的元素。我创建了一个抽象类,在其中扩展。用不同数量的参数

abstract class Element { 

    protected $_value = null; 

    public function __construct($value) { 
     $this->_value = $value; 
    } 

    // ... 

    public abstract function render(); 

} 

一个元素的例子可能是一些文字包裹在段落标记中。

class TextElement extends Element { 

    public function render() { 
     return "<p>{$this->_value}</p>\n"; 
    } 

} 

我无法创建具有多个值的元素。例如,图像元素可能会呈现图像标记并包含多个属性。这是一个问题,因为抽象类中的构造函数只接受一个参数。我看到了解决这个问题的两种可能的解我能通过在含有不同的属性的元素构造(溶液1)的阵列或I可以覆盖在子类的构造(溶液2)。我的问题是,这些解决方案中的哪一个是更好的设计,还是它们存在更好的解决方案?我应该使用接口吗?

解决方案1 ​​

class ImageElement extends Element { 

    public function render() { 
     return "<img src=\"{$this->_value['src']}\" alt=\"{$this->_value['alt']}\" />"; 
    } 

} 

$imageElement = new ImageElement(array('src' => '/image.png', 'alt' => 'image')); 

解决方案2

class ImageElement extends Element { 

    protected $_alt; 

    public function __construct($src, $alt) { 
     $this->_value = $src; 
     $this->_alt = $alt; 
    } 

    // ... 

    public function render() { 
     return "<img src=\"{$this->_value}\" alt=\"{$this->_alt}\" />"; 
    } 

} 

回答

1

有了第一个解决方案,如果有人看你的代码,在那里他们将需要检查的渲染功能,找出哪些参数是可用。

随着第二个解决方案,如果你的IDE支持自动完成,或者如果你从源生成的文档,你会被给予的参数列表,你可以用你的一天更快去。

$价值并没有真正告诉我很多关于它是干什么用的,以及如果你碰上,这并不具有任何参数的元素?即BR元素或某物。

我认为解决方案2是更“正确”但只是一个“渲染”功能的接口是最佳的解决方案。

+0

如果我要使用一个接口,我将失去循环通过元素集合的能力。使用接口和抽象类是否可行?我看到的唯一问题是抽象类基本上是空的。 – birderic 2011-05-09 16:43:44

1

这两种解决方案是合理的,但在你的情况下,我会选择你的第一个解决方案。你在这里处理HTML元素,所以这可能意味着你要支持大量的属性,其中许多属性是可选的。这看起来不错:

class ImageElement extends Element { 
    public function __construct($src, alt) {...} 
} 

$img = new ImageElement('/img/src.png', 'alt text'); 

当你需要传递多个参数,其中有许多是可选的,最好是一个对象或数组传递给构造函数这是不是很好

class ImageElement extends Element { 
    public function __construct($src, $alt, $id = null, $class = null, $width = null, $height = null, $style = null, $title = null) {...} 
} 

$img = new ImageElement('/img/src.png', 'alt text', null, 'img-class', null, null, null, 'Image title'); 

。这看起来好多了:

$img = new ImageElement(array(
    'src' => '/img/src.png', 
    'alt' => 'alt text', 
    'class' => 'img-class', 
    'title' => 'Image title', 
)); 
0

重载!不幸的是,PHP不会超载,所以假装:

public function __construct($VAL){ 
    if(is_array($VAL)){ 
     foreach($VAL as $k=>$v){ 
      $this->$k=$v; 
     } 
    }else{ 
     $this->_value=$VAL; 
    } 
} 
相关问题