una sinonimos significado que pajar kingdom jugueteria ingles frases encontrar dificil come aguja oop class-design program-structure

oop - sinonimos - ¿Cómo encuentras una aguja en un pajar?



una aguja en un pajar jugueteria (29)

Al implementar una búsqueda con aguja de un pajar de una manera orientada a objetos, esencialmente tiene tres alternativas:

1. needle.find(haystack) 2. haystack.find(needle) 3. searcher.find(needle, haystack)

¿Cuál prefieres y por qué?

Sé que algunas personas prefieren la segunda alternativa porque evita introducir un tercer objeto. Sin embargo, no puedo evitar sentir que el tercer enfoque es conceptualmente "correcto", al menos si su objetivo es modelar "el mundo real".

¿En qué casos cree que está justificado introducir objetos auxiliares, como el buscador en este ejemplo, y cuándo deberían evitarse?


@ Peter Meyer

Entiendes la idea. Creo que ir tan flojamente como sea posible es algo bueno, ¡pero tal vez me estaba dejando llevar un poco! :)

Errr ... sí ... creo que el tipo de IStuffSmallEnoughToBeLostInAHaystack es una bandera roja :-)


Al implementar una búsqueda con aguja de un pajar de una manera orientada a objetos, esencialmente tiene tres alternativas:

  1. needle.find (pajar)

  2. haystack.find (aguja)

  3. searcher.find (aguja, pajar)

¿Cuál prefieres y por qué?

Corrígeme si me equivoco, pero en los tres ejemplos ya tienes una referencia a la aguja que estás buscando, ¿no es como buscar tus lentes cuando están sentados en tu nariz? :pag

Dejando a un lado, creo que realmente depende de lo que consideres que la responsabilidad del pajar está dentro del dominio dado. ¿Nos importa solo en el sentido de ser una cosa que contiene agujas (una colección, esencialmente)? Entonces haystack.find (needlePredicate) está bien. De lo contrario, farmBoy.find (predicate, haystack) podría ser más apropiado.


También tiene una cuarta alternativa que creo que sería mejor que la alternativa 3:

haystack.find(needle, searcher)

Veo tu punto, pero ¿qué searcher si el searcher implementa una interfaz de búsqueda que permite buscar otros tipos de objetos además de los Pajares, y encontrar otras cosas que no sean agujas en ellos?

La interfaz también podría implementarse con diferentes algoritmos, por ejemplo:

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

Pero, como otros ya han señalado, también creo que esto solo es útil si tiene múltiples algoritmos de búsqueda o múltiples clases buscables o que se pueden buscar. Si no, estoy de acuerdo en que haystack.find(needle) es mejor debido a su simplicidad, por lo que estoy dispuesto a sacrificar algo de "corrección" por ello.


¿El código está tratando de encontrar una aguja específica o simplemente una aguja? Suena como una pregunta estúpida, pero cambia el problema.

Buscando una aguja específica, el código en la pregunta tiene sentido. Buscando cualquier aguja sería más como

needle = haystack.findNeedle()

o

needle = searcher.findNeedle(haystack)

De cualquier manera, prefiero tener un buscador de esa clase. Un pajar no sabe cómo buscar. Desde la perspectiva de CS, es solo una tienda de datos con MUCHAS basura que no desea.


Brad Wilson señala que los objetos deben tener una responsabilidad única. En el caso extremo, un objeto tiene una responsabilidad y ningún estado. Entonces puede convertirse ... en una función.

needle = findNeedleIn(haystack);

O podrías escribirlo así:

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());


De los tres, prefiero la opción n. ° 3.

El Principio de Responsabilidad Individual me hace no querer poner capacidades de búsqueda en mis DTO o modelos. Su responsabilidad es ser datos, no encontrarse a sí mismos, ni las agujas deben saber sobre pajares, ni los pajares saben sobre agujas.

Por lo que vale, creo que la mayoría de los practicantes de OO TIENEN MUCHO tiempo para entender por qué # 3 es la mejor opción. Hice OO durante una década, probablemente, antes de que realmente lo asimilara.

@wilhelmtell, C ++ es uno de los pocos idiomas con especialización de plantilla que hace que dicho sistema realmente funcione. Para la mayoría de los idiomas, un método de "búsqueda" de propósito general sería una idea HORRIBLE.


