17

いくつかのテンプレート ファイルを解析するコードがあり、プレースホルダーが見つかると、それを値に置き換えます。何かのようなもの:

<html>
<head>
    <title>%title%</title>
</head>
<body bgcolor="%color%">
...etc.

コードでは、パーサーがそれらを見つけて、次の関数を呼び出します。

string getContent(const string& name)
{
    if (name == "title")
        return page->getTitle();
    else if (name == "color")
        return getBodyColor();
    ...etc.
}

元のプレースホルダーを戻り値に置き換えます。

実際には、これはダミーの Web ページではなく、多数 (50 以上) の異なるプレースホルダーが発生する可能性があります。

私のコードは C++ ですが、この問題はどの言語にも存在すると思います。それは、アルゴリズムと OO 設計に関するものだと思います。唯一の重要なことは、動的/評価済みのコードが必要なかったとしても、これをコンパイルする必要があるということです。

Chain of Responsibility パターンの実装について考えましたが、状況があまり改善されないようです。

更新: また、別のスレッドのこのコメントについても心配しています。私はそれを気にする必要がありますか?

4

6 に答える 6

26

タグ名をタグ ハンドラにマップするディクショナリを使用します。

于 2009-03-18T18:41:46.250 に答える
5

conditional を polymorphism に置き換えます。だいたい:

string getContent(const string& name) {
    myType obj = factory.getObjForName(name);
    obj.doStuff();
}

doStuff がオー​​バーロードされている場所。

于 2009-03-18T18:43:55.543 に答える
3

私は3つのアイデアを組み合わせます:

  1. (Steven Hugig より): セレクターごとに異なるクラスを取得するファクトリー メソッドを使用します。
    • (Neil Butterworth より): 工場内では辞書を使って大きなswitch(){}.
    • (私のもの):setup()それ自体(または新しいクラスインスタンス)を辞書に追加するメソッドを各ハンドラークラスに追加します。

少し説明します:

  • 辞書を持つ抽象クラスとstatic、インスタンスをセレクター文字列に登録するメソッドを作成します。
  • 各サブクラスで、setup()メソッドは自分自身をスーパークラスの辞書に登録します
  • ファクトリメソッドは、辞書を読むだけです
于 2009-03-18T19:01:27.043 に答える
3

XSLT について考えたことはありますか? こういうのにとても合います。まったく同じことを行うコンテンツ管理システムを開発したところ、XSLT が非常に効果的であることがわかりました。パーサーが多くの作業を行います。

更新: Steven のコメントは重要な点を指摘しています。XSLT ルートを使用する場合は、テンプレートを有効な XHTML にする必要があります。また、代替トークンには別の区切り文字を使用します。自然に発生する可能性が低いもの。#!PLACEHOLDER#! を使用しました。私のCMSで。

于 2009-03-18T18:44:31.687 に答える
2

解析するのではなく、テンプレートを文字列に読み取ってから置換を実行するだけでした。

fileContents = fileContents.Replace("%title%", page->getTitle());
fileContents = fileContents.Replace("%color%", getBodyColor());
于 2009-03-18T18:44:45.133 に答える