Pregunta

¿Qué factores determinan qué enfoque es más apropiado?

¿Fue útil?

Solución

Creo que ambos tienen sus lugares.

No deberías simplemente usar DoSomethingToThing(Thing n) sólo porque piensas que "la programación funcional es buena".Del mismo modo, no deberías simplemente usar Thing.DoSomething() porque "la programación orientada a objetos es buena".

Creo que todo se reduce a lo que intentas transmitir.Deja de pensar en tu código como una serie de instrucciones y empieza a pensar en él como un párrafo o una frase de una historia.Piensa qué partes son las más importantes desde el punto de vista de la tarea en cuestión.

Por ejemplo, si la parte de la 'oración' que deseas enfatizar es el objeto, debes usar el estilo OO.

Ejemplo:

fileHandle.close();

La mayoría de las veces, cuando pasa identificadores de archivos, lo principal en lo que piensa es en realizar un seguimiento del archivo que representa.

Contraejemplo:

string x = "Hello World";
submitHttpRequest( x );

En este caso, enviar la solicitud HTTP es mucho más importante que la cadena que es el cuerpo, por lo que submitHttpRequst(x) es preferible a x.submitViaHttp()

No hace falta decir que estos no son mutuamente excluyentes.Probablemente tendrás

networkConnection.submitHttpRequest(x)

en el que los mezclas a ambos.Lo importante es que pienses en qué partes se enfatizan y qué le transmitirás al futuro lector del código.

Otros consejos

Para estar orientado a objetos, diga, no pregunte: http://www.pragmaticprogrammer.com/articles/tell-dont-ask.

Entonces, Thing.DoSomething() en lugar de DoSomethingToThing(Thing n).

Si estás tratando con el estado interno de una cosa, Thing.DoSomething() tiene más sentido, porque incluso si cambias la representación interna de la cosa, o cómo funciona, el código que le habla no tiene que cambiar.Si está tratando con una colección de cosas o escribiendo algunos métodos de utilidad, el estilo procedimental DoSomethingToThing() podría tener más sentido o ser más sencillo;pero aún así, generalmente se puede representar como un método en el objeto que representa esa colección:por ejemplo

GetTotalPriceofThings();

vs

Cart.getTotal();

Realmente depende de qué tan orientado a objetos esté su código.

  1. Cosa.Hacer algo es apropiado si Cosa es el sujeto de su oración.
    • Hacer algo a la cosa (cosa n) es apropiado si Cosa es el objeto de su oración.
    • Cosa A.Hacer algo a la cosa B (Cosa B m) Es una combinación inevitable, ya que en todos los lenguajes que se me ocurren, las funciones pertenecen a una clase y no se pertenecen mutuamente.Pero esto tiene sentido porque puedes tener un sujeto y un objeto.

La voz activa es más sencilla que la voz pasiva, así que asegúrese de que su oración tenga un tema que no sea solo "la computadora".Esto significa que utilice el formulario 1 y el formulario 3 con frecuencia, y utilice el formulario 2 rara vez.

Para mayor claridad:

// Form 1:  "File handle, close."
fileHandle.close(); 

// Form 2:  "(Computer,) close the file handle."
close(fileHandle);

// Form 3:  "File handle, write the contents of another file handle."
fileHandle.writeContentsOf(anotherFileHandle);

Estoy de acuerdo con Orion, pero voy a reformular el proceso de decisión.

Tienes un sustantivo y un verbo/un objeto y una acción.

  • Si muchos objetos de este tipo utilizarán esta acción, intente que la acción forme parte del objeto.
  • En caso contrario, intenta agrupar la acción por separado, pero con acciones relacionadas.

Me gustan los ejemplos de archivos/cadenas.Hay muchas operaciones de cadena, como "SendAsHTTPReply", que no sucederán para una cadena promedio, pero sí ocurren con frecuencia en una configuración determinada.Sin embargo, básicamente siempre cerrarás un Archivo (con suerte), por lo que tiene mucho sentido poner la acción Cerrar en la interfaz de clase.

Otra forma de pensar en esto es como comprar parte de un sistema de entretenimiento.Tiene sentido combinar un control remoto de TV con un televisor, porque siempre los usas juntos.Pero sería extraño combinar un cable de alimentación para una videograbadora específica con un televisor, ya que muchos clientes nunca lo usarán.La idea clave es ¿Con qué frecuencia se utilizará esta acción en este objeto??