Definitivamente el tercero, en mi humilde opinión.

La cuestión de una aguja en un pajar es un ejemplo de un intento de encontrar un objeto en una gran colección de otros, lo que indica que necesitará un algoritmo de búsqueda complejo (posiblemente con imanes o (más probable) procesos secundarios) y no lo hace Tiene mucho sentido que se espere que un pajar realice la gestión de hilos o implemente búsquedas complejas.

Sin embargo, un objeto de búsqueda está dedicado a la búsqueda y se puede esperar que sepa cómo administrar subprocesos secundarios para una búsqueda binaria rápida, o use las propiedades del elemento buscado para delimitar el área (es decir, un imán para encontrar elementos ferrosos) .


Depende de tus requisitos.

Por ejemplo, si no te importan las propiedades del buscador (por ejemplo, la fuerza del buscador, la visión, etc.), entonces diría que haystack.find (aguja) sería la solución más limpia.

Pero, si te importan las propiedades del buscador (o cualquier otra propiedad para el caso), inyectaría una interfaz de ISearcher en el constructor de pajar o en la función para facilitar eso. Esto es compatible tanto con el diseño orientado a objetos (un pajar tiene agujas) como con la inversión de la inyección de control / dependencia (facilita la prueba unitaria de la función "buscar").


El pajar no debe saber sobre la aguja, y la aguja no debe saber sobre el pajar. El investigador necesita saber sobre ambos, pero si el pajar debería saber cómo buscarse a sí mismo es el verdadero punto en disputa.

Así que iría con una mezcla de 2 y 3; el pajar debería poder decirle a otra persona cómo buscarlo, y el buscador debería ser capaz de usar esa información para buscar en el pajar.


En la mayoría de los casos, prefiero poder realizar operaciones simples de ayuda como esta en el objeto central, pero dependiendo del idioma, el objeto en cuestión puede no tener un método suficiente o sensible disponible.

Incluso en idiomas como JavaScript ) que le permiten aumentar / extender objetos incorporados, creo que puede ser conveniente y problemático (por ejemplo, si una versión futura del lenguaje presenta un método más eficiente que se reemplaza por uno personalizado).

Este artículo hace un buen trabajo al delinear tales escenarios.


Esto depende completamente de qué varía y qué permanece igual.

Por ejemplo, estoy trabajando en un framework (no OOP) donde el algoritmo de búsqueda es diferente dependiendo del tipo de aguja y el pajar. Además del hecho de que esto requeriría un doble despacho en un entorno orientado a objetos, también significa que no tiene sentido escribir needle.find(haystack) o escribir haystack.find(needle) .

Por otro lado, su aplicación podría delegar el hallazgo en cualquiera de las dos clases, o quedarse con un algoritmo en total, en cuyo caso la decisión es arbitraria. En ese caso, preferiría el método haystack.find(needle) porque parece más lógico aplicar el hallazgo al pajar.


Estoy con Brad en este caso. Cuanto más trabajo en sistemas inmensamente complejos, más veo la necesidad de desvincular verdaderamente los objetos. El tiene razón. Es obvio que una aguja no debería saber nada sobre el pajar, por lo que 1 definitivamente no está. Pero, un pajar no debería saber nada sobre una aguja.

Si estuviese modelando un pajar, podría implementarlo como una colección, pero como una colección de heno o paja , ¡no como una colección de agujas! Sin embargo, tomaría en consideración que las cosas se pierden en un pajar, pero no sé exactamente qué es exactamente eso. Creo que es mejor no hacer que el pajar busque elementos en sí mismo (qué inteligente es un pajar de todos modos). El enfoque correcto para mí es hacer que el pajar presente una colección de cosas que están en él, pero no son paja o heno o lo que sea que le da a un pajar su esencia.

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) }

De hecho, había más que escribir y abstraer en interfaces y luego me di cuenta de lo loco que estaba. Me sentí como si estuviera en una clase de CS en la universidad ...: P

Entiendes la idea. Creo que ir tan flojamente como sea posible es algo bueno, ¡pero tal vez me estaba dejando llevar un poco! :)


Fácil: ¡Quema el pajar! Después, solo la aguja permanecerá. Además, puedes probar los imanes.

