0

(这个问题没什么严重的)

有一次我读过这样一个“糟糕的应用程序架构”的例子:

有一个“渲染应用程序”(浏览器,据我记得),所以有人告诉我,在 TagA、TagUL、TagDIV 类中使用“render()”方法是非常糟糕的做法,因为你会有很多“渲染代码”到处都是。所以(在这个例子中),他们建议使用 RenderA、RenderUL、RenderDIV 类来实现渲染。并且标签对象将封装这些渲染器。

我不明白为什么这是一个不好的做法。在这种情况下,我们将在 Render-* 对象周围涂抹大量渲染代码。最后,为什么不让 Redner-singleton 有很多被覆盖的方法呢?这听起来,至少,更便宜。

读什么才能更好地理解它?

4

2 回答 2

3

所有这些不同对象的渲染是否相同?如果是这样,那么它应该只实现一次,最有可能在基类中实现。这将是一个比Singleton更好的解决方案,后者的目的完全不同:主要是实现一个应该只存在一次的资源(注意它是一个资源,而不是一个方法)。

如果 render() 的每个实现都不同(很可能是这种情况),那么在单独的对象中实现它们就没有错,这称为多态。不过,可能应该做的是有一个类层次结构,其中 render() 方法在基类中定义(很可能是抽象的)并在派生类中实现。这有效地形式化了接口,这意味着从所述基类继承的任何类都将具有可用的 render() 方法并且必须实现它。

如果您有部分渲染代码是公用的,以及特定于派生类的部分,则不必在所有派生类实现中复制公用部分,您可以使用模板方法模式,即基类方法执行公共部分,并协调调用派生类实现。这是 C++ 中的伪代码示例

class TagBase {
public:
    void render() {
        // do some common stuff here
        doRender();
        // do some more common stuff here
    }

    virtual void doRender() = 0;
    ....
};

class TagA : public TagBase {
public:
    virtual void doRender() {
        // do your specific stuff here
    }
};

这里有几本好书:

于 2012-05-29T10:11:26.450 回答
1

我不明白为什么这是一个不好的做法。

如果标签本身不负责呈现自己,这可能是一种不好的做法 - 请参阅单一职责原则

例如,如果 Tag 类已经包含 HTML 解析行为并且您向其添加渲染,那么它将有 2 个职责、2 个更改的原因,并且可能会中断。由于它们的搭配,解析将与渲染紧密耦合,这带来了许多问题:

  • 您不能独立于另一个职责更改或添加一个变体 - 例如,除了桌面浏览器渲染之外添加移动浏览器渲染将需要编写另一个重复解析行为的类。具有更集中职责的更小类意味着更多的活动部件和增加的模块化。

  • 一个类嵌入的职责越多,当您对其进行更改时,可能会意外出现更多的错误和副作用。在许多情况下,很难判断这两个职责中的哪一个导致了这个错误。

  • 您必须重新构建、重新测试和重新部署一个类中包含的所有职责,即使您只更改其中一个职责。

  • 当其他职责可以干扰时,调试其中一项职责也更加困难。

于 2012-05-29T12:43:56.440 回答