Tuve un pequeño debate con un compañero de trabajo. En pocas palabras, ¿hay una buena razón para ocultar / encapsular funciones que son puras?
Por "puro" me refiero a la definición de Wikipedia :
- Siempre devuelve los mismos resultados de la misma entrada. (En aras de esta discusión
Foo Create(){ return new Foo(); }
se considera impuro siFoo
no tiene semántica de valor). - No utiliza estado mutable (excepto variables locales) o E / S.
- No produce efectos secundarios.
design
pure-function
Telastyn
fuente
fuente
Respuestas:
Una función pura aún podría ser un detalle de implementación. Aunque la función puede no causar daño (desde el punto de vista de no romper invariantes / contratos importantes), al exponerla, tanto el autor como los usuarios de esa clase / módulo / paquete pierden. El autor pierde porque ahora no puede eliminarlo incluso si la implementación cambia y la función ya no le es útil. Los usuarios pierden porque tienen que examinar e ignorar las funciones adicionales que no son relevantes para usar la API para comprenderla.
fuente
La pregunta es al revés.
No busca una razón para hacer que una función no sea pública. Para empezar, es una mentalidad incorrecta (en mi opinión). El razonamiento debe ser al revés.
En otras palabras, no pregunte "¿por qué lo haría privado?". Pregunte: "¿por qué debería hacerlo público?"
En caso de duda, no lo exponga. Es algo así como la navaja de afeitar de Ockham: no multiplique los derechos más allá de la necesidad.
EDITAR: Abordar los argumentos en contra presentados por @Telastyn en los comentarios (para evitar una discusión extendida allí):
Sí, a veces es una molestia si una clase está abierta a la herencia, pero no puede anular algunos métodos privados (cuyo comportamiento le gustaría modificar).
Pero
protected
sería suficiente, y todavía no es público.Si se vuelve problemático, ¡simplemente hazlo público! Existe la necesidad de la que estaba hablando :)
Mi punto es que no deberías hacerlo por si acaso (YAGNI y todo).
Tenga en cuenta que siempre es más fácil hacer pública una función privada que devolverla a la privacidad. Es probable que este último rompa el código existente.
fuente
No creo que la decisión de ocultar / encapsular una función dependa de su pureza. El hecho de que una función sea pura no significa que los externos necesiten saber sobre ella. Curiosamente, si la función es pura y está destinada a ser pública, tal vez ni siquiera necesite ser un miembro de la instancia de la interfaz, tal vez sea más adecuada como estática. Pero nuevamente, todo esto depende de la intención del contrato y, en este caso, de la agrupación lógica de la funcionalidad, no de la pureza de la función.
fuente
Las clases deben cumplir con el Principio de responsabilidad única . Si bien una clase puede necesitar recurrir a otra funcionalidad para lograr sus objetivos, solo debe exponer funciones que son parte de su responsabilidad única.
Este es solo un ejemplo de un caso en el que la visibilidad podría causar un problema.
Considere una clase que frobnica los widgets. Tal vez como parte de su código de frobnication necesita alguna función de utilidad que analice una cadena: tal vez necesita transformar el nombre del widget de una manera que las funciones de cadena estándar no admitan.
Dado que esta es una función pura (la cadena entra, la transforma de alguna manera, devuelve una nueva cadena), podría ser pública o privada sin consecuencias. O podría?
Si lo haces público, ahora tu clase tiene dos responsabilidades: frobnicando widgets y transformando cadenas. Esto viola SRP y puede causar problemas si otras clases dependen de la función. Dado que esto es algo que cree que solo se usa internamente en la clase, quizás cambie su interfaz o visibilidad. Ahora las clases en otras partes del sistema están rotas.
Al mantener la función privada, nadie tiene la oportunidad de confiar en un código que no sea parte de la responsabilidad única de la clase.
fuente
StringTransformer
clase separada para encapsular dos o tres líneas de código que solo se usan en un lugar? Estoy de acuerdo en que una vez que el código se usa en varios lugares, es mejor separarlo en una nueva clase con una responsabilidad, pero hay una compensación.