Una pregunta más difícil: ¿cómo se encuentra una aguja en particular en un grupo de agujas?

Respuesta: enhebre cada una y una el otro extremo de cada filamento de hilo a un índice ordenado (es decir, punteros)


Hay otra alternativa, que es el enfoque utilizado por el STL de C ++:

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

¡Creo que es un gran ejemplo de gritos de C ++ "en tu cara"! a OOP. La idea es que OOP no es una bala de plata de ningún tipo; a veces las cosas se describen mejor en términos de acciones, a veces en términos de objetos, a veces ni a veces ni a los dos.

Bjarne Stroustrup dijo en TC ++ PL que cuando diseña un sistema debe esforzarse por reflejar la realidad bajo las limitaciones de un código eficaz y eficiente. Para mí, esto significa que nunca debes seguir nada a ciegas. Piensa en las cosas a mano (pajar, aguja) y en el contexto en el que estamos (buscando, de eso se trata la expresión).

Si el énfasis está en la búsqueda, entonces use un algoritmo (acción) que enfatice la búsqueda (es decir, se adapta de manera flexible a los almiares, océanos, desiertos, listas enlazadas). Si el énfasis está en el pajar, encapsule el método de búsqueda dentro del objeto pajar, y así sucesivamente.

Dicho esto, a veces tienes dudas y tienes dificultades para elegir. En este caso, estar orientado a objetos. Si cambias de opinión más adelante, creo que es más fácil extraer una acción de un objeto que dividir una acción en objetos y clases.

Siga estas pautas, y su código será más claro y, bueno, más hermoso.


Haystack puede contener cosas de un tipo de cosas es buscador de aguja es algo que es responsable de la búsqueda del buscador de cosas puede aceptar un montón de cosas como la fuente de dónde encontrar el buscador de cosas también puede aceptar una descripción de lo que debe encontrar

por lo tanto, preferiblemente, para una solución flexible, haría algo como: Interfaz IStuff

Haystack = IList <IStuff> Needle: IStuff

Finder .Find (IStuff stuffToLookFor, IList <IStuff> stuffsToLookIn)

En este caso, su solución no se atará solo a la aguja y al pajar, pero se puede usar para cualquier tipo que implemente la interfaz

así que si quieres encontrar un Pez en el océano, puedes.

var results = Finder.Find (pez, océano)


La respuesta a esta pregunta en realidad debería depender del dominio para el que se implementa la solución.
Si simula una búsqueda física en un pajar físico, es posible que tenga las clases

  • Espacio
  • Paja
  • Aguja
  • Buscador

Espacio
sabe qué objetos se encuentran en qué coordenadas
implementa las leyes de la naturaleza (convierte energía, detecta colisiones, etc.)

Aguja , paja
están ubicados en el espacio
reaccionar a las fuerzas

Buscador
interactúa con el espacio:
mueve la mano, aplica el campo magnético, quema el heno, aplica rayos X, busca la aguja ...

Por seeker.find(needle, space) tanto, seeker.find(needle, space) o seeker.find(needle, space, strategy)

El pajar está justo en el espacio donde estás buscando la aguja. Cuando abstrae el espacio como un tipo de máquina virtual (piense en: la matriz), puede obtener lo anterior con pajar en lugar de espacio (solución 3 / 3b) :

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

Pero la matriz era el Dominio, que solo debería ser reemplazado por el pajar, si su aguja no podría estar en ningún otro lado.

Y una vez más, era solo una anología. Curiosamente, esto abre la mente a direcciones totalmente nuevas:
1. ¿Por qué perdió la aguja en primer lugar? ¿Puedes cambiar el proceso para que no lo pierdas?
2. ¿Tienes que encontrar la aguja perdida o puedes simplemente obtener otra y olvidarte de la primera? (Entonces sería bueno, si la aguja se disolvió después de un tiempo)
3. Si pierde sus agujas con regularidad y necesita encontrarlas de nuevo, es posible que desee

  • hacer agujas que puedan encontrar, p. ej., se preguntan regularmente: ¿Estoy perdido? Si la respuesta es sí, envían su posición calculada por GPS a alguien o comienzan a emitir un pitido o lo que sea:
    needle.find(space) o needle.find(haystack) (solución 1)

  • instala un pajar con una cámara en cada pajita, después puedes preguntarle a la colmena de la pajar si vio la aguja últimamente:
    haystack.find (aguja) (solución 2)

  • coloque etiquetas RFID en sus agujas, para que pueda triangularlas fácilmente

