Frage

Bei der objektorientierten Umsetzung einer Nadelsuche im Heuhaufen stehen Ihnen grundsätzlich drei Alternativen zur Verfügung:

1. needle.find(haystack)

2. haystack.find(needle)

3. searcher.find(needle, haystack)

Was bevorzugen Sie und warum?

Ich weiß, dass einige Leute die zweite Alternative bevorzugen, weil sie die Einführung eines dritten Objekts vermeidet.Allerdings bin ich der Meinung, dass der dritte Ansatz konzeptionell „richtiger“ ist, zumindest wenn Ihr Ziel darin besteht, „die reale Welt“ zu modellieren.

In welchen Fällen ist es Ihrer Meinung nach gerechtfertigt, Hilfsobjekte einzuführen, wie in diesem Beispiel den Sucher, und wann sollten sie vermieden werden?

War es hilfreich?

Lösung

Normalerweise sollten Aktionen auf das angewendet werden, worauf Sie die Aktion ausführen ...in diesem Fall der Heuhaufen, daher halte ich Option 2 für die am besten geeignete.

Sie haben auch eine vierte Alternative, die meiner Meinung nach besser wäre als Alternative 3:

haystack.find(needle, searcher)

In diesem Fall können Sie die Art und Weise angeben, in der Sie als Teil der Aktion suchen möchten, und so die Aktion mit dem Objekt, an dem gearbeitet wird, beibehalten.

Andere Tipps

Von den dreien bevorzuge ich Option Nr. 3.

Der Prinzip der Einzelverantwortung Ich möchte meinen DTOs oder Modellen keine Suchfunktionen hinzufügen.Ihre Verantwortung besteht darin, Daten zu sein, nicht darin, sich selbst zu finden, und Nadeln sollten auch nichts über Heuhaufen wissen müssen, und Heuhaufen sollten auch nichts über Nadeln wissen.

Ich denke, die meisten OO-Anwender brauchen lange, um zu verstehen, warum Nr. 3 die beste Wahl ist.Ich habe wahrscheinlich ein Jahrzehnt lang OO gemacht, bevor ich es wirklich verstanden habe.

@wilhelmtell, C++ ist eine der ganz wenigen Sprachen mit Template-Spezialisierung, die dafür sorgen, dass ein solches System tatsächlich funktioniert.Für die meisten Sprachen wäre eine allgemeine Suchmethode eine SCHRECKLICHE Idee.

Es gibt eine weitere Alternative, nämlich den von der STL von C++ verwendeten Ansatz:

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

Ich denke, es ist ein großartiges Beispiel dafür, dass C ++ "in deinem Gesicht!" OOP.Die Idee dahinter ist, dass OOP kein Allheilmittel ist;Manchmal lassen sich Dinge am besten anhand von Handlungen beschreiben, manchmal anhand von Objekten, manchmal keines von beiden und manchmal beides.

Bjarne Stroustrup sagte in TC++PL, dass man beim Entwurf eines Systems danach streben sollte, die Realität unter den Einschränkungen eines effektiven und effizienten Codes widerzuspiegeln.Für mich bedeutet das, dass man niemals etwas blind befolgen sollte.Denken Sie an die Dinge, die Sie zur Hand haben (Heuhaufen, Nadel) und an den Kontext, in dem wir uns befinden (suchen, darum geht es in dem Ausdruck).

Wenn der Schwerpunkt auf dem Suchen liegt, dann wird ein Algorithmus (eine Aktion) verwendet, bei dem das Suchen im Vordergrund steht (d. h.ist flexibel für Heuhaufen, Ozeane, Wüsten, verknüpfte Listen geeignet).Wenn der Schwerpunkt auf dem Heuhaufen liegt, kapseln Sie die Find-Methode in das Heuhaufen-Objekt usw.

Allerdings zweifeln Sie manchmal und es fällt Ihnen schwer, eine Wahl zu treffen.Seien Sie in diesem Fall objektorientiert.Wenn Sie Ihre Meinung später ändern, ist es meiner Meinung nach einfacher, eine Aktion aus einem Objekt zu extrahieren, als eine Aktion in Objekte und Klassen aufzuteilen.

Befolgen Sie diese Richtlinien und Ihr Code wird klarer und, nun ja, schöner.

