在同一个循环中执行两个不同的任务是不是很糟糕? [关闭]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在同一个循环中执行两个不同的任务是不是很糟糕? [关闭]相关的知识,希望对你有一定的参考价值。
我正在为我的数据库开发一个高度专业化的搜索引擎。当用户提交搜索请求时,引擎会将搜索项拆分为数组并循环遍历。在循环内部,针对几种可能的场景检查每个搜索项以确定它可能意味着什么。当搜索项与场景匹配时,会向SQL查询添加WHERE条件。某些术语可以有多种含义,在这些情况下,引擎会构建一个建议列表,以帮助用户缩小结果范围。
旁白:如果有人有兴趣知道,通过在前面添加一个关键字来改进模糊的术语。例如,1954年可能是一年或序列号。引擎将向用户建议这两种情况,并将搜索项修改为年份:1954或序列号:1954。
在同一个循环中构建SQL查询和细化建议对我来说感觉不对,但是将它们分开会增加更多的开销,因为我必须循环遍历同一个数组两次并测试所有相同的场景两次。什么是更好的行动方案?
我可能会将这两个动作分解为自己的功能。然后你就拥有了
foreach (term in terms) {
doThing1();
doThing2();
}
这很干净。
如果你在循环中做的事情是相关的,那么很好。编写“每次迭代的东西”并将其包装在一个循环中可能是有意义的,因为那可能是你在脑海中想到它的方式。
添加注释,如果它太长,请查看拆分或使用简单的实用工具方法。
我想有人可能会说这可能与语言无关;它也高度依赖于你想要完成的事情。如果您将多个任务放在一个循环中,使得它们无法通过编译器轻松地并行化并行环境,那么它肯定是代码味道。
不,这还不错。我认为循环两次会更令人困惑。
但是,如果任务彼此分离得足够多,可能会将某些任务放入函数中。
我认为为了理论纯度而添加多个循环是没有意义的,特别是考虑到如果你要针对多个场景添加循环,你将从O(n) - > O(n * #scenarios)。另一种解决方法而不涉及“上帝方法”陷阱的方法是使用一个运行单个循环并返回匹配数组的方法,另一个运行搜索匹配数组中每个元素的方法。
使用相同的循环对我来说似乎是一个有效的优化,尝试保持两个任务的代码独立,以便在必要时可以更改此优化。
您的场景适合构建器模式,如果每个操作都相当复杂,那么它可以很好地解决问题。如果您的所有逻辑都适合50行代码,那么这就是工程上的问题,但如果您有依赖管理和复杂的逻辑,那么您应该使用经过验证的设计模式来实现关注点的分离。它可能看起来像这样:
var relatedTermsBuilder = new RelatedTermsBuilder();
var whereClauseBuilder = new WhereClauseBuilder();
var compositeBuilder = new CompositeBuilder()
.Add(relatedTermsBuilder)
.Add(whereClauseBuilder);
var parser = new SearchTermParser(compositeBuilder);
parser.Execute("the search phrase");
string[] related = relatedTermsBuilder.Result;
string whereClause = whereClauseBuilder.Result;
支持对象看起来像:
public interface ISearchTermBuilder {
void Build(string term);
}
public class SearchTermParser {
private readonly ISearchTermBuilder builder;
public SearchTermParser(ISearchTermBuilder builder) {
this.builder = builder;
}
public void Execute(string phrase) {
foreach (var term in Parse(phrase)) {
builder.Build(term);
}
}
private static IEnumerable<string> Parse(string phrase) {
throw new NotImplementedException();
}
}
我称它为代码味道,但不是很糟糕。我会将循环中的功能分开,首先放置其中一个,然后在空白行之后和/或注释另一个。
我会把它看作是观察者模式的一个实例:每次你循环引发一个事件,并且你想要的许多观察者都可以订阅它。当然,将它作为模式来做是过分的,但相似之处告诉我,执行两个或三个或你想要多少动作就好了。
我不认为在一个循环中进行两个动作是错误的。我甚至建议制作两个从循环内部调用的方法,如:
for (...) {
refineSuggestions(..)
buildQuery();
}
另一方面,O(n)= O(2n)
所以不要太担心 - 这不是一个表演罪。
你当然可以运行两个循环。
如果很多这是业务逻辑,你也可以在第一个循环中创建某种数据结构,然后使用它来生成SQL,类似于
search_objects = []
loop through term in terms
search_object = {}
search_object.string = term
// suggestion & rules code
search_object.suggestion = suggestion
search_object.rule = { 'contains', 'term' }
search_objects.push(search_object)
loop through search_object in search_objects
//generate SQL based on search_object.rule
这至少使您不必在两个循环中执行if / then / else,并且我认为在第一个循环之外移动SQL代码更加清晰。
以上是关于在同一个循环中执行两个不同的任务是不是很糟糕? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章