Todo eso solo para decir que en su implementación usted hizo la aguja y el pajar y la mayoría del tiempo la matriz en algún tipo de nivel.

Así que decide según tu dominio:

  • ¿Es el propósito del pajar contener agujas? Luego busca la solución 2.
  • ¿Es natural que la aguja se pierda en cualquier lugar? Luego busca la solución 1.
  • ¿La aguja se pierde en el pajar por accidente? Luego vaya a la solución 3. (o considere otra estrategia de recuperación)

Otra forma posible puede ser crear dos interfaces para objeto de búsqueda, por ejemplo, pajar y objeto ToBeSearched, por ejemplo, aguja. Entonces, se puede hacer de esta manera

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 } }


Para citar a los grandes autores de SICP ,

Los programas deben estar escritos para que las personas los lean, y solo de manera incidental para que las máquinas los ejecuten

Prefiero tener ambos métodos 1 y 2 a la mano. Usando ruby ​​como ejemplo, viene con .include? que se usa así

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

Sin embargo, a veces, solo por razones de legibilidad, quiero darle la vuelta. Ruby no viene con un in? método, pero es de una sola línea, así que a menudo hago esto:

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

Si es "más importante" enfatizar el pajar, o la operación de búsqueda, ¿prefiero escribir include? . A menudo, sin embargo, ni el pajar ni la búsqueda son realmente lo que te importa, solo que el objeto está presente, ¿en este caso lo encuentro in? mejor transmite el significado del programa.


Personalmente, me gusta el segundo método. Mi razonamiento se debe a que las principales API con las que he trabajado usan este enfoque, y creo que tiene más sentido.

Si tiene una lista de cosas (pajar) debería buscar (buscar ()) la aguja.


Por lo general, las acciones deben aplicarse a lo que está haciendo la acción en ... en este caso, el pajar, por lo que creo que la opción 2 es la más adecuada.

También tiene una cuarta alternativa que creo que sería mejor que la alternativa 3:

haystack.find(needle, searcher)

En este caso, le permite proporcionar la manera en que desea buscar como parte de la acción, y así puede mantener la acción con el objeto que está siendo operado.


Puedo pensar en situaciones donde cualquiera de los dos primeros sabores tiene sentido:

  1. Si la aguja necesita preprocesamiento, como en el algoritmo Knuth-Morris-Pratt, needle.findIn(haystack) (o pattern.findIn(text) ) tiene sentido, porque el objeto aguja contiene las tablas intermedias creadas para que el algoritmo funcione eficazmente

  2. Si el pajar necesita un preprocesamiento, como por ejemplo en un trie, el haystack.find(needle) (o words.hasAWordWithPrefix(prefix) ) funciona mejor.

En ambos casos, uno de aguja o pajar está al tanto de la búsqueda. Además, ambos se conocen el uno al otro. Si desea que la aguja y el pajar no se den cuenta el uno del otro o de la búsqueda, searcher.find(needle, haystack) sería apropiado.


Si Needle y Haystack son DAO, entonces las opciones 1 y 2 están descartadas.

La razón de esto es que los DAO solo deberían ser responsables de mantener las propiedades de los objetos del mundo real que están modelando, y solo tienen métodos getter y setter (o solo acceso directo a la propiedad). Esto hace que la serialización de los DAO en un archivo, o la creación de métodos para una copia genérica de comparación / genérica sea más fácil de escribir, ya que el código no contiene un montón de declaraciones "if" para omitir estos métodos de ayuda.

Esto simplemente deja la opción 3, que la mayoría estaría de acuerdo con el comportamiento correcto.

La opción 3 tiene algunas ventajas, y la mayor ventaja es la prueba unitaria. Esto se debe a que los objetos Needle y Haystack se pueden burlar fácilmente ahora, mientras que si se usaron las opciones 1 o 2, el estado interno de Needle o Haystack debería modificarse antes de poder realizar una búsqueda.

En segundo lugar, con el buscador ahora en una clase separada, todos los códigos de búsqueda pueden mantenerse en un solo lugar, incluido el código de búsqueda común. Mientras que si el código de búsqueda fue puesto en el DAO, el código de búsqueda común sería almacenado en una jerarquía de clases complicada, o con una clase Searcher Helper de todos modos.