Ich würde sagen, dass Option 1 völlig ausgeschlossen ist.Der Code sollte so gelesen werden, dass er Ihnen sagt, was er tut.Option 1 lässt mich denken, dass diese Nadel einen Heuhaufen für mich finden wird.

Option 2 sieht gut aus, wenn ein Heuhaufen Nadeln enthalten soll.ListCollections enthalten immer ListItems, daher ist die Ausführung von „collection.find(item)“ natürlich und ausdrucksstark.

Ich halte die Einführung eines Hilfsobjekts für angemessen, wenn:

  1. Sie haben keine Kontrolle über die Implementierung der betreffenden Objekte
    IE:search.find(ObsecureOSObject, Datei)
  2. Es besteht keine regelmäßige oder sinnvolle Beziehung zwischen den Objekten
    IE:nameMatcher.find(häuser,bäume.name)

Da stimme ich mit Brad überein.Je mehr ich an immens komplexen Systemen arbeite, desto mehr sehe ich die Notwendigkeit, Objekte wirklich zu entkoppeln.Er hat recht.Es ist offensichtlich, dass eine Nadel nichts über Heuhaufen wissen sollte, also ist 1 definitiv draußen.Aber ein Heuhaufen sollte nichts über eine Nadel wissen.

Wenn ich einen Heuhaufen modellieren würde, könnte ich ihn als Sammlung implementieren – aber als Sammlung von Heu oder Stroh – keine Nadelsammlung!Allerdings würde ich damit rechnen, dass Dinge im Heuhaufen verloren gehen, aber ich weiß nicht genau, was das für Dinge sind.Ich denke, es ist besser, den Heuhaufen nicht selbst nach Gegenständen suchen zu lassen (wie schlau ist sowieso ein Heuhaufen).Für mich ist der richtige Ansatz, dass der Heuhaufen eine Ansammlung von Dingen darstellt, die sich darin befinden, aber kein Stroh oder Heu oder was auch immer einem Heuhaufen seine Essenz verleiht.

class Haystack : ISearchableThingsOnAFarm {
   ICollection<Hay> myHay;
   ICollection<IStuffSmallEnoughToBeLostInAHaystack> stuffLostInMe;

   public ICollection<Hay> Hay {
      get {
         return myHay;
      }
   }

   public ICollection<IStuffSmallEnoughToBeLostInAHayStack> LostAndFound {
      get {
        return stuffLostInMe;
      }
   }
}

class Needle : IStuffSmallEnoughToBeLostInAHaystack {
}

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

Eigentlich wollte ich noch mehr tippen und in Schnittstellen abstrahieren, und dann wurde mir klar, wie verrückt ich wurde.Ich fühlte mich, als wäre ich in einem CS-Kurs an der Uni...:P

Du hast die Idee.Ich denke, dass es eine gute Sache ist, so locker wie möglich zu koppeln, aber vielleicht habe ich mich etwas übertreiben lassen!:) :)

Wenn sowohl Needle als auch Haystack DAOs sind, kommen die Optionen 1 und 2 nicht in Frage.

Der Grund dafür ist, dass DAOs nur für die Speicherung der Eigenschaften der realen Objekte, die sie modellieren, verantwortlich sein sollten und nur über Getter- und Setter-Methoden (oder nur direkten Zugriff auf Eigenschaften) verfügen sollten.Dies erleichtert das Schreiben der DAOs in eine Datei oder das Erstellen von Methoden für einen generischen Vergleich/eine generische Kopie, da der Code nicht eine ganze Reihe von „if“-Anweisungen zum Überspringen dieser Hilfsmethoden enthalten würde.

Damit bleibt nur Option 3 übrig, die die meisten als korrektes Verhalten ansehen würden.

Option 3 hat einige Vorteile, wobei der größte Vorteil das Unit-Testen ist.Dies liegt daran, dass sowohl Needle- als auch Haystack-Objekte jetzt problemlos simuliert werden können, während bei Verwendung von Option 1 oder 2 der interne Zustand von Needle oder Haystack geändert werden müsste, bevor eine Suche durchgeführt werden könnte.

Zweitens kann der gesamte Suchcode, einschließlich des allgemeinen Suchcodes, an einem Ort gespeichert werden, da sich der Sucher jetzt in einer separaten Klasse befindet.Wenn der Suchcode hingegen in das DAO eingefügt würde, würde der allgemeine Suchcode entweder in einer komplizierten Klassenhierarchie oder ohnehin mit einer Searcher Helper-Klasse gespeichert.

