当前位置:  开发笔记 > 人工智能 > 正文

你怎么在大海捞针中找到针?

如何解决《你怎么在大海捞针中找到针?》经验,为你挑选了8个好方法。

当以面向对象的方式实现大海捞针搜索时,您基本上有三种选择:

1. needle.find(haystack)

2. haystack.find(needle)

3. searcher.find(needle, haystack)

你更喜欢哪个?为什么?

我知道有些人更喜欢第二种选择,因为它避免引入第三种物体.然而,我不禁感到第三种方法在概念上更"正确",至少如果你的目标是塑造"现实世界".

在哪种情况下,您认为引入辅助对象是合理的,例如本例中的搜索器,何时应避免使用?



1> Brad Wilson..:

在这三个中,我更喜欢选项#3.

该单一职责原则使我不希望把搜索我的DTO或模型的能力.他们的责任是成为数据,而不是发现自己,也不需要了解干草堆,也不知道干草堆知道针头.

对于它的价值,我认为大多数OO从业者需要花费很长时间来理解为什么#3是最佳选择.在我真正理解它之前,我做了OO十年.

@wilhelmtell,C++是极少数具有模板专业化的语言之一,使这样的系统真正起作用.对于大多数语言而言,通用的"查找"方法将是一个可怕的想法.



2> Mike Stone..:

通常应该将动作应用于您正在执行的操作...在这种情况下是haystack,所以我认为选项2是最合适的.

你还有第四种选择,我认为比替代3更好:

haystack.find(needle, searcher)

在这种情况下,它允许您提供要作为操作的一部分进行搜索的方式,因此您可以将操作与正在操作的对象保持一致.



3> wilhelmtell..:

还有另一种选择,即C++的STL使用的方法:

find(haystack.begin(), haystack.end(), needle)

我认为这是一个很好的例子,C++喊"在你的脸上!" OOP.这个想法是OOP不是任何类型的银弹; 有时事情最好用行动来描述,有时候就物体而言,有时既不是,也不是两者兼而有之.

Bjarne Stroustrup在TC++ PL中说,当你设计一个系统时,你应该努力在有效和高效的代码约束下反映现实.对我来说,这意味着你永远不应盲目追随任何事情.想想手头的事情(干草堆,针)和我们所处的背景(搜索,这就是表达的内容).

如果重点是搜索,那么使用强调搜索的算法(动作)(即灵活地适应干草堆,海洋,沙漠,链表).如果重点是haystack,请将find方法封装在haystack对象中,依此类推.

也就是说,有时你会有疑问并且很难做出选择.在这种情况下,面向对象.如果您稍后改变主意,我认为从对象中提取操作然后将操作拆分为对象和类更容易.

遵循这些准则,您的代码将更清晰,更美观.



4> Tilendor..:

我会说选项1完全没了.代码应该以一种告诉你它的作用的方式阅读.选项1让我觉得这针会找到我的大海捞针.

如果大海捞针要包含针,选项2看起来不错.ListCollections总是包含ListItems,所以做collection.find(item)是自然而富有表现力的.

我认为在以下情况下引入辅助对象是合适的:

    您无法控制
    IE 中有问题的对象的实现:search.find(ObsecureOSObject,file)

    对象
    IE 之间没有规律或合理的关系:nameMatcher.find(houses,trees.name)



5> Peter Meyer..:

我和布拉德就这个问题.我在越来越复杂的系统上工作的越多,我就越需要真正解耦对象.他是对的.显而易见的是针头不应该对干草堆知之甚少,所以1肯定是出来的.但是,大海捞针应该对针头一无所知.

如果我正在为大海捞针建模,我可能会把它作为一个集合来实现 - 但是作为干草稻草的集合 - 而不是针的集合!但是,我会考虑到在大海捞针中丢失的东西,但我对这些东西一无所知.我认为最好不要让干草堆本身寻找物品(无论如何,干草堆有多聪明).对我来说正确的做法是让干草堆里面有一系列东西,但不是稻草或干草,或者其他东西都是大海捞针的本质.

class Haystack : ISearchableThingsOnAFarm {
   ICollection myHay;
   ICollection stuffLostInMe;

   public ICollection Hay {
      get {
         return myHay;
      }
   }

   public ICollection LostAndFound {
      get {
        return stuffLostInMe;
      }
   }
}

class Needle : IStuffSmallEnoughToBeLostInAHaystack {
}

class Farmer {
  Search(Haystack haystack, 
                 IStuffSmallEnoughToBeLostInAHaystack itemToFind)
}

实际上我会更多地打字和抽象到接口,然后我意识到我有多疯狂.感觉就像我在大学的CS课......:P

你明白了.我认为尽可能松散耦合是一件好事,但也许我有点沮丧!:)



6> jklp..:

如果Needle和Haystack都是DAO,则选项1和2是不可能的.

这样做的原因是DAO应该只负责保存他们正在建模的现实世界对象的属性,并且只有getter和setter方法(或者只是直接属性访问).这使得将DAO序列化为文件,或者创建通用比较/通用副本的方法更容易编写,因为代码不会包含一大堆"if"语句来跳过这些辅助方法.

这只留下选项3,大多数人都同意这是正确的行为.

选项3有一些优点,最大的优点是单元测试.这是因为现在可以很容易地模拟Needle和Haystack对象,而如果使用选项1或2,则必须在执行搜索之前修改Needle或Haystack的内部状态.

其次,当搜索者现在在一个单独的类中时,所有搜索代码都可以保存在一个地方,包括常见的搜索代码.如果将搜索代码放入DAO中,则常用搜索代码将存储在复杂的类层次结构中,或者仍然存储在Searcher Helper类中.



7> Konrad Rudol..:

这完全取决于变化的内容和保持不变的内容.

例如,我正在研究一个(非OOP)框架,其中查找算法根据针的类型和干草堆而不同.除了在面向对象的环境中需要双重调度这一事实之外,它还意味着编写任何一个needle.find(haystack)或写入都没有意义haystack.find(needle).

另一方面,您的应用程序可以愉快地将查找委托给两个类中的任何一个,或者完全坚持使用一个算法,在这种情况下,决策是任意的.在那种情况下,我更喜欢这种haystack.find(needle)方式,因为将这一发现应用于大海捞针似乎更合乎逻辑.



8> Fredrik Kals..:

当以面向对象的方式实现大海捞针搜索时,您基本上有三种选择:

    needle.find(干草堆)

    haystack.find(针)

    searcher.find(针,干草堆)

你更喜欢哪个?为什么?

纠正我,如果我错了,但在所有三个例子你已经拥有你正在寻找的针的引用,所以这不就是有点像找你的眼镜时,他们坐在你的鼻子?:p

除了旁白,我认为这实际上取决于你认为大海捞针在给定领域内的责任.我们只关心它是一个含有针的东西(一个集合,基本上)?然后haystack.find(needlePredicate)很好.否则,farmBoy.find(谓词,haystack)可能更合适.

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有