在同一个循环中执行两个不同的任务是不是很糟糕? [关闭]

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代码更加清晰。

以上是关于在同一个循环中执行两个不同的任务是不是很糟糕? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在适配器中进行网络调用和处理响应是否很糟糕?

函数指针是否使程序变慢?

JavaScipt 中的事件循环机制,以及微任务 和宏任务的概念

如何继续循环vba

使用“return”从main方法中逃脱是否很糟糕?

根据第三列值在 bigquery 中选择两个不同的列