Das hängt ganz davon ab, was variiert und was gleich bleibt.

Ich arbeite zum Beispiel an einem (nicht-OOP) Rahmen wobei der Suchalgorithmus je nach Nadeltyp und Heuhaufen unterschiedlich ist.Abgesehen von der Tatsache, dass dies in einer objektorientierten Umgebung einen doppelten Dispatch erfordern würde, bedeutet dies auch, dass es auch keinen Sinn macht, zu schreiben needle.find(haystack) oder zu schreiben haystack.find(needle).

Andererseits könnte Ihre Anwendung die Suche gerne an eine der beiden Klassen delegieren oder ganz bei einem Algorithmus bleiben; in diesem Fall wäre die Entscheidung willkürlich.In diesem Fall würde ich das bevorzugen haystack.find(needle) weil es logischer erscheint, die Erkenntnis auf den Heuhaufen anzuwenden.

Bei der Implementierung einer Nadelsuchung eines Heuheuers auf objektorientierte Weise haben Sie im Wesentlichen drei Alternativen:

  1. Needle.find(Heuhaufen)

  2. haystack.find(Nadel)

  3. searcher.find(Nadel, Heuhaufen)

Was bevorzugen Sie und warum?

Korrigieren Sie mich, wenn ich falsch liege, aber in allen drei Beispielen schon haben ein Hinweis auf die Nadel, nach der Sie suchen. Ist das also nicht so, als würden Sie nach Ihrer Brille suchen, wenn sie auf Ihrer Nase sitzt?:P

Abgesehen vom Wortspiel denke ich, dass es wirklich davon abhängt, welche Verantwortung für den Heuhaufen Ihrer Meinung nach innerhalb des gegebenen Bereichs liegt.Ist es uns nur im Sinne einer Sache wichtig, die Nadeln enthält (im Wesentlichen eine Sammlung)?Dann ist haystack.find(needlePredicate) in Ordnung.Andernfalls ist farmBoy.find(predicate, haystack) möglicherweise besser geeignet.

Um die großen Autoren von zu zitieren SICP,

Programme müssen geschrieben werden, damit sie von Menschen gelesen werden können, und nur nebenbei, damit sie von Maschinen ausgeführt werden können

Ich bevorzuge es, beide Methoden 1 und 2 zur Hand zu haben.Am Beispiel von Ruby ist es dabei .include? was so verwendet wird

haystack.include? needle
=> returns true if the haystack includes the needle

Manchmal möchte ich es jedoch nur aus Gründen der Lesbarkeit umdrehen.Ruby wird nicht mit einem geliefert in? Methode, aber es ist ein Einzeiler, deshalb mache ich oft Folgendes:

needle.in? haystack
=> exactly the same as above

Wenn es „wichtiger“ ist, den Heuhaufen oder den Suchvorgang hervorzuheben, schreibe ich lieber include?.Oft geht es einem jedoch weder um den Heuhaufen noch um die Suche, sondern nur darum, dass das Objekt vorhanden ist – in diesem Fall finde ich in? vermittelt die Bedeutung des Programms besser.

Es hängt von Ihren Anforderungen ab.

Wenn Ihnen beispielsweise die Eigenschaften des Suchenden egal sind (z. B.Suchstärke, Sicht usw.), dann würde ich sagen, dass haystack.find(needle) die sauberste Lösung wäre.

Wenn Sie sich jedoch für die Eigenschaften des Suchers (oder für andere Eigenschaften) interessieren, würde ich eine ISearcher-Schnittstelle entweder in den Haystack-Konstruktor oder in die Funktion einfügen, um dies zu erleichtern.Dies unterstützt sowohl objektorientiertes Design (ein Heuhaufen hat Nadeln) als auch die Umkehrung der Kontrolle/Abhängigkeitsinjektion (erleichtert das Unit-Testen der Funktion „Suchen“).

Ich kann mir Situationen vorstellen, in denen eine der ersten beiden Varianten sinnvoll ist:

  1. Wenn die Nadel eine Vorverarbeitung benötigt, wie im Knuth-Morris-Pratt-Algorithmus, needle.findIn(haystack) (oder pattern.findIn(text)) ist sinnvoll, da das Nadelobjekt die Zwischentabellen enthält, die erstellt wurden, damit der Algorithmus effektiv arbeiten kann

  2. Wenn der Heuhaufen vorverarbeitet werden muss, wie etwa bei einem Trie, wird der haystack.find(needle) (oder words.hasAWordWithPrefix(prefix)) funktioniert besser.

