用什么替换巨型 switch 语句?
我有一个代码可以解析一些模板文件,当它找到占位符时,它会用一个值替换它。 类似于:
<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.
}
然后用返回值替换原始占位符。
在实际情况中,它不是一个虚拟网页,并且可能会出现许多(50 多个)不同的占位符。
我的代码是C++,但我想任何语言都存在这个问题。 我想更多的是关于算法和面向对象设计。 唯一重要的是,它必须被编译,即使我想要我不能有任何动态/评估代码。
我考虑过实施责任链模式,但似乎并没有多大改善情况。
更新:我也担心 此评论在另一个线程中。 我应该关心它吗?
I have a code that parses some template files and when it finds a placeholder, it replaces it with a value. Something like:
<html>
<head>
<title>%title%</title>
</head>
<body bgcolor="%color%">
...etc.
In code, the parser finds those, calls this function:
string getContent(const string& name)
{
if (name == "title")
return page->getTitle();
else if (name == "color")
return getBodyColor();
...etc.
}
and then replaces the original placeholder with returned value.
In real case, it is not a dummy web page, and there are many (50+) different placeholders that can occur.
My code is C++, but I guess this problem exists with any language. It's more about algorithms and OO design I guess. Only important thing is that this must be compiled, even if I wanted I couldn't have any dynamic/eval'd code.
I though about implementing Chain of Responsibility pattern, but it doesn't seem it would improve the situation much.
UPDATE: and I'm also concerned about this comment in another thread. Should I care about it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用将标签名称映射到标签处理程序的字典。
Use a dictionary that maps tag names to a tag handler.
您希望用多态性替换条件。 粗略地说:
doStuff 超载的地方。
You want replace conditional with polymorphism. Roughly:
where doStuff is overloaded.
您考虑过 XSLT 吗? 它非常适合这种事情。 我开发了一个内容管理系统,它执行完全相同的操作,并且发现 XSLT 非常有效。 解析器为您做了很多工作。
更新:Steven 的评论提出了一个重要的观点 - 如果您决定采用 XSLT 路线,您将希望您的模板是有效的 XHTML。
另外-我会为您的替换令牌使用不同的分隔符。 自然发生的事情不太可能发生。 我用了#!PLACEHOLDER#! 在我的 CMS 中。
Have you considered XSLT? It's very well suited to this kind of thing. I developed a content management system that did the exact same thing and found XSLT to be very effective. The parser does a lot of the work for you.
UPDATE: Steven's comment raises an important point- you'll want your templates to be valid XHTML if you decide to go the XSLT route.
Also- I would use a different delimiter for your replacement tokens. Something less likely to occur naturally. I used #!PLACEHOLDER#! in my CMS.
我将结合 3 个想法:(
switch(){}
。setup()
方法,该方法将其自身(或新的类实例)添加到字典中。解释一下:
setup()
方法将自身注册到超类的字典中,i'll combine 3 ideas:
switch(){}
.setup()
method to each handler class, that adds itself (or a new class instance) to the dictionary.explaining a bit:
static
dict, and methods to register an instance with a selector string.setup()
method registers itself with the superclass' dict尝试将模板读入字符串,然后执行替换,而不是解析。
Rather than parsing, have tried just reading the template into a string and then just performing replaces.
正如“叔叔”鲍勃·马丁在之前与乔尔和杰夫一起的播客中提到的,几乎你想出的任何东西本质上都会复制大的 switch 语句。
如果您觉得实施上面选择的解决方案之一效果更好,那也没有问题。 它可能会使您的代码更漂亮,但在幕后,它本质上是等效的。
重要的是确保大 switch 语句只有一个实例。 您的 switch 语句或字典应确定哪个类处理此标记,然后应使用多态性来处理后续确定。
As "Uncle" Bob Martin mentioned in a previous podacast with Joel and Jeff, pretty much anything you come up with is going to essentially be reproducing the big switch statement.
If you feel better implementing one of the solutions selected above, that's fine. It may make your code prettier, but under the covers, it's essentially equivalent.
The important thing is to ensure that there is only one instance of your big switch statement. Your switch statement or dictionary should determine which class handles this tag, and then subsequent determinations should be handled using polymorphism.