Extract Method
Cuando un método se torna demasiado largo hay muchas posibilidades de poder separar parte del mismo en un nuevo método y hacer una llamada a este método.La manera de abordar un refactor con «Extract Method» es:
- Encontrar una parte del código que tenga sentido por si sola en su propio método. Los bloques de los bucles, los bucles completos, los bloques de los condicionales son unos buenos candidatos.
- Hay que verificar que no se hagan asignaciones a variables temporales que estén declaradas fuera de la visibilidad del la región que se va a extraer.
- Copiar el código del método al nuevo método.
- Por cada variable temporal o parámetro del método original que se usa en el nuevo método hay que añadir un parámetro al nuevo método.
- Hacer la llamada del nuevo método desde el método original.
Los IDE actuales son capaces de hacer este trabajo por ti así que trata de usar su funcionalidad para ahorrar tiempo.
Esta refactorización se utiliza para tratar de entender un código complicado. Separar el código en funciones con nombres descriptivos hace más fácil entender que está haciendo ese código.
También se utiliza para eliminar la duplicación que puede darse en varias partes del código de manera que se pueda reutilizar este bloque.
Habrá momentos que se llevará al extremo hacer «Extract Method» no viendo una manera clara de continuar. En estos casos se puede usar la refactorización contraria «Inline Method» para deshacer la refactorización y volver a empezar con «Extract Method».
Inline Method
Es el paso contrario a «Extract Method». En las ocasiones en las que tiene más sentido que el código esté en el método desde que se hace la llamada.
Los pasos a seguir son:
- Copiar el método.
- Pegar el contenido del método sobre la llamada.
- Reemplazar todo los parámetros con los parámetros que se usen dentro del método al cual se está copiando.
Extract Interface
Para introducir una segunda implementación de una operación se crea una interfaz que contenga definidas las operaciones.Para llevar a cabo la refactorización:
- Se declara una interfaz. A veces el nombre coincide con el de la case que existe en cuyo caso habría que renombrar la clase.
- La clase que existe debe implementar la nueva interfaz.
- Hay que definir en la interfaz aquellos métodos que sean necesarios.
- Cambiar las declaraciones de tipo de la clase a la interface cuando sea posible.
Cuando se necesita un refactorizar con «Extract Method» es porque se necesita una segunda implementación. Por ejemplo, si se tiene una clase «Rectangle» y quiere añadir un Oval, entonces puedes crear una interface «Shape» que defina los métodos de «Rectangle».
Move Method
Si un método pertenece realmente a otra clase habría que moverlo a la nueva clase e invocarlo desde donde se utilice.
Los pasos para hacer el refactor:
- Copiar el método.
- Pegar el método en la clase objetivo.
- Si el método tiene referencias al objeto original entonces hay que pasar el objeto como parámetro. Si hay referencia a variables del objeto original entonces son estas las que se pasan como parámetro. Si se asignan variables del objeto original entonces se debería parar y no hacer esta refactorización.
- Reemplazar el cuerpo del método original con una invocación al nuevo método.
Por ejemplo, calcular el área es responsabilidad de «Shape».
Cada vez que se ve más de un mensaje a otro objeto en un método hay que sospechar. En este caso hay cuatro llamadas a distintos métodos de «$bounds» por lo que se debería mover esta parte del método a la clase «Rectangle».
Y desde el método original se hace la llamada a este nuevo método.
Las tres grandes propiedades de «Extract Method» son:
- Es fácil de ver sin necesidad de tener un conocimiento profundo de la lógica. Si se ven dos o más mensajes a un objeto es el momento de aplicarlo.
- Los pasos para hacer el refactor son rápidos y seguros.
- A veces los resultados son reveladores. “Pero los Rectángulos no hacen cálculos … Oh! Espera. Esto es mejor.”
A veces sólo se querrá mover una parte del método por lo que habrá que usar primero «Extract Method» y move el método.
Method Object
Cuando un método se complica tanto como para tener varios parámetros y variables locales se puede hacer un objeto que absorba la funcionalidad de este método.Los pasos para refactorizar con «Method Object» son:
- Crear un objeto con los mismos parámetros que el método.
- Crear tantos atributos como variables locales.
- Crear un método llamado «run()» cuyo contenido sea el mismo que el contenido del método original.
- En el método original crear un nuevo objeto y hacer una llamada al método «run()».
Las refactorizaciones «Method Object» son útiles ya que permiten añadir un nuevo tipo de lógica al sistema. Por ejemplo, se pueden tener varios métodos para calcular el flujo de efectivo en un componente para el cálculo de estos flujos. Se puede practicar una refactorización de estos métodos con «Method Object». También se puede escribir un nuevo tipo de cálculo con sus propias pruebas y con lo que conectarlo será un sólo paso.
Los «Method Object» también son buenos para simplificar el código al que no se puede aplicar la refactorización «Extract Method». En ocasiones habrá un bloque de código que al aplicar «Extract Method» nos encontremos con una función con demasiados parámetros y el aspecto de esta no es mucho mejor que el código original. En este caso, crear un nuevo objeto da un nuevo espacio el cual puede albergar las variables locales sin tener que pasar nada.
Add Parameter
Pues sí, «Add Parameter» es un tipo de refactorización:
- Si el método es de una interfaz entonces se añade el parámetro a la interfaz.
- En los lenguajes compilados habrá errores que adviertan del código que se necesita cambiar. Si no habrá que usar las funcionalidades del IDE para buscar aquellos lugares.
Añadir un parámetro es a veces un paso de extensión. Primero se tiene el primer caso ejecutándose sin necesidad de parámetros para más tarde, pasar un parámetro que añade más información para realizar la operación correctamente.
Añadir un parámetro puede ser parte de una migración una representación de un dato a otro. Primero se añade el parámetro, entonces se borra todos los usos del parámetro viejo y después el parámetro viejo.
Method Parameter to Constructor Parameter
Mover parámetros de un método o métodos al constructor es otra manera de refactorizar.
Los pasos son:
- Añadir un parámetro al constructor.
- Añadir un atributo con el mismo nombre que el parámetro.
- Asignar valor del parámetro al atributo en el constructor.
- Cambiar todas las referencias del parámetro en el método por referencias al atributo.
- Cuando ya no haya más referencias al parámetro se borra el parámetro de la firma del método y todos los que hacen la llamada.
En los casos en los que el mismo parámetro se pasa en diferentes métodos dentro del mismo objeto se puede simplificar la API pasando el parámetro una sóla vez (eliminando la duplicación). Esta refactorización se puede aplicar de forma inversa si se encuentra con que un atributo sólo se utiliza en un método.