In beiden oben genannten Fällen ist sich entweder Nadel oder Heuhaufen der Suche bewusst.Außerdem sind beide sich des anderen bewusst.Wenn Sie wollen, dass Nadel und Heuhaufen nichts voneinander oder von der Suche bemerken, searcher.find(needle, haystack) wäre angebracht.

Einfach:Verbrennt den Heuhaufen!Danach bleibt nur noch die Nadel übrig.Sie könnten es auch mit Magneten versuchen.

Eine schwierigere Frage:Wie findet man eine bestimmte Nadel in einem Nadelpool?

Antwort:Fädeln Sie jeden Faden ein und befestigen Sie das andere Ende jedes Fadenstrangs an einem sortierten Index (d. h.Zeiger)

Die Antwort auf diese Frage sollte eigentlich von der Domäne abhängen, für die die Lösung implementiert wird.
Wenn Sie zufällig eine physische Suche in einem physischen Heuhaufen simulieren, verfügen Sie möglicherweise über die entsprechenden Kurse

  • Raum
  • Stroh
  • Nadel
  • Sucher

Raum
weiß, welche Objekte sich an welchen Koordinaten befinden
setzt die Naturgesetze um (wandelt Energie um, erkennt Kollisionen usw.)

Nadel, Stroh
befinden sich im Weltraum
auf Kräfte reagieren

Sucher
interagiert mit dem Raum:
    bewegt die Hand, legt ein Magnetfeld an, verbrennt Heu, wendet Röntgenstrahlen an, sucht nach einer Nadel...

Daherseeker.find(needle, space) oder seeker.find(needle, space, strategy)

Der Heuhaufen befindet sich zufällig an der Stelle, an der Sie nach der Nadel suchen.Wenn Sie den Raum als eine Art virtuelle Maschine abstrahieren (denken Sie an:die Matrix) könnten Sie das oben Gesagte mit Heuhaufen anstelle von Leerzeichen erhalten (Lösung 3/3b):

seeker.find(needle, haystack) oder seeker.find(needle, haystack, strategy)

Aber die Matrix war die Domäne, die nur dann durch Heuhaufen ersetzt werden sollte, wenn Ihre Nadel nirgendwo anders sein konnte.

Und andererseits war es nur eine Anologie.Interessanterweise öffnet dies den Geist für völlig neue Richtungen:
1.Warum hast du überhaupt die Nadel verloren?Können Sie den Prozess ändern, damit Sie ihn nicht verlieren?
2.Müssen Sie die verlorene Nadel wiederfinden oder können Sie einfach eine neue besorgen und die erste vergessen?(Dann wäre es schön, wenn sich die Nadel nach einer Weile auflösen würde)
3.Wenn Sie Ihre Nadeln regelmäßig verlieren und Sie sie wiederfinden müssen, möchten Sie dies vielleicht tun

  • Nadeln herstellen, die sich selbst finden können, z.B.Sie fragen sich regelmäßig:Bin ich verloren?Wenn die Antwort „Ja“ lautet, senden sie ihre GPS-berechnete Position an jemanden oder fangen an zu piepen oder was auch immer:
    needle.find(space) oder needle.find(haystack)    (Lösung 1)

  • Installieren Sie einen Heuhaufen mit einer Kamera auf jedem Strohhalm. Anschließend können Sie den Verstand des Heuhaufen-Bienenstocks fragen, ob er in letzter Zeit die Nadel gesehen hat:
    haystack.find(Nadel) (Lösung 2)

  • Bringen Sie RFID-Tags an Ihren Nadeln an, damit Sie sie leicht triangulieren können

Das alles nur, um das in Ihrer Implementierung zu sagen Du Ich habe die Nadel und den Heuhaufen und meistens auch die Matrix auf irgendeiner Ebene gemacht.

Entscheiden Sie sich also entsprechend Ihrer Domain:

  • Ist es der Zweck des Heuhaufens, Nadeln zu enthalten?Dann gehen Sie zu Lösung 2.
  • Ist es normal, dass die Nadel irgendwo verloren geht?Dann entscheiden Sie sich für Lösung 1.
  • Geht die Nadel versehentlich im Heuhaufen verloren?Dann gehen Sie zu Lösung 3.(oder erwägen Sie eine andere Wiederherstellungsstrategie)

