¿Es un olor a código si un método privado llama a uno público?


25

¿Es un olor a código llamar método público en método privado de la misma instancia de objeto?


AAMOI, ¿tienes un ejemplo específico?
ocodo

No, actualmente no. Acabo de recordar un caso que discutí con mis colegas. Quería obtener algunas opiniones aquí también.
Eimantas

55
Por lo general, puedo encontrar un acrónimo según el contexto, pero AAMOI definitivamente tuve que buscarlo
Carson Myers

@Carson: ¿encontraste algo?
Eimantas

44
Como un asunto de interés
Carson Myers

Respuestas:


32

No no mal olor. Esto podría ser necesario, ¿por qué sospecha que está mal? Un método a nivel atómico es una entidad independiente que realiza una tarea. Siempre que realice una tarea, cualquiera que tenga acceso a ella puede llamarla para realizarla.


Estoy de acuerdo. Algunos métodos proporcionan una funcionalidad útil tanto para los internos como para los llamadores externos. Una bandera roja podría ser si el método público fuera muy específico para la implementación interna, pero aun así, no todas las clases tienen la intención de ocultar sus elementos internos. A menudo tengo una capa de "herramienta" de estructura de datos debajo de una capa de tipo abstracto de contenedor, por ejemplo, de esa manera puedo reutilizar parte del código de estructura de datos para otras estructuras de datos subyacentes a otros contenedores.
Steve314

19

Código de olor? Sí, no es realmente malo, pero es un buen indicador de que la clase puede tener demasiadas responsabilidades.

Tómelo como una señal de que es posible que la clase deba dividirse en diferentes objetos, los métodos privados realmente no deberían necesitar llamar a los métodos públicos del mismo objeto, ciertamente en un diseño OO limpio.

Por supuesto, una vez que haya inspeccionado la clase y las razones para la llamada al método estén claras, puede ser un uso perfectamente razonable, en general, esperaría que los métodos de utilidad para la clase sean privados, pero si uno es lo suficientemente útil para ser público y utilizado por otros métodos, generalmente esperaría que esos métodos también sean públicos.

Al igual que con todos los olores de código, esto es una motivación para una mayor inspección del código, racionalizar y quizás refactorizar, pero no es motivo de alarma.


55
+1 para "no es motivo de alarma". Demasiadas veces vemos un "olor" y pasamos instantáneamente al modo refactorizado sin pensar.
Michael K

+1 para SRP. Me encontré con un caso en el que un decorador no funcionaba porque la clase decorada estaba llamando a su propia función pública, sin pasar por el decorador. La solución: dividir la clase en dos e inyectar la dependencia decorada.
Jon Hulka

18

Puede llevar a sorpresas desagradables si alguien que no ha leído el código fuente de esta clase intenta subclasificarlo y anula el método público. Si eso es una preocupación real obviamente depende de su situación. Tal vez deberías considerar hacer que el método público o incluso la clase sea final.


¿Por qué? Si un método público sobrescrito lleva a sorpresas desagradables, ¿realmente importa quién llamó al método?
user281377

44
Si lo hace Si anular un método público rompe otro método público, también puedo anular ese otro método. Si se rompe un método privado, ¿puedo ...?
Kim

55
Una sorpresa desagradable resultante de anular un método público es un olor a código en sí mismo. Un hedor de código, en realidad.
Larry Coleman

Kim: si el método es público, debes asumir que otras clases también lo llaman ...
user281377

@Larry: ¡Exactamente! Un método privado (que generalmente contiene supuestos específicos de implementación) que llama a uno público hace que sea más probable que anular el método público rompa las cosas.
Kim

5

No creo que podamos genaralizar.

Todo depende en gran medida del contexto.

Podría tener, por ejemplo, un método de utilidad pública en una clase que usan otras clases, y también algún método privado en la misma clase.


5

No. ¿Qué más se debe hacer en ese caso? ¿Hacer público el método privado o el método público privado? Copiar y pegar el código del método público al privado?


O haga que el método público delegue en un (nuevo) método privado que es invocado por el otro método privado. Pero, ¿por qué molestarse?
Lawrence Dol

4

NO , no hay mal olor aquí.

si implementamos la interfaz de una cola con List, ¿es un mal olor simplemente llamar a las funciones apropiadas de List para lograr la implementación de la cola fácilmente?

