Post Top Ad

Your Ad Spot

viernes, 11 de septiembre de 2020

Cómo refactorizar el código a una clase dedicada

 Cómo refactorizar con PHPStorm


En este tutorial vamos a aprender todo sobre cómo refactorizar con PHP Storm. Durante el curso de la construcción de nuestra aplicación, a menudo encontramos que los métodos en nuestros controladores comienzan a expandirse en tamaño. A medida que surge la necesidad de aplicar más y más lógica, no queremos que nuestros métodos se vuelvan tan complicados que resulten difíciles de leer y razonar. En este tutorial, intentaremos refactorizar algunos códigos para que sean más agradables de leer y trabajar con el controlador, sin dejar de mantener la misma funcionalidad de la aplicación.


Refactorización del método ThreadsController @ index ()

Este es el método que queremos refactorizar.


Crear una clase de filtrado

Nuestro objetivo aquí es crear una nueva clase de filtrado que hará el trabajo pesado por nosotros, y luego simplemente inyectamos esa clase en nuestro método o controlador y llamamos a un método o métodos simples según sea necesario. Entonces, lo que vamos a hacer es crear un nuevo directorio dentro del appdirectorio llamado FiltersEn el nuevo directorio de Filtros crearemos un nuevo archivo llamado ThreadFilters.php y comenzaremos con un shell vacío de una clase como esta:


Imaginando tu API

Ahora podemos comenzar a experimentar cómo nos gustaría interactuar con esta clase en nuestro controlador. Aquí hay un comienzo y podemos examinar la idea:

Lo que queremos hacer es inyectar una clase en nuestro método y luego pasarla a un alcance de consulta en el modelo Thread. A continuación, el modelo Thread aplicará de forma inteligente los alcances y filtros según sea necesario y nos dará los resultados que queremos.


Cree el código de apoyo

Para poder llamar a esos métodos anteriores, necesitamos el código detrás de ellos en su lugar. Primero, agreguemos un método filter () al modelo Thread. Continúe y abra Thread.php y agregue el siguiente método al final de la clase:

Este es nuestro alcance de consulta, donde aceptamos la consulta y los filtros. Luego devolvemos la consulta aplicada desde dentro de la función. Bien, ese método apply () aún no existe en nuestra clase ThreadFilters, por lo que tendremos que crearlo. Abra ThreadFilters.php y configure este código:


Ejecutar pruebas después de la refactorización

A medida que refactoriza su código, desea ejecutar sus pruebas de vez en cuando para ver dónde pueden fallar las cosas. En este punto, todo está pasando, por lo que este ha sido un buen refactor hasta ahora.

vagabundo @ homestead: ~ / Código / forumio $ phpunit
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

..................... 21/21 (100%)

Tiempo: 2,91 segundos, memoria: 12,00 MB

OK (21 pruebas, 37 afirmaciones)

Extraer un método

Podemos usar PHP Storm para extraer automáticamente un método para nosotros. Lo que haremos con este refactor es tomar parte del código dentro del método apply () y extraerlo a su propio método. En PHP Storm, puede resaltar el código que le gustaría extraer a un método y hacer clic derecho. En el submenú que aparece, elija Refactor-> Extraer-> Método.
método de extracción de phpstorm refactor

En este punto, ahora tiene la oportunidad de nombrar su método y elegir la visibilidad del mismo. Nombraremos nuestro método extraído 'por' y configuraremos la visibilidad como protegida.
método de nombre phpstorm elegir visibilidad

Aquí está el formulario de código generado PHP Storm resaltado a continuación. Esta es una característica realmente agradable de PHP Storm IDE, ya que hace parte del trabajo pesado por usted al refactorizar.


Asignar $ builder al objeto

Sigamos refactorizando. Tanto en el método apply () como en el método by (), se envía $ builder, pero podríamos asignarlo al objeto, lo que podría hacerlo un poco más legible. Una vez más, podemos usar PHP Storm para ayudarnos con esto. Aquí asignamos $ constructor al objeto y luego hacemos clic en constructor. En ese punto, si hace clic alt + Enteren PHP Storm, puede agregar el campo a la clase que también completamos aquí.
asignar campo al objeto

Una vez que se asigna $ builder al objeto, nuestro código se puede actualizar así. Los cambios que notamos son los siguientes.

  • $ builder ahora es un campo protegido de la clase.
  • $ builder en sí ya no se pasa como argumento al método by ().
  • En el método by () ahora hacemos referencia al constructor usando $ this-> builder

Las líneas resaltadas muestran dónde tiene un impacto este refactor.


Verificando si la solicitud tiene 'por'

Ahora agregaremos algo de lógica al método apply () para verificar si la solicitud que se realiza contiene el 'by' en la cadena de consulta . Si está en la cadena de consulta, aplicaremos ese filtro.


Cómo utilizar una clase principal abstracta

Ahora realmente te vamos a volar los calcetines. Haremos uso de una clase abstracta para eliminar el código que podría reutilizarse en múltiples escenarios, así como hacer que la clase secundaria sea más liviana. Podemos poner las cosas repetitivas en la clase abstracta. Entonces, dentro del directorio Filters, usemos PHP Storm para crear una nueva clase PHP.
phpstorm crea una nueva clase php

Deberá agregar manualmente la palabra clave abstracta, pero aquí vamos con nuestra nueva clase de filtros abstractos.


Usando PHP Storm para levantar miembros