haystack.find(needle), aber es sollte ein Suchfeld vorhanden sein.

Ich weiß, dass Abhängigkeitsinjektion in aller Munde ist, daher überrascht es mich nicht, dass @Mike Stones haystack.find(needle, searcher) akzeptiert wurde.Aber ich bin anderer Meinung:Die Wahl des verwendeten Suchers scheint mir eine Entscheidung für den Heuhaufen zu sein.

Betrachten Sie zwei ISearcher:MagneticSearcher iteriert über das Volumen und bewegt und schrittweise den Magneten in einer Weise, die mit der Stärke des Magneten übereinstimmt.QuickSortSearcher teilt den Stapel in zwei Teile, bis die Nadel in einem der Unterstapel sichtbar ist.Die richtige Wahl des Suchers kann davon abhängen, wie groß der Heuhaufen ist (z. B. im Verhältnis zum Magnetfeld), wie die Nadel in den Heuhaufen gelangt ist (d. h. ist die Position der Nadel wirklich zufällig oder voreingenommen?) usw.

Wenn Sie Haystack.find (Nadel, Sucher) haben, sagen Sie: "Die Auswahl ist die beste Suchstrategie, die am besten außerhalb des Heuhaufens durchgeführt wird." Ich denke nicht, dass das wahrscheinlich richtig ist.Ich denke, es ist wahrscheinlicher, dass "Heuhäuser wissen, wie man sich am besten sucht". Fügen Sie einen Setter hinzu, und Sie können den Sucher immer noch manuell injizieren, wenn Sie überschreiben oder zum Testen sind.

Persönlich gefällt mir die zweite Methode.Meine Begründung ist, dass die wichtigsten APIs, mit denen ich gearbeitet habe, diesen Ansatz verwenden, und ich finde, dass er am sinnvollsten ist.

Wenn Sie eine Liste von Dingen (Heuhaufen) haben, würden Sie nach (find()) der Nadel suchen.

@Peter Meyer

Du hast die Idee.Ich denke, dass es eine gute Sache ist, so locker wie möglich zu koppeln, aber vielleicht habe ich mich etwas übertreiben lassen!:) :)

Ähm...Ja...Ich denke der IStuffSmallEnoughToBeLostInAHaystack Irgendwie ist das ein Warnsignal :-)

Sie haben auch eine vierte Alternative, die meiner Meinung nach besser wäre als Alternative 3:

haystack.find(needle, searcher)

Ich verstehe Ihren Standpunkt, aber was wäre, wenn searcher implementiert eine Suchschnittstelle, die es ermöglicht, andere Arten von Objekten als Heuhaufen zu durchsuchen und andere Dinge als Nadeln darin zu finden?

Die Schnittstelle könnte auch mit anderen Algorithmen implementiert werden, zum Beispiel:

binary_searcher.find(needle, haystack)
vision_searcher.find(pitchfork, haystack)
brute_force_searcher.find(money, wallet)

Aber wie andere bereits betont haben, denke ich auch, dass dies nur dann hilfreich ist, wenn Sie tatsächlich über mehrere Suchalgorithmen oder mehrere durchsuchbare oder auffindbare Klassen verfügen.Wenn nicht, stimme ich zu haystack.find(needle) ist aufgrund seiner Einfachheit besser, daher bin ich bereit, dafür etwas „Korrektheit“ zu opfern.

class Haystack {//whatever
 };
class Needle {//whatever
 }:
class Searcher {
   virtual void find() = 0;
};

class HaystackSearcher::public Searcher {
public:
   HaystackSearcher(Haystack, object)
   virtual void find();
};

Haystack H;
Needle N;
HaystackSearcher HS(H, N);
HS.find();

Eigentlich eine Mischung aus 2 und 3.

Manche Heuhaufen verfügen nicht über eine spezielle Suchstrategie;Ein Beispiel hierfür ist ein Array.Die einzige Möglichkeit, etwas zu finden, besteht darin, am Anfang zu beginnen und jeden Artikel zu testen, bis Sie den gewünschten Artikel gefunden haben.

Für so etwas ist wahrscheinlich eine freie Funktion am besten geeignet (wie C++).