No hay suficiente información aquí.Depende de si su idioma admite la construcción "Cosa.algo" o equivalente (es decir,es un lenguaje OO).Si es así, es mucho más apropiado porque ese es el paradigma OO (los miembros deben estar asociados con el objeto sobre el que actúan).En un estilo procedimental, por supuesto, DoSomethingtoThing() es su única opción...o CosaHacerAlgo()

DoSomethingToThing(Thing n) sería más un enfoque funcional mientras que Thing.DoSomething() sería más un enfoque orientado a objetos.

Esa es la opción de programación orientada a objetos versus programación procedimental :)

Creo que las ventajas de OO bien documentadas se aplican a Thing.DoSomething()

Aquí hay un par de factores a considerar:

  • ¿Se puede modificar o ampliar el Thing clase.Si no, usa el primero.
  • Poder Thing ser instanciado.Si no, utilice este último como método estático.
  • Si Thing realmente se modifica (es decir,tiene propiedades que cambian), prefieren este último.Si Thing no se modifica, este último es igualmente aceptable.
  • De lo contrario, como los objetos están destinados a mapearse en objetos del mundo real, elija el método que parezca más basado en la realidad.

Incluso si no estás trabajando en un lenguaje OO, donde tendrías Thing.DoSomething(), para la legibilidad general de tu código, con un conjunto de funciones como:

ThingDoSomething () ThingDoanotherTask () ThingwedosomelElse ()

entonces

Otra cosaHacer algo()

y así sucesivamente es mucho mejor.

Todo el código que funciona en "Cosa" está en una única ubicación.Por supuesto, "Hacer algo" y otras tareas deben nombrarse de forma coherente, de modo que tenga ThingOneRead(), ThingTwoRead()...A estas alturas ya deberías entender.Cuando vuelva a trabajar en el código dentro de doce meses, apreciará tomarse el tiempo para hacer las cosas lógicas.

En general, si "algo" es una acción que "cosa" naturalmente sabe cómo hacer, entonces deberías usar thing.doSomething().Esa es una buena encapsulación de OO, porque de lo contrario DoSomethingToThing(cosa) tendría que acceder a información interna potencial de la "cosa".

Por ejemplo factura.getTotal()

Si "algo" no forma parte naturalmente del modelo de dominio de "cosa", entonces una opción es utilizar un método auxiliar.

Por ejemplo:Logger.log(factura)

Si es probable que hacer algo en un objeto produzca un resultado diferente en otro escenario, entonces le sugiero oneThing.DoSomethingToThing(anotherThing).

Por ejemplo, es posible que tenga dos elementos para guardar en su programa, por lo que podría adoptar DatabaseObject.Save(thing). SessionObject.Save(thing) sería más ventajoso que thing.Save() o thing.SaveToDatabase o thing.SaveToSession(). .

Rara vez no paso parámetros a una clase, a menos que esté recuperando propiedades públicas.

Para agregar a la respuesta de Aeon, depende de la cosa y de lo que quieras hacer con ella.Entonces, si estás escribiendo una cosa y DoSomething altera el estado interno de la cosa, entonces el mejor enfoque es Thing.DoSomething.Sin embargo, si la acción hace más que cambiar el estado interno, entonces HacerAlgo(Cosa) tiene más sentido.Por ejemplo:

Collection.Add(Thing)

es mejor que

Thing.AddSelfToCollection(Collection)

Y si no escribiste Cosa y no puedes crear una clase derivada, entonces no tienes otra opción que hacer Hacer Algo (Cosa)

Incluso en la programación orientada a objetos podría resultar útil utilizar una llamada a función en lugar de un método (o, de hecho, llamar a un método de un objeto distinto de aquel al que lo llamamos).Imagine un marco de persistencia de base de datos simple en el que le gustaría simplemente llamar a save() en un objeto.En lugar de incluir una declaración SQL en cada clase que le gustaría guardar, complicando así el código, distribuyendo SQL por todo el código y haciendo que el cambio del motor de almacenamiento sea un PITA, puede crear una interfaz que defina save(Class1), save(Class2). ) etc.y su implementación.Entonces estarías llamando a DatabaseSaver.save(class1) y tendrías todo en un solo lugar.

tengo que estar de acuerdo con Kevin Conner

También tenga en cuenta la persona que llama de cualquiera de las 2 formas.La persona que llama probablemente sea un método de algún otro objeto que definitivamente le hace algo a tu cosa :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top