¿Por qué (no) necesitan captadores?

El artículo anterior sobre setters / getters como una forma de trabajar con una entidad (usando Symfony en PHP como ejemplo) recibió una acalorada discusión. En este artículo trataré de expresar mis pensamientos por separado sobre los captadores: por qué y cuándo obtener algo, qué responsabilidad deciden y cuándo es apropiado usarlos, cuando no es apropiado. Traté de recopilar pensamientos en un solo lugar y formalizarlos contigo.

getHumanFactory (). getHuman (). getDoneWork (). getWorkTime ()


Se necesitan getters para obtener algún estado del objeto actual. En los lenguajes OOP, este es el valor de alguna variable de clase, generalmente privada.

class Article {
     private String name

     public function getName(): String {
          return this.name
     }
}

El valor de la variable de clase en sí se puede obtener como lo desee. Simplemente le pedimos al objeto que nos dé lo que es, el mismo nombre del método nos dice "dar": pero no "hacer", no "enviar", no "crear", no "contar". Dice dar, dar lo que es. Esto funciona normalmente en todo tipo de objetos de datos, cuya responsabilidad es simplemente dar / transportar información.

No puede haber lógica en el captador, porque la semántica de la palabra es sencilla. "Mamá, dame un pastel " no contiene "Mamá, compra harina, dispara un pastel y finalmente dame un pastel ". Tal vez la frase "proporcionarme un pastel" de alguna manera puede encapsular todas estas acciones, pero definitivamente no es "dar".

Te sorprenderás, pero he conocido esta forma de nombrar todos los métodos más de una vez. La complejidad del código al mismo tiempo crece bastante, porque en las cadenas getter no siempre está claro qué está sucediendo exactamente en las capas de la aplicación y qué tipo de conexiones están involucradas, por regla general, no todo está en orden con el diseño y la connivencia de este tipo es una fuente de errores.

getValue () throw WhyDoYouNeedIt? {}


El propósito del objeto de datos es comprensible: este es el cabo de la película de 1917, que huye a algún lugar para transmitir algún mensaje sobre la necesidad de retirarse.

¿Pero qué hacer con los objetos comerciales? ¿Por qué la entidad "Documento" le da a alguien una lista de sus campos?

Si se trata de un objeto comercial, el documento se puede publicar, rechazar, verificar (incluso en estos campos), completar o confirmar.

Si es necesario "dar" el campo, entonces este documento no es parte del proceso comercial. ¿Por qué necesito darle un campo a alguien? Tal vez para su publicación? ¿O extraer, archivar o enviar una copia por correo o informe? No está del todo claro por qué y para quién: hay una responsabilidad separada de "dar" como la de un buen objeto de datos antiguo, puede ver claramente el uso en forma de alguna fuente para leer en el contexto de otro proceso comercial que no es básico para comprender el documento en sí.

doEverythingEverywhere (world.getGod ())


Volver a las entidades comerciales. Si dejas a los captadores en entidades, entonces la tentación es genial para usar sus captadores exactamente en todas partes y como quieras. Estamos atados al estado de cierto objeto y revertimos absolutamente cualquier lógica a la campaña. Incluso puede parecer que no hemos roto la encapsulación. ¿Pero que pasa? Estado en un lugar, comportamiento en otro: una violación clásica de encapsulación.

Por ejemplo, hay alguna entidad:

class Order
{
     private Status status
     private Boolean closed

     public function getStatus(): Status {
          return this.status
     }

     public function setClosed(Boolean closed): void {
           this.closed = closed
     }
}

Seguramente, con tal arquitectura, solicitará un estado en una docena / cien lugares. Puede ser todo tipo de servicios, controladores, otros módulos. Solo vi una vez cuando se crearon restricciones artificiales para la distribución de este código mediante algún conjunto de reglas para desarrolladores, no código ... La encapsulación fue proporcionada por estándares de codificación, y no por diseño de código :).

Si necesita hacer algo como esto en alguna parte:

if(order.getStatus() == input.getStatus()) {
      order.setClosed(true)
}

Lo más probable es que la entidad no contenga una máquina de estados. Esto significa que los invariantes del objeto desde el interior no se controlan de ninguna manera; no hay verificación de datos durante cada operación desde el interior. Como resultado: alta conectividad, pruebas funcionales complejas, ya que no es suficiente verificar la lógica de la unidad del código que cambia el estado de la entidad, debe verificar que el estado de la entidad externa al código sea válido. Y como resultado: mayor complejidad, probabilidad de errores, más código y pruebas complejas.

En pocas palabras: espero que mis colegas y usted usen getters menos que cualquier método que funcione con el resultado que arrojará.

Y espero que más desarrolladores presten atención al concepto CQRS, donde las responsabilidades de lectura y operaciones comerciales se dividen.

Bueno para todos!

All Articles