CK calcula las métricas de código de nivel de clase y de nivel de método en proyectos Java mediante análisis estático (es decir, no es necesario que el código compilado). Actualmente, contiene un gran conjunto de métricas, incluida la famosa CK:
CBO (acoplamiento entre objetos) : cuenta el número de dependencias que tiene una clase. Las herramientas verifican cualquier tipo utilizado en toda la clase (declaración de campo, tipos de devolución de métodos, declaraciones variables, etc.). Ignora las dependencias a Java (por ejemplo, java.lang.string).
CBO modificado (acoplamiento entre objetos) : cuenta el número de dependencias que tiene una clase. Es muy similar al CBO original del CKTool. Sin embargo, esta métrica considera que una dependencia de una clase es ambas referencias que el tipo hace a otros y las referencias que recibe de otros tipos.
Fan-In : cuenta el número de dependencias de entrada que una clase tiene, es decir, el número de clases que hacen referencia a una clase en particular. Por ejemplo, dada una Clase X, el Fan-In de X sería el número de clases que llaman a X haciendo referencia a ella como un atributo, accediendo a algunos de sus atributos, invocando algunos de sus métodos, etc.
Fan-Out : cuenta el número de dependencias de salida que una clase tiene, es decir, el número de otras clases a las que se hace referencia una clase en particular. En otras palabras, dada una Clase X, la ventiladora de X es el número de clases llamadas por X a través de atributos Referencia, invocaciones de métodos, instancias de objetos, etc.
Dit (árbol de herencia de profundidad) : cuenta el número de "padres" que tiene una clase. Todas las clases tienen al menos 1 (todos heredan java.lang.object). Para que esto suceda, las clases deben existir en el proyecto (es decir, si una clase depende de x que se basa en un archivo jar/dependencia, y x depende de otras clases, DIT se cuenta como 2).
NOC (número de niños) : cuenta el número de subclases inmediatas que tiene una clase en particular.
Número de campos : cuenta el número de campos. Números específicos para el número total de campos, estáticos, públicos, privados, protegidos, predeterminados, finales y sincronizados.
Número de métodos : cuenta el número de métodos. Números específicos para el número total de métodos, estáticos, públicos, abstractos, privados, protegidos, predeterminados, finales y sincronizados. Los métodos de constructor también cuentan aquí.
Número de métodos visibles : cuenta el número de métodos visibles. Un método es visible si no es privado.
NOSI (número de invocaciones estáticas) : cuenta el número de invocaciones a los métodos estáticos. Solo puede contar los que pueden ser resueltos por el JDT.
RFC (respuesta para una clase) : cuenta el número de invocaciones de métodos únicos en una clase. Como las invocaciones se resuelven mediante análisis estático, esta implementación falla cuando un método tiene sobrecargas con el mismo número de parámetros, pero diferentes tipos.
WMC (clase de método de peso) o complejidad de McCabe . Cuenta el número de instrucciones de rama en una clase.
LOC (líneas de código) : cuenta las líneas de recuento, ignorando las líneas y comentarios vacíos (es decir, sus líneas de código o SLOC). El número de líneas aquí puede ser un poco diferente del archivo original, ya que utilizamos la representación interna de JDT del código fuente para calcularlo.
LCOM (falta de cohesión de métodos) : calcula la métrica LCOM. Esta es la primera versión de Metric, que no es confiable. LCOM-HS puede ser mejor (con suerte, nos enviará una solicitud de extracción).
Lcom* (falta de cohesión de métodos) : esta métrica es una versión modificada de la versión actual de LCOM implementada en la herramienta CK. Lcom* es una métrica normalizada que calcula la falta de cohesión de la clase dentro de un rango de 0 a 1. Entonces, cuanto más cerca de 1 el valor de lcom* en una clase, menos es el grado de cohesión de esta clase respectiva. Cuanto más cerca de 0 el valor de lcom* en una clase, la mayoría de la cohesión de esta clase respectiva. Esta implementación sigue la tercera versión de LCom* definida en [1].
TCC (cohesión de clase estrecha) : mide la cohesión de una clase con un rango de valor de 0 a 1. TCC mide la cohesión de una clase a través de conexiones directas entre métodos visibles, dos métodos o sus árboles de invocación acceden a la misma variable de clase.
LCC (cohesión de clase suelta) : similar a TCC, pero además incluye el número de conexiones indirectas entre las clases visibles para el cálculo de la cohesión. Por lo tanto, la restricción LCC> = TCC se mantiene siempre.
Cantidad de devoluciones : el número de instrucciones return .
Cantidad de bucles : el número de bucles (es decir, para, mientras que lo hace mientras, mejoró).
Cantidad de comparaciones : el número de comparaciones (es decir, == y! =). Nota:! = Solo está disponible en 0.4.2+.
Cantidad de try/capturas : el número de try/capturas
Cantidad de expresiones entre paréntesis : el número de expresiones dentro de la paréntesis.
Literales de cadena : el número de literales de cadena (por ejemplo, "John Doe" ). Las cuerdas repetidas cuentan tantas veces como aparecen.
Cantidad de número : el número de números (es decir, int, largos, dobles, flotación) literales.
Cantidad de operaciones matemáticas : el número de operaciones matemáticas (tiempos, divide, resto, más, menos, mierda izquierda, cambio derecho).
Cantidad de variables : número de variables declaradas.
Bloques anidados máximos : el mayor número de bloques anidados juntos.
Cantidad de clases anónimas, clases internas y expresiones lambda : el nombre lo dice todo. Tenga en cuenta que cada vez que se declara una clase anónima o una clase interna, se convierte en una "clase nueva nueva", por ejemplo, CK genera AB y AB $ C, C es una clase interna dentro de AB Sin embargo, las expresiones lambda no se consideran clases y, por lo tanto, son parte de la clase/método en la que se incrustan. Una clase o un método solo tiene el número de clases internas que se declaran a su nivel, por ejemplo, una clase interna que se declara dentro de un método M2, que se encuentra dentro de una clase A anónima, que se declara dentro de un método M, que finalmente se declara dentro de una clase C, no se contará en la Clase C, pero solo en el método M2 (el método de primer nivel, está incorporado), y la clase ANIMONDIA de la primera A (la clase de primer nivel, está en la clase Velvel It It It It).
Número de palabras únicas : número de palabras únicas en el código fuente. A nivel de método, solo usa el cuerpo del método como entrada. A nivel de clase, utiliza todo el cuerpo de la clase como métricas. El algoritmo básicamente cuenta el número de palabras en un método/clase, después de eliminar las palabras clave Java. Los nombres se dividen en función de Camel Case and Subline (por ejemplo, LongName_Likethis se convierte en cuatro palabras). Consulte la clase WordCounter para obtener detalles sobre la implementación.
Número de declaraciones de registro : Número de declaraciones de registro en el código fuente. El conteo usa reglas compatibles con las llamadas de API SLF4J y LOG4J. Consulte NumberOfLogStatements.java y los ejemplos de prueba ( NumberOfLogStatementsTest y fixtures/logs ) para obtener más información.
Tiene javadoc : booleano que indica si un método tiene javadoc. (Solo a nivel de método por ahora)
Modificadores : público/abstracto/privado/protegido/modificadores nativos de clases/métodos. Se puede decodificar usando org.eclipse.jdt.core.dom.Modifier .
Uso de cada variable : con qué frecuencia se usó cada variable dentro de cada método.
Uso de cada campo : con qué frecuencia se usó cada campo local dentro de cada método, el campo local son campos dentro de una clase (no se incluyen subclases). También se detectan usos de campo locales indirectos, los usos de campo locales indirectos incluyen todos los usos de campos dentro del árbol de invocación local de una clase, por ejemplo, A invoca B y B usa el campo A, entonces A es utilizado indirectamente por A.
Invocaciones de métodos : todos los métodos invocados directamente, las variaciones son invocaciones locales e invocaciones locales indirectas.
Nota: CK separa clases, clases internas y clases anónimas. LOC es la única métrica que no está completamente aislada de los demás, por ejemplo, si A tiene una declaración de una clase interna B, entonces LOC (A) = LOC (Clase A) + LOC (Clase Interior B).
CK es una herramienta de colección de métricas de código Java, simplificado en una estructura simple que gira en torno a tres paquetes principales:
Para la brevedad, dentro de esta documentación, se omiten los prefijos de paquetes como com.github.mauricioaniche.ck .
CK administra la orquestación de todo el proceso de recolección de métricas. Inicializa a los buscadores de métricos, maneja la partición de archivos basada en la memoria disponible, establece los analizadores AST con la configuración del entorno apropiado y gestiona el flujo de ejecución en diferentes directorios y dependencias de JAR. Ajusta dinámicamente su comportamiento en función de las entradas de los usuarios como useJars , maxAtOnce y variablesAndFields para optimizar el procesamiento de archivos Java para la recopilación de métricas.ck . Esta clase procesa argumentos de línea de comandos para configurar y iniciar el proceso de recopilación de métricas. Maneja la entrada del usuario para la ruta del proyecto, la inclusión JAR, la partición de archivos, los detalles de métricas y la configuración del directorio de salida. Runner orquesta la ejecución general inicializando y utilizando la clase CK y manejo de la salida de resultados a través de ResultWriter .FileASTRequestor , un componente del núcleo de Eclipse JDT (herramientas de desarrollo Java). Desempeña un papel fundamental en el marco CK al orquestar el proceso de recolección de métricas. El MetricsExecutor coordina la creación del árbol de sintaxis abstracto (AST) para archivos fuente Java, que es esencial para analizar y extraer métricas de código. Metricsfinder: esta clase de utilidad, ubicada en ck.utils , juega un papel crucial en la identificación dinámica e instanciación de las clases de coleccionistas métricos dentro del marco CK. Se dirige a clases que implementan las interfaces ClassLevelMetric y MethodLevelMetric del paquete metrics .
MetricsFinder utiliza la biblioteca Reflections para escanear y cargar clases de coleccionistas métricos en tiempo de ejecución, lo que permite que el sistema CK sea extensible y adaptable a nuevas métricas sin requerir modificaciones a la arquitectura central. Esta característica es particularmente útil para integrar métricas personalizadas en el proceso de análisis sin problemas.
CKVisitor: un componente integral del marco CK, CKVisitor extiende la clase ASTVisitor proporcionada por la biblioteca Eclipse JDT (Java Development Tools), que permite un análisis detallado y una colección métrica directamente del árbol de sintaxis abstracto del código de origen de Java (AST).
El visitante está diseñado para atravesar varios nodos de la AST, como tipos y métodos, y aplicar acciones específicas en cada nodo. Gestiona efectivamente una jerarquía de clases y métodos basados en la pila, lo que permite calcular y recolectar métricas en el contexto del alcance del nodo actual.
CKASTVISITOR: Implementado por clases de métricas en ck.metrics , lo que permite que cada métrica maneje nodos de interés AST específicos, como invocaciones de métodos y creaciones de instancias de clase.
ClassLevelMetric y MethetLevelMetric: Interfaces Definición de métodos para recopilar métricas a nivel de clase y a nivel de método, respectivamente.
CKNotifier .CKClassResult y CKMethodResult con los datos recopilados.CK Framework incorpora una serie de patrones de diseño bien establecidos para mejorar la modularidad, la extensibilidad y la mantenimiento de su base de código. Estos patrones permiten que el marco maneje eficientemente operaciones complejas, como atravesar árboles de sintaxis abstractos (AST), recolectar métricas y notificar los resultados. A continuación se presentan los patrones de diseño clave utilizados:
Patrón de visitantes: las interfaces CKVisitor y CKASTVisitor implementan el patrón de visitantes, que es fundamental en las operaciones de manejo de varios nodos AST sin alterar las clases de los elementos en los que opera. Este patrón es especialmente beneficioso en escenarios en los que un componente necesita realizar operaciones distintas y no relacionadas en una jerarquía de clase de nodos AST. Simplifica el código externalizando la lógica operativa en objetos de visitantes, facilitando la adición fácil de nuevas operaciones sin modificar las clases de nodos existentes. Esta separación de preocupaciones conduce a una base de código más mantenible y extensible, donde las estructuras y operaciones de nodo AST se desacoplan.
Patrón de notificador: CK adopta el patrón de notificador mediante el uso de CKNotifier , que actúa como un mecanismo central para transmitir los resultados de la colección de métricas a todos los observadores registrados. Este patrón es crucial para crear una arquitectura libremente acoplada donde el sujeto (proceso de cálculo métrico) es independiente de sus observadores (procesadores de resultados o generadores de informes). Esto permite a CK notificar a múltiples componentes sobre la finalización de los cálculos métricos sin acoplamiento a componentes específicos, lo que mejora la flexibilidad y la escalabilidad del sistema.
Patrón de fábrica: la instancia de los coleccionistas métricos es administrada por MetricsFinder , que encarna el patrón de fábrica. Este patrón se utiliza para encapsular la lógica de instancias de clases de colección métricas específicas basadas en decisiones de tiempo de ejecución. El patrón de fábrica simplifica el proceso de agregar nuevos tipos de coleccionistas métricos sin perturbar el código existente, proporcionando una arquitectura plug-and-play donde se pueden introducir nuevas métricas sin problemas. También ayuda a mantener la separación de las preocupaciones, ya que el proceso de crear objetos métricos se aísla de la lógica central de la colección métrica.
Al aprovechar estos patrones de diseño, CK gestiona eficientemente la complejidad y garantiza que el marco siga siendo robusto, adaptable y fácil de extender a medida que surgen nuevos requisitos y tipos métricos.
Necesita al menos Java 8 para poder compilar y ejecutar esta herramienta.
Para usar la última versión (que debería), clone el proyecto y genere un JAR. Un simple mvn clean compile package genera el archivo JAR único para usted (consulte su carpeta de destino ).
Entonces, solo corre:
java -jar ck-x.x.x-SNAPSHOT-jar-with-dependencies.jar
<project dir>
<use jars:true|false>
<max files per partition:0=automatic selection>
<variables and fields metrics?:true|false>
<output dir>
[ignored directories...]
Project dir se refiere al directorio donde CK puede encontrar que todo el código fuente se analice. CK buscará recursivamente archivos .java. CK puede usar las dependencias del proyecto para mejorar su precisión. Los parámetros use jars le dicen a CK que busque cualquier archivo .jar en el directorio y los use para resolver mejor los tipos. Max files per partition le dicen a JDT el tamaño del lote para procesar. Permítanos decidir eso por usted y comenzar con 0; Si ocurren problemas (es decir, fuera de memoria), piensas en ajustarlo. Variables and field metrics indican a CK si desea métricas a niveles de variables y de campo también. Son altamente de grano fino y producen mucha producción; Debe omitirlo si solo necesita métricas a nivel de clase o método. Finalmente, output dir se refiere al directorio donde CK exportará el archivo CSV con métricas del proyecto analizado. Opcionalmente, puede especificar cualquier número de directorios ignorados, separados por espacios (por ejemplo, build/ ). Por defecto, se ignoran .git y todas las demás carpetas ocultas.
La herramienta generará tres archivos CSV: clase, método y niveles variables.
Aprender con el ejemplo. Ver Runner.java Class.
Vea la versión más reciente de la biblioteca en la insignia al comienzo de este readMe, o en https://mvnrepository.com/artifact/com.github.mauricioaniche/ck.
Use el siguiente fragmento en su pom.xml. Actualizar XYZ con la versión más reciente de la herramienta (verifique MVNRepository.com o la insignia al comienzo de este archivo ReadMe):
<!-- https://mvnrepository.com/artifact/com.github.mauricioaniche/ck -->
<dependency>
<groupId>com.github.mauricioaniche</groupId>
<artifactId>ck</artifactId>
<version>X.Y.Z</version>
</dependency>
También puede usar el complemento CK Maven, desarrollado por @JazzMuesli, que automáticamente ejecuta CK en su proyecto. Muy útil para los desarrolladores: https://github.com/jazzmuesli/ck-mvn-plugin.
Esta herramienta utiliza la biblioteca JDT Core de Eclipse debajo del capó para la construcción de AST. Actualmente, la versión de cumplimiento está establecida en Java 11.
¿Necesita soporte para una versión de idioma más nueva? El proceso de agregarlo es muy sencillo, considerando contribuir con un PR:
pom.xml . Puede usar un navegador de repositorio como el repositorio MVN para aliviar este proceso.pom.xml , actualice las propiedades source y target del complemento del compilador Maven en consecuencia.CK.java : [...]
ASTParser parser = ASTParser.newParser(AST.JLS11);
[...]
JavaCore.setComplianceOptions(JavaCore.VERSION_11, options);
[...]
Debido a que la herramienta nació para calcular el CK ClasslevelMetrics, pero creció más allá de mis expectativas ... ¡la vida es divertida!
Por favor, use la siguiente entrada de Bibtex:
@manual{aniche-ck,
title={Java code metrics calculator (CK)},
author={Maurício Aniche},
year={2015},
note={Available in https://github.com/mauricioaniche/ck/}
}
¡Simplemente envíe un PR! :)
Este software tiene licencia bajo la licencia Apache 2.0.