Una buena regla general es que los nombres de los métodos deben ser verbos o predicados de modo que el objeto sobre el que los invoque ( self
en la convención estándar de Python, this
en la mayoría de los otros idiomas) se convierta en el sujeto.
Según esta regla, file.close
es un poco incorrecto, a menos que vaya con el modelo mental de que el archivo se cierra solo, o que el file
objeto no representa el archivo en sí, sino más bien un identificador de archivo o algún tipo de objeto proxy.
Sin embargo, un saco de boxeo nunca se perfora solo, por lo que punchingBag.punch()
está mal de cualquier manera. be_punched()
es técnicamente correcto, pero feo. receive_punch()
podría funcionar, o handle_punch()
. Otro enfoque, bastante popular en JavaScript, es tratar tales llamadas a métodos como eventos, y la convención debe ir con el nombre del evento, con el prefijo 'on', para que sea on_punched()
o on_hit()
. Alternativamente, podría adoptar la convención de que los participios pasados indican voz pasiva, y según esa convención, el nombre del método sería justo punched()
.
Otro aspecto a considerar es si el saco de boxeo sabe realmente qué lo golpeó: ¿hace alguna diferencia si lo golpeas, lo golpeas con un palo o te topas con un camión? Si es así, ¿cuál es la diferencia? ¿Puedes reducir la diferencia a una discusión, o necesitas diferentes métodos para diferentes tipos de castigo recibido? Un método único con un parámetro genérico es probablemente la solución más elegante, porque mantiene el grado de acoplamiento bajo, y dicho método no debería llamarse punched()
o handle_punch()
, sino más bien algo más genérico receive_hit()
. Con tal método en su lugar, puede implementar todo tipo de actores que pueden golpear sacos de arena, sin cambiar el saco de arena en sí.
Hitable
.Creo que es una cuestión conceptual (cómo pensamos sobre el mundo). Está bien decir:
door.close()
paper.fold()
file.close()
Es raro decir:
bag.punch()
Tendría que tener algo con lo que golpearse en primer lugar (por ejemplo, brazos). Probablemente dirías:
punching_bag.move()
Está bien que los objetos programáticos hagan cosas que normalmente otros hacen con ellos (en el "mundo real"). Pero supongo que siempre debería tener al menos algún sentido que la cosa se está haciendo a sí misma . Debería poder imaginarlo fácilmente sin oscurecerse (como en el caso de
punching_bag
).fuente
Es cuestión de gustos, creo.
Punching bag
Elpunch()
método es al menos consistente confile.close()
oframe.move()
en el sentido de experimentar acción sobre sí mismo. Mayor pregunta sería, ¿por quéBoxer
tienepunch(something)
método en absoluto?fuente
Coach.sayPunchToBoxer()
,Boxer.punchNearestBag()
yBag.punch()
. De lo contrario, debe adivinar lo que sucederá cada vez que llameCoach.punch()
. La regla general es: si el objeto que experimenta acción no se especifica en el nombre del método, entonces el receptor es ese objeto.Tiene dos mensajes diferentes: uno para ordenar que un objeto golpee y otro para informar a un objeto que fue perforado. Tenga en cuenta que es probable que un objeto Boxer deba responder a ambos . De manera diferente . Esa es una muy buena razón para darles diferentes nombres.
Mi inclinación sería mantener
punch(boxer, object, strength)
y cambiar el nombre del método opuesto apunched
. Podría llamarlohandle_punch
o algo así, pero aún es ambiguo si se trata de manejar un comando de golpe o la notificación de que se golpeó.fuente
defend
en este caso particular). Pero el saco de boxeo nunca será bidireccional como ese. Y ya existe este archivo .close () ...defend
es un comando Es una posible acción que un objeto podría realizar en respuestapunched
, pero no querrá que otros objetos invoquendefend
directamente.Su enfoque eventualmente conducirá a un código muy acoplado.
Para resumir, Eric Lippert, idealmente aquí, querrás que el boxeador sea capaz de golpear muchas cosas. Tener el saco de boxeo como la firma de la función de boxeador implica que el boxeador se crea con un conocimiento inmediato de Todos (eso es punzante). Además, dar un puñetazo y recibir un puñetazo son dos cosas MUY diferentes, por lo tanto, no deberían compartir el mismo nombre.
Prefiero modelar esto como un Boxer que crea un golpe (otro objeto que contiene la fuerza, el alcance, la dirección, etc. del atributo del golpe).
Luego, tenga el saco de boxeo con un método como onPunch que recibe este objeto de punzón para calcular el efecto del punzón en sí mismo.
Teniendo esto en cuenta, el nombre de las cosas es muy importante. Debe ajustarse al modelo mental que tiene de la situación. Si se encuentra tratando de explicar cómo puede suceder algo que no tiene sentido a primera vista, o si le resulta más difícil nombrar algo, entonces quizás su modelo esté equivocado y deba cambiar.
Es difícil cambiar un modelo después de comenzar, la gente generalmente tiende a doblegar la realidad para que se ajuste al modelo. El problema con esto es que a medida que dobla las cosas para que quepan (como un saco de boxeo que puede perforar cosas) el mundo que está creando se vuelve cada vez más complejo y las interacciones se vuelven cada vez más difíciles de implementar. Eventualmente llegarás a un punto en el que agregar incluso lo más trivial se convierte en una pesadilla de cambios y errores. Esta deuda técnica conceptual puede tener un precio muy elevado, incluso si el costo inicial se percibía en ese momento como lo más barato.
fuente
Este es el problema que llamo confusión "objeto / sujeto" y es bastante frecuente.
Las oraciones generalmente tienen un sujeto que hace el verbo en su objeto objetivo .
Ahora con respecto a la programación, lo único que realmente hace las cosas es la computadora. O prácticamente un proceso, hilo o fibra. Los objetos no son animados por defecto. No tienen sus propios hilos en ejecución, por lo que realmente no pueden hacer nada.
Esto significa que los métodos operan en ellos, son el objetivo de la acción, no quién realiza la acción. ¡Es por eso que los llamamos "objetos", no "sujetos"!
Cuando dice
File.close
que no se cierra el archivo, es el subproceso actual que cierra el archivo. Si diceArray.sort
, el subproceso actual ordena la matriz. Si diceHttpServer.sendRequest
, el subproceso actual en ejecución envía la solicitud al servidor (¡no al revés!). De manera similar, decirPunchingBag.punch
significa que el hilo corriente actual golpea la bolsa.Esto significa que si desea
Boxer
poder perforar, entonces debe ser una subclase de unaThread
para que pueda hacer cosas como sacos de boxeo en su función de hilo.Sin embargo, a veces también tiene sentido decir que el saco de boxeo se golpea solo en el caso de que cada objeto tenga su propio hilo, es posible que desee evitar las condiciones de carrera e implementar llamadas de método como mensaje que pasa:
punch
golpea el saco enviándole el mensaje, son golpes de hilo a continuación, le devuelve elpunch successful
mensaje, pero eso es solo un detalle de implementación.fuente
Estoy de acuerdo en que "punch" es un buen nombre de método para la clase Boxer, ya que (con algunos ajustes) podría reutilizarse contra otros objetos. También describe con precisión que un objeto de una clase está realizando una acción sobre otro objeto. Sin embargo, cambiaría el nombre del método a "doPunch", para demostrar más claramente la relación.
Sin embargo, para la clase PunchingBag, encuentro que el nombre del método es demasiado vago o un poco impreciso de lo que está sucediendo en el método. Cuando veo "golpe", creo que algo está golpeando a otra cosa. Sin embargo, aquí, el objeto PunchingBag está reaccionando a un golpe de un objeto (en este caso, un objeto Boxer). Entonces, cambiaría el nombre del método aquí a "isPunched" para ilustrar que el objeto está reaccionando a un golpe.
Sin embargo, esta es mi interpretación de cómo nombraría los métodos. Todo es cuestión de gustos y qué estándares estás siguiendo.
fuente
isPunched
es realmente engañoso (más o menos, dependiendo del esquema de nombres del marco).punch()
?hmmmm Estoy cuestionando el saco de boxeo como clase, porque realmente no te importa el saco de boxeo, te importa el impacto y la fuerza del puño de los Boxers. Por lo tanto, los métodos deben ser sobre lo que sea medir e informar el impacto del golpe. incluso si esto proviene del 'saco de boxeo', el nombre aún debe revelar la responsabilidad, como punchImpactMeter, etc.
fuente
El boxeador golpea el saco de boxeo -> boxer.punch
El boxeador golpea el saco de boxeo -> punchingbag.get_punch
fuente