si tiene algo y desea convertirlo en otra cosa (como envoltorio), entonces no es un mal olor, su reutilización de código con patrón de diseño actuó en el nivel de función (¿es una función un objeto?)


2

Sé que esta es una publicación antigua, pero es algo que he estado debatiendo en el trabajo. 'Sí' considero que esto es un olor a código, y no puedo entender por qué querrías hacer esto. Si un método privado debe llamar a un método público, entonces el contenido del método público debe tomarse y colocarse en un método privado, que ambos métodos pueden llamar. ¿Por qué?

  1. El método público puede contener pruebas que no son necesarias una vez que ejecuta el código internamente. Es posible que reciba un UserObj y quiera probar los permisos de usuario, por ejemplo.

  2. Después de una llamada pública, es posible que deba bloquear el objeto, si está utilizando subprocesos, por lo que internamente, no querrá volver a llamar a un método público.

  3. En mi opinión, es más probable que introduzca errores circulares y bucles infinitos y excepciones fuera de memoria.

  4. Simple y llanamente, mal diseño y "vago". Los métodos públicos brindan acceso al mundo exterior. No hay razón para caminar de regreso cuando ya estás adentro.


1
¿Qué pasa si el método público existente es llamado por muchas otras clases? Hacerlo privado lo romperá. Recuerde que los métodos públicos son llamados por otras clases por otros motivos, no solo por esta clase. por qué existen los métodos públicos.
Michael Durrant

Dije que 'el contenido del método público debe tomarse y colocarse en un método privado ...' El método público permanecerá, pero llame al nuevo método privado. Al igual que cualquier otro método privado que necesite reutilizar la misma funcionalidad.
Mark Graham el

Por lo tanto, está agregando otro método por ninguna otra razón que, bueno, porque declaró que se trata de un "olor a código". Los métodos sin sentido son un mal olor del código.
gnasher729

Lo siento, pero, ¿no acabo de enumerar varias razones anteriores? Gran parte del código que escribo es para sistemas empresariales, muchas clases están restringidas a los usuarios según el rol. Muchos métodos públicos prueban los permisos y parámetros de los usuarios. ¿Por qué querría volver a llamar al mismo método público para reutilizar su funcionalidad y volver a probar los permisos del usuario?
Mark Graham el

Nunca en mi vida he necesitado llamar a un método público desde uno privado. Simplemente me parece y se siente muy mal. Me sorprende mucho que la mayoría de la gente piense que está bien.
Trampa

2

Imagina lo contrario. Está en un método privado y necesita funcionalidad en un método público. ¿Qué pasaría si no pudiera llamar a ese método público desde el privado? ¿Qué harías?

  • ¿Crear un método privado duplicado? No
  • ¿Crear un método público especial para la ocasión? No
  • ¿Llamar a un método privado especial que puede llamar a métodos públicos? No
  • ¿Algún tipo de súper que pueda hacer esto? No

La respuesta es claramente que cuando desea la funcionalidad en un método público, debería poder llamar a ese método desde métodos de esta clase o de otras clases.


1

En mi código, a menudo creo captadores de carga diferida, es decir, el objeto se inicializa la primera vez que se solicita y luego reutiliza el mismo objeto instanciado. Sin embargo, un objeto instanciado usando una carga diferida implica que no necesariamente se puede instanciar en un punto dado. En lugar de comprender la secuencia de llamadas de tal manera que sé que ese objeto ya está instanciado o repite el mismo código de una carga diferida dentro de otro método, simplemente llamo al cargador diferido cada vez que necesito ese objeto.

Así como puede usar métodos públicos de una manera inteligente, también puede usarlos incorrectamente. Un ejemplo de esto podría ser un método público que procesa sus parámetros antes de llamar a otro método privado. Sería un error llamar a ese método público de manera casual simplemente porque tiene los mismos parámetros. El error es sutil, pero es un error de diseño más que cualquier otra cosa y requiere que aprenda a manejar con los parámetros del método interno en lugar de los parámetros del método público.

Entonces, para responder a su pregunta, ciertamente no es un código incorrecto si lo usa correctamente.


1

La pregunta que debe hacerse es por qué su clase tiene la misma necesidad que los clientes de su clase. Por lo general, una clase tiene necesidades muy diferentes de sus clientes. Entonces sí, esto es una indicación de que tienes

(a) expuso algo públicamente que debería ser privado; o

(b) el comportamiento de la clase no es lo suficientemente limitado (piense en el principio de responsabilidad individual).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.