php - 设计模式问题: encapsulation or inheritance

标签 php design-patterns templates

我有一个问题困扰了我很长时间。我正在构建一个包含两个主要类的模板引擎 Template.phpTag.php ,有一堆扩展类,如 Img.phpString.php .

程序的工作原理如下:

Template 对象创建 Tag 对象。每个标签对象决定要实现哪个扩展类(img、string等)。

Tag 类的要点是为每个扩展类提供辅助函数,例如 wrap('div'), addClass('slideshow')

每个Img 或 String 类都用于渲染特定于所需内容的代码,因此 $Img->render()会给出类似 <img src='blah.jpg' /> 的内容

我的问题是:

我应该像这样封装 Tag 对象中的所有扩展功能吗:

Tag.php

function __construct($namespace, $args) {
    // Sort out namespace to determine which extension to call
    $this->extension = new $namespace($this); // Pass in Tag object so it can be used within extension

    return $this; // Tag object
}

function render() {
    return $this->extension->render();
}

Img.php

    function __construct(Tag $T) {
        $args = $T->getArgs();
        $T->addClass('img');
    }

    function render() {
        return '<img src="blah.jpg" />';
    }

用法:

$T = new Tag("img", array(...);
$T->render();

...或者我应该创建更多的继承结构,因为“Img是一个标签”

Tag.php

public static create($namespace, $args) {
    // Sort out namespace to determine which extension to call
    return new $namespace($args);

}

Img.php

class Img extends Tag {
    function __construct($args) {
        // Determine namespace then call create tag
        $T = parent::__construct($namespace, $args);
    }

    function render() {
        return '<img src="blah.jpg" />';
    }
}

用法:

$Img = Tag::create('img', array(...));
$Img->render();

我确实需要一个用于创建自定义标签的通用接口(interface),即我可以实例化 Img(...) 然后实例化 String(...),我确实需要使用 Tag 实例化每个扩展。

编辑:另外只是为了澄清:Tag 类具有所有扩展类共有的功能,Tag 类中不应该有任何需要在扩展类中实现的方法。标签类仅提供辅助函数。

我知道这个问题有点模糊,我希望你们中的一些人过去处理过这个问题,并且能够预见到选择每种设计模式时的某些问题。如果您有任何其他建议,我很乐意听到。

谢谢! 马特·穆勒

最佳答案

继承比将不同标签的所有功能封装在单个 Tag 类中更有意义。关注点分离很重要,因此最好在这里采用基于继承的方法。否则,您最终会在一个类中拥有一堆不同的特定于标签的逻辑,这很糟糕。这是维护的噩梦!

如果您有特定于 Img 的逻辑,请将其放在自己的类中。您可以将所有常用方法放在 Tag 类中。如果这是 Java,我会将 Tag 设为抽象类甚至接口(interface),并具有不同的实现(ImgDiv 等)。 ) 扩展(对于抽象类)或实现(对于接口(interface))。

更好的方法是拥有一个 Tag 接口(interface),然后是一个实现所有通用逻辑的 AbstractTag 抽象类。然后您的特定标签可以实现 Tag 接口(interface)并扩展 AbstractTag。不过,我不知道这在 PHP 中是否完全可能,但你可以尝试做类似的事情。

关于php - 设计模式问题: encapsulation or inheritance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2786041/

相关文章:

c++ - 如何在 C++ 中扩展现有模板?

php 未选择数据库

php - 插入 foreach 循环

javascript - 使用 PHP 显示未列出的自动完成搜索结果

c# - 工厂模式可以这样使用吗?

design-patterns - 序列化模式是什么?

java - builder 设计模式——没有抽象类/接口(interface)

php - 我想在我的脚本中添加分页

c++ - 将模板类更改为常规类 - C++

c++ - 推导的模板 arg 和自动 arg 之间有什么区别吗?