2010-09-17 29 views
5

Recientemente leí el libro de Michael C. Feathers Working effectively with legacy code y encontré el punto donde mencionó una forma de probar la seguridad de las herramientas de refactorización automáticas.¿Hay alguna herramienta de refactorización segura para .net (o al menos C#)?

Mi pregunta es: ¿Existen herramientas de refactorización seguras para la plataforma .net?; eso significa herramientas que solo permiten refactorizaciones reales y p. no permita la refactorización inline variable en la variable temp en el siguiente ejemplo, o al menos muestre una advertencia de que estoy cambiando la lógica.

class Program 
{ 
    private static int _x; 

    static void Main() 
    { 
     int temp = Test(); 
     for (int i = 0; i < 10; ++i) 
     { 
      Console.WriteLine(temp); 
     } 
     Console.ReadKey(); 
    } 


    private static int Test() 
    { 
     return ++_x; 
    } 
} 

He probado este ejemplo en las herramientas de refactorización Resharper y Coderush + Refactor pro con las últimas versiones y ambos fallaron la prueba y deja que la refactorización a:

class Program 
{ 
    private static int _x; 

    static void Main() 
    { 
     for (int i = 0; i < 10; ++i) 
     { 
      Console.WriteLine(Test()); 
     } 
     Console.ReadKey(); 
    } 

    private static int Test() 
    { 
     return ++_x; 
    } 
} 
+0

¿Tiene un ejemplo de una herramienta que se * * realizar la forma que desee, incluso para un idioma diferente? –

+1

En realidad, me gustaría que la herramienta no ofrezca esta refactorización en particular o mostrar algún tipo de alerta que esto podría cambiar la lógica del código. Debido a que una refactorización no debe cambiar la lógica, consulte la definición en wikipedia: http://en.wikipedia.org/wiki/Refactoring. – RoXX

Respuesta

5

Para estar realmente seguro con refactorizaciones automatizadas es muy difícil.

Cuando presentamos refactorizaciones por primera vez en Visual C#, nos hicimos esta pregunta: ¿nuestras refactorizaciones deben estar completamente correctas todo el tiempo, o deberíamos permitir que cometan errores en ciertos casos?

Tener razón todo el tiempo requeriría mucho esfuerzo del programador, lo que significa que solo obtendríamos algunas refactorizaciones en la caja. También haría que las refactorizaciones fueran lentas, ya que pasarían mucho tiempo en la validación.

Permitirles que cometan errores los haría inútiles para los equipos que no tenían una gran cobertura de prueba automatizada. Los equipos de TDD tienen buenas pruebas, pero eso es solo una parte de la base de usuarios de Visual Studio. ¡No queríamos hacer funciones que teníamos que decirle a la gente que no usara!

Los equipos de TDD detectarían los errores rápidamente, pero aprenderían igual de rápido a no confiar en nuestras herramientas de refactorización. Ellos dudarían en usarlos, y buscarían otras soluciones la mayor parte del tiempo (buscar y reemplazar en lugar de Renombrar).

Además, como equipo de C#, estábamos en una buena posición para realizar refactorizaciones de alta fidelidad. Tuvimos una ventaja única, con los diseñadores de lenguaje C# y el equipo de compilación al final del pasillo. Sabíamos que deberíamos jugar con nuestras fortalezas.

Por lo tanto, decidimos hacer menos refactorizaciones de alta calidad, en lugar de muchas refactorizaciones que no eran tan confiables. Hoy en día hay 6.

Visual Studio Refactorings

Mirando hacia atrás, me gustaría que sólo había hecho Renombrar, Extraer método, e introducir la variable local. Esos dos últimos son casi los mismos, según la implementación. Las 3 refactorizaciones de Parámetros (solía haber un 7mo, Promover Variable Local a Parámetro, pero fue cortado en VS2010) fueron mucho trabajo para hacer las cosas bien, y probablemente no valieron la pena.

Mi recomendación es hacer TDD, que le ofrece una gran colección de pruebas para que pueda refactorizar con seguridad, ya sea que utilice una herramienta o lo haga a mano.

10

Refactoring es inherentemente arriesgada. Confiar exclusivamente en una herramienta para hacer que su código sea seguro es imprudente.

Usamos Resharper pero no sin la red de seguridad de las pruebas unitarias integrales. No conozco ninguna herramienta de C# mejor en este espacio.

+1

Estoy de acuerdo en el punto de que siempre debe tener pruebas unitarias para cubrir su refactorización, pero en realidad si tuviera una herramienta que solo permite refactorizaciones seguras, podría, por ejemplo, aplique algunas refactorizaciones básicas antes de agregar pruebas unitarias al código heredado o para hacer que el código sea comprobable, lo que lo haría más productivo. – RoXX

+2

La refabricación * no debe * ser intrínsecamente arriesgada desde el punto de vista de la funcionalidad. Esto simplemente demuestra que las herramientas no son lo suficientemente fuertes como para hacer la verificación, por lo que los fabricantes de herramientas las ofrecen sin la verificación necesaria. El comprador tenga cuidado. (No me malinterprete: es * difícil * implementar todas las comprobaciones necesarias: necesita lo que equivale a la parte frontal completa de un compilador). –

2

"seguro" es bastante subjetiva ....

Si bien esas dos herramientas que no sea ser considerados "seguros" en base a esta prueba en su mente tanto de esas herramientas son de gran utilidad. Ninguna herramienta es perfecta. Si hay una situación en la que hacen algo que no te gusta, evita hacerlo o crea un trabajo alternativo.

5

No estoy de acuerdo con que su "prueba" muestre un error.

USTED cambió la lógica, no la herramienta. Cambió el código de modo que se llamaría un método repetidamente en lugar de una vez.

Las herramientas simplemente hicieron lo que les dijo que hicieran.

+0

Sí. Es por eso que debe probar su código después de cada refactorización para que * sepa * cuando cambie la lógica. – strager

+0

Aceptaría la declaración de OP si la herramienta realmente introdujera el error, como usar una refactorización de la sentencia if invertida que produjera un resultado lógico diferente. –

+2

En realidad, utilicé la HERRAMIENTA para aplicar una refactorización, que no era una refactorización. La definición de refactorización es cambiar el código sin modificar su comportamiento, pero la herramienta modificó algunos comportamientos, por lo que no debería llamar a esta funcionalidad refactorización. Por supuesto, tener pruebas unitarias para cubrir esto siempre es lo mejor, pero en realidad sería más productivo si pudiera aplicar estas refactorizaciones automáticas sin tener que preocuparse por romper la funcionalidad existente – RoXX

Cuestiones relacionadas