Ahora que tenemos una clase principal abstracta (Filtros) podemos visitar la subclase que en este caso será ThreadFilters.php y hacer que extienda su clase principal. Una vez que defina la definición de la clase ThreadFilters extends Filters, puede hacer clic en el campo de solicitud y abrir el menú 'refactorizar esto'. En la versión de Windows, esto se hace haciendo clic en Ctrl+Alt+Shift+TSi eso es demasiado para recordar, haga clic derecho y elija Refactor-> Pull Members Up.
php storm refactoriza esto

Selección de los miembros a levantar.
seleccionar miembros para levantar


PHP Storm crea automáticamente la clase abstracta para usted

Ahora que ha utilizado PHP Storm para extraer miembros, todo ese código reutilizable se ha transferido automáticamente a la clase abstracta principal de Filters.php, mientras que la subclase de ThreadFilters.php se ha limpiado considerablemente.

Aquí está la clase ThreadFilters agradable y limpia.

Y aquí está la clase principal abstracta que PHP Storm esencialmente creó para usted.


Refactorización adicional en la clase abstracta

En primer lugar, agregaremos un campo en la clase ThreadFilters que es una matriz. Esa matriz contendrá varias cadenas de lo que queremos filtrar. La clase principal también necesitará un campo que defina una matriz vacía.

Ahora viene la parte algo más complicada. Queremos eliminar el filtro codificado "por" del método apply (). Ahora queremos tener la capacidad de elegir entre una variedad de tipos de filtros. Entonces, lo que configuramos es un bucle foreach en el que recorremos cada filtro posible, y si hay un método para ese filtro, lo activamos con el valor del filtro. El código resaltado está aquí para reflejar eso.

Esto se ve bastante bien y las pruebas están pasando. ¿Qué más se puede refactorizar? Bueno, el código dentro del condicional if es un poco extraño, así que extraigamos eso a un método protegido en la clase. Continúe y use PHP Storm nuevamente para hacer el trabajo por usted.
refactorizar al método protegido en phpstorm

¡Mira tu método extraído ahora! Dentro del método apply () hacemos una simple llamada a hasFilter () y todo sigue funcionando. El trabajo pesado se traslada al método protegido que PHP Storm creó para nosotros y se destaca a continuación.


Acorte su bloque if () con una declaración de devolución

Aquí hay otra refactorización que podría hacer. Puede convertir la declaración if que ve arriba en algo como esto:


Protéjase con solo ()

Como probablemente sepa, los usuarios de Internet intentarán piratear cadenas de consulta y enviar datos incorrectos a su aplicación. Entonces, ¿cómo te proteges de eso? Bueno, ahora mismo, veamos cómo funciona esto. Vamos a agregar una declaración dd () al método apply () de esta manera:

Ahora podemos probar las cadenas de consulta en el navegador. Si visitamos http://forum.io/threads?by=asdf en el navegador, vemos que la matriz de filtros se completa como esperábamos.
buena cadena de consulta

¿Qué pasaría si obtuviéramos la solicitud con el método all () de esta manera $ this-> request-> all () y un usuario intenta un ataque de piratería visitando algo como esto http://forum.io/threads?by= asdf & hacker = attack Bueno, en ese caso, tendríamos un problema.
cadena de consulta incorrecta

En ese momento, aceptará esos datos incorrectos directamente en su aplicación. Vemos esa evidencia arriba, y eso es algo que queremos evitar.

Con nuestro nuevo conocimiento sobre el método only (), usémoslo en nuestro ciclo foreach en el método apply (). También tenga en cuenta que, dado que estamos recorriendo una matriz de pares clave-valor, también debemos incluir $ value en foreach () como vemos aquí.

También hagamos otra refactorización para limpiar ese código dentro del condicional if.
refactorizar este método

Nombrar el método extraído para getFilters ()
extraer la vista previa de la firma del método


Eliminando el método hasFilter ()

A medida que avanzamos en la refactorización, parece que ahora podríamos eliminar el método hasFilter (). Simplemente actualizaremos el método apply () para manejar esto. Básicamente ahora, mientras recorremos los filtros, verificamos si existe un método en el objeto con el mismo nombre que el filtro, y si es así, el disparador es al pasar por el filtro.

Con ese factor, ahora podemos eliminar este fragmento de la clase.


Una refactorización final en el método ThreadsController @ index

Recuerde, toda esta refactorización comenzó porque queríamos hacer que el método index () fuera más simplificado en ThreadsController. Revisemos ese método una vez más y limpiemos un poco más.

Aquí está el estado actual del método

Y aquí hay una refactorización más optimizada del mismo código

Lo último que haremos es ir aún más lejos y extraer un método más de este código para que nuestro método index () final sea lo más simple posible.
refactorizar esta opción 7

Nombre el método extraído
parámetro protegido del método de refactorización


El resultado final

Uf. Siento que mi cerebro va a explotar. En cualquier caso, esta fue la versión larga de cómo puede usar la refactorización para pasar de este código

Todo el camino hasta este código aquí


Cómo refactorizar el código en un resumen de clase dedicado

Se necesita algo de tiempo y muchas pruebas de ejecución sobre la marcha. Para ser justos, phpunit se estaba ejecutando en segundo plano casi constantemente durante todo este tutorial. Omitimos algo de eso solo por brevedad. La conclusión aquí es que si desea mantener limpio el código de su controlador, deberá poder apoyarse en las pruebas que ha creado y seguir refactorizando hasta que tenga una API que le guste mientras continúa manteniendo todas sus pruebas en un estado pasajero. Una vez que ambos estén bajo control, ¡su refactorización estará completa!

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

outbrain

Páginas