Si tiene una referencia al objeto aguja, ¿por qué lo busca? :) El dominio del problema y los casos de uso te dicen que no necesitas la posición exacta de la aguja en un pajar (como lo que podrías obtener de list.indexOf (element)), solo necesitas una aguja. Y todavía no lo tienes. Entonces mi respuesta es algo como esto

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

o

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

o

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

Estoy de acuerdo en que hay más soluciones posibles que se basan en diferentes estrategias de búsqueda, por lo que presentan el buscador. Hubo algunos comentarios sobre esto, así que no le presto atención aquí. Lo que quiero decir es soluciones anteriores, olvídate de los casos de uso: ¿de qué sirve buscar algo si ya tienes referencia? En el caso de uso más natural todavía no tienes una aguja, por lo que no usas una aguja variable.


Una mezcla de 2 y 3, realmente.

Algunos pajares no tienen una estrategia de búsqueda especializada; un ejemplo de esto es una matriz. La única forma de encontrar algo es comenzar desde el principio y probar cada elemento hasta que encuentre el que desea.

Para este tipo de cosas, una función gratuita es probablemente la mejor (como C ++).

Algunos pajares pueden tener una estrategia de búsqueda especializada impuesta sobre ellos. Se puede ordenar una matriz, lo que le permite usar la búsqueda binaria, por ejemplo. Una función gratuita (o un par de funciones gratuitas, por ejemplo, sort y binary_search) es probablemente la mejor opción.

Algunos pajares tienen una estrategia de búsqueda integrada como parte de su implementación; los contenedores asociativos (conjuntos ordenados y ordenados y mapas) todos lo hacen, por ejemplo. En este caso, encontrar es probablemente un método de búsqueda esencial, por lo que probablemente debería ser un método, es decir, haystack.find (aguja).


Yo diría que la opción 1 está completamente fuera. El código debe leer de una manera que le indique lo que hace. La opción 1 me hace pensar que esta aguja me va a buscar un pajar.

La opción 2 se ve bien si un pajar está destinado a contener agujas. ListCollections siempre contendrá ListItems, por lo que la colección collection.find (elemento) es natural y expresiva.

Creo que la introducción de un objeto auxiliar es apropiada cuando:

  1. No controlas la implementación de los objetos en cuestión
    IE: search.find (ObsecureOSObject, archivo)
  2. No hay una relación regular o sensata entre los objetos
    IE: nameMatcher.find (casas, trees.name)

haystack.find (aguja), pero debería haber un campo de búsqueda.

Sé que la inyección de dependencia está de moda, por lo que no me sorprende que se haya aceptado @just Stone''s haystack.find (aguja, buscador). Pero no estoy de acuerdo: la elección de qué buscador se utiliza me parece una decisión para el pajar.

Considere dos ISearchers: MagneticSearcher itera sobre el volumen, moviéndose y pisando el imán de una manera consistente con la fuerza del imán. QuickSortSearcher divide la pila en dos hasta que la aguja es evidente en una de las subpilas. La elección correcta del buscador puede depender de qué tan grande es el pajar (relativo al campo magnético, por ejemplo), cómo la aguja se metió en el pajar (es decir, ¿la posición de la aguja es realmente aleatoria o sesgada?), Etc.

Si tienes haystack.find (aguja, buscador), estás diciendo "la mejor opción para elegir es cuál es la mejor estrategia de búsqueda fuera del contexto del pajar". No creo que eso sea correcto. Creo que es más probable que "los pajares saben cómo buscarse ellos mismos". Agregue un colocador y aún puede inyectar manualmente el buscador si necesita anular o para probar.


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();


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

iterator puede ser una interfaz para cualquier colección inmutable, con colecciones que tienen el findFirst(fun: T => Boolean) común findFirst(fun: T => Boolean) haciendo el trabajo. Siempre que el pajar sea inmutable, no es necesario ocultar ningún dato útil de "afuera". Y, por supuesto, no es bueno vincular la implementación de una colección personalizada no trivial y algunas otras cosas que sí tienen haystack . Divide y conquista, ¿de acuerdo?


haystack.magnet().filter(needle);