Manchen Heuhaufen kann eine spezielle Suchstrategie auferlegt werden.Ein Array kann sortiert werden, sodass Sie beispielsweise eine binäre Suche verwenden können.Eine freie Funktion (oder ein Paar freier Funktionen, z. B.sort und binäre_Suche) ist wahrscheinlich die beste Option.

Einige Heuhaufen verfügen im Rahmen ihrer Implementierung über eine integrierte Suchstrategie;Assoziative Container (gehashte oder geordnete Mengen und Karten) funktionieren beispielsweise alle.In diesem Fall ist das Finden wahrscheinlich eine wesentliche Suchmethode, daher sollte es wahrscheinlich eine Methode sein, d. h.haystack.find(Nadel).

Haystack kann Dinge enthalten. Eine Art von Dingen ist Nadelfinder ist etwas, das für die Suche nach Sachen Finder verantwortlich ist.

Für eine flexible Lösung würden Sie also vorzugsweise Folgendes tun:IStuff-Schnittstelle

Haystack = ilistu003CIStuff> Nadel:IStuff

Finder .Find (Istuff StuffTolookfor, Ilistu003CIStuff> StuffStolookin)

In diesem Fall ist Ihre Lösung nicht nur an Nadel und Heuhaufen gebunden, sondern kann für jeden Typ verwendet werden, der die Schnittstelle implementiert

Wenn Sie also einen Fisch im Ozean finden möchten, können Sie das tun.

var results = Finder.Find(fisch, ozean)

Wenn Sie einen Verweis auf das Nadelobjekt haben, warum suchen Sie danach?:) Die Problemdomäne und Anwendungskräfte sagen Ihnen, dass Sie in einem Heuhaufen keine genaue Position der Nadel benötigen (wie das, was Sie von der Liste erhalten könnten. Indexof (Element)), benötigen Sie nur eine Nadel.Und Sie haben es noch nicht.Meine Antwort ist also ungefähr so

Needle needle = (Needle)haystack.searchByName("needle");

oder

Needle needle = (Needle)haystack.searchWithFilter(new Filter(){
    public boolean isWhatYouNeed(Object obj)
    {
        return obj instanceof Needle;
    }
});

oder

Needle needle = (Needle)haystack.searchByPattern(Size.SMALL, 
                                                 Sharpness.SHARP, 
                                                 Material.METAL);

Ich stimme zu, dass es mehr mögliche Lösungen gibt, die auf unterschiedlichen Suchstrategien basieren, also führen sie den Sucher ein.Es gab viele Kommentare dazu, daher möchte ich hier nicht weiter darauf eingehen.Mein Punkt ist, dass die oben genannten Lösungen Anwendungsfälle vergessen – welchen Sinn hat es, nach etwas zu suchen, wenn Sie bereits einen Verweis darauf haben?Im natürlichsten Anwendungsfall haben Sie noch keine Nadel und verwenden daher keine variable Nadel.

Brad Wilson weist darauf hin, dass Objekte eine einzige Verantwortung haben sollten.Im Extremfall hat ein Objekt eine Verantwortung und keinen Zustand.Dann kann es werden...eine Funktion.

needle = findNeedleIn(haystack);

Oder Sie könnten es so schreiben:

SynchronizedHaystackSearcherProxyFactory proxyFactory =
    SynchronizedHaystackSearcherProxyFactory.getInstance();
StrategyBasedHaystackSearcher searcher =
    new BasicStrategyBasedHaystackSearcher(
        NeedleSeekingStrategies.getMethodicalInstance());
SynchronizedHaystackSearcherProxy proxy =
    proxyFactory.createSynchronizedHaystackSearcherProxy(searcher);
SearchableHaystackAdapter searchableHaystack =
    new SearchableHaystackAdapter(haystack);
FindableSearchResultObject foundObject = null;
while (!HaystackSearcherUtil.isNeedleObject(foundObject)) {
    try {
        foundObject = proxy.find(searchableHaystack);
    } catch (GruesomeInjuryException exc) {
        returnPitchforkToShed();  // sigh, i hate it when this happens
        HaystackSearcherUtil.cleanUp(hay); // XXX fixme not really thread-safe,
                                           // but we can't just leave this mess
        HaystackSearcherUtil.cleanup(exc.getGruesomeMess()); // bug 510000884
        throw exc; // caller will catch this and get us to a hospital,
                   // if it's not already too late
    }
}
return (Needle) BarnyardObjectProtocolUtil.createSynchronizedFindableSearchResultObjectProxyAdapterUnwrapperForToolInterfaceName(SimpleToolInterfaces.NEEDLE_INTERFACE_NAME).adapt(foundObject.getAdaptable());

Der Heuhaufen sollte nichts von der Nadel wissen, und die Nadel sollte nichts von dem Heuhaufen wissen.Der Suchende muss über beides Bescheid wissen, aber ob der Heuhaufen wissen sollte, wie er sich selbst durchsucht, ist der eigentliche Streitpunkt.

Ich würde also eine Mischung aus 2 und 3 wählen;Der Heuhaufen sollte jemand anderem sagen können, wie er zu durchsuchen ist, und der Suchende sollte in der Lage sein, diese Informationen zum Durchsuchen des Heuhaufens zu verwenden.

haystack.magnet().filter(needle);

Versucht der Code, eine bestimmte Nadel oder nur eine beliebige Nadel zu finden?Es klingt wie eine dumme Frage, aber es verändert das Problem.

Wenn Sie nach einer bestimmten Nadel suchen, ist der Code in der Frage sinnvoll.Auf der Suche nach einer Nadel, die eher so wäre

needle = haystack.findNeedle()

oder

needle = searcher.findNeedle(haystack)

In jedem Fall bevorzuge ich einen Sucher dieser Klasse.Ein Heuhaufen weiß nicht, wie man sucht.Aus CS-Sicht ist es nur ein Datenspeicher mit VIEL Mist, den Sie nicht wollen.

Auf jeden Fall der Dritte, meiner Meinung nach.

Die Frage nach der Nadel im Heuhaufen ist ein Beispiel für den Versuch, ein Objekt in einer großen Sammlung anderer zu finden, was darauf hindeutet, dass ein komplexer Suchalgorithmus erforderlich ist (möglicherweise mit Magneten oder (wahrscheinlicher) untergeordneten Prozessen) und dies nicht der Fall ist. Es macht wenig Sinn, von einem Heuhaufen die Thread-Verwaltung oder die Implementierung komplexer Suchvorgänge zu erwarten.

Ein Suchobjekt ist jedoch ausschließlich der Suche gewidmet und kann von ihm erwarten, dass er weiß, wie man untergeordnete Threads für eine schnelle binäre Suche verwaltet oder Eigenschaften des gesuchten Elements verwendet, um den Bereich einzugrenzen (z. B.:ein Magnet zum Auffinden eisenhaltiger Gegenstände).

Eine andere Möglichkeit besteht darin, zwei Schnittstellen für durchsuchbare Objekte zu erstellen, z. B.Heuhaufen und ToBeSearched-Objekt, z.B.Nadel.Es kann also auf diese Weise durchgeführt werden

public Interface IToBeSearched
{}

public Interface ISearchable
{

    public void Find(IToBeSearched a);

}

Class Needle Implements IToBeSearched
{}

Class Haystack Implements ISearchable
{

    public void Find(IToBeSearched needle)

   {

   //Here goes the original coding of find function

   }

}
haystack.iterator.findFirst(/* pass here a predicate returning
                               true if its argument is a needle that we want */)

iterator kann eine Schnittstelle zu jeder unveränderlichen Sammlung sein, wobei Sammlungen Gemeinsamkeiten haben findFirst(fun: T => Boolean) Methode, die den Job erledigt.Solange der Heuhaufen unveränderlich ist, besteht keine Notwendigkeit, nützliche Daten vor „außen“ zu verbergen.Und natürlich ist es nicht gut, die Implementierung einer benutzerdefinierten, nicht trivialen Sammlung und einige andere Dinge, die dazu gehören, miteinander zu verknüpfen haystack.Teile und herrsche, okay?

In den meisten Fällen bevorzuge ich es, einfache Hilfsoperationen wie diese am Kernobjekt durchführen zu können, aber je nach Sprache verfügt das betreffende Objekt möglicherweise nicht über eine ausreichende oder sinnvolle Methode.

Auch in Sprachen wie JavaScript), mit denen Sie integrierte Objekte erweitern/erweitern können, kann meiner Meinung nach sowohl praktisch als auch problematisch sein (z. B.wenn eine zukünftige Version der Sprache eine effizientere Methode einführt, die durch eine benutzerdefinierte überschrieben wird).

Dieser Artikel leistet gute Arbeit bei der Darstellung solcher Szenarien.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top