Este documento resume tres capítulos de un libro sobre desarrollo de software limpio. El Capítulo 9 discute las pruebas unitarias, incluidas las leyes del desarrollo guiado por pruebas y ejemplos de código de pruebas limpias y no limpias. El Capítulo 10 cubre temas de diseño de clases como tamaño, encapsulamiento, responsabilidad única y cohesión. El Capítulo 11 trata sobre sistemas.
Este documento define y explica PreparedStatement y CallableStatement en Java. PreparedStatement contiene una sentencia SQL precompilada con uno o más parámetros que se especifican usando métodos como setInt antes de ejecutar la sentencia. CallableStatement provee una forma estándar de llamar procedimientos almacenados en la base de datos, los cuales pueden tener parámetros de entrada, salida o ambos. Se proveen ejemplos de cómo usar PreparedStatement e implementar actualizaciones en la base de datos.
El documento presenta una introducción a las pruebas unitarias. Explica que las pruebas unitarias automatizan la validación de unidades de código para verificar su funcionamiento. Luego describe algunos frameworks populares como JUnit, tipos comunes de pruebas, y patrones como el uso de dobles para aislar dependencias. Finalmente, identifica algunos desafíos comunes como el estado global, las APIs engañosas y el código no testable, y ofrece soluciones como inyección de dependencias.
El documento habla sobre la importancia de los test unitarios y el framework JUnit para realizarlos. Explica que los tests unitarios deben ser automatizables, completos, repetibles e independientes. También introduce el concepto de Test-Driven Development (TDD) y cómo se usa JMock para simular objetos con los que interactúa el código bajo prueba sin necesidad de crearlos realmente.
En esta presentación se describen las buenas prácticas para las pruebas unitarias y funcionales desde el punto de vista de la experiencia adquirida en mi lugar de trabajo
Este documento proporciona una introducción a JDBC y las bases de datos en Java. Explica los conceptos clave como conexiones a bases de datos, ejecución de sentencias SQL, tipos de statements, prepared statements, stored procedures, transacciones y más. También incluye ejemplos de código para establecer conexiones, consultas, inserciones, actualizaciones y eliminaciones de datos.
Este documento proporciona una introducción a las pruebas unitarias. Explica la definición de pruebas unitarias, los marcos de prueba como JUnit, cómo escribir una primera prueba unitaria, diferentes tipos de pruebas, cómo usar Mockito para pruebas con dependencias, y cómo escribir código que sea fácil de probar mediante técnicas como inyección de dependencias. También discute excusas comunes para no escribir pruebas unitarias y cómo detectar código que no es fácil de probar.
1. El documento introduce los conceptos de pruebas de aceptación y la importancia de probar programas antes de entregarlos o aceptarlos. 2. Se describe a JUnit, un paquete Java para automatizar pruebas de clases. JUnit permite crear clases de prueba con métodos que comiencen por "test" para ejecutar casos de prueba. 3. Se explican funciones como assertEquals para comparar resultados esperados vs. obtenidos.
Este documento define y explica PreparedStatement y CallableStatement en Java. PreparedStatement contiene una sentencia SQL precompilada con uno o más parámetros que se especifican usando métodos como setInt antes de ejecutar la sentencia. CallableStatement provee una forma estándar de llamar procedimientos almacenados en la base de datos, los cuales pueden tener parámetros de entrada, salida o ambos. Se proveen ejemplos de cómo usar PreparedStatement e implementar actualizaciones en la base de datos.
El documento presenta una introducción a las pruebas unitarias. Explica que las pruebas unitarias automatizan la validación de unidades de código para verificar su funcionamiento. Luego describe algunos frameworks populares como JUnit, tipos comunes de pruebas, y patrones como el uso de dobles para aislar dependencias. Finalmente, identifica algunos desafíos comunes como el estado global, las APIs engañosas y el código no testable, y ofrece soluciones como inyección de dependencias.
El documento habla sobre la importancia de los test unitarios y el framework JUnit para realizarlos. Explica que los tests unitarios deben ser automatizables, completos, repetibles e independientes. También introduce el concepto de Test-Driven Development (TDD) y cómo se usa JMock para simular objetos con los que interactúa el código bajo prueba sin necesidad de crearlos realmente.
En esta presentación se describen las buenas prácticas para las pruebas unitarias y funcionales desde el punto de vista de la experiencia adquirida en mi lugar de trabajo
Este documento proporciona una introducción a JDBC y las bases de datos en Java. Explica los conceptos clave como conexiones a bases de datos, ejecución de sentencias SQL, tipos de statements, prepared statements, stored procedures, transacciones y más. También incluye ejemplos de código para establecer conexiones, consultas, inserciones, actualizaciones y eliminaciones de datos.
Este documento proporciona una introducción a las pruebas unitarias. Explica la definición de pruebas unitarias, los marcos de prueba como JUnit, cómo escribir una primera prueba unitaria, diferentes tipos de pruebas, cómo usar Mockito para pruebas con dependencias, y cómo escribir código que sea fácil de probar mediante técnicas como inyección de dependencias. También discute excusas comunes para no escribir pruebas unitarias y cómo detectar código que no es fácil de probar.
1. El documento introduce los conceptos de pruebas de aceptación y la importancia de probar programas antes de entregarlos o aceptarlos. 2. Se describe a JUnit, un paquete Java para automatizar pruebas de clases. JUnit permite crear clases de prueba con métodos que comiencen por "test" para ejecutar casos de prueba. 3. Se explican funciones como assertEquals para comparar resultados esperados vs. obtenidos.
Este documento proporciona instrucciones para conectarse a bases de datos MySQL y SQL Server 2005 utilizando NetBeans IDE 6.1. Explica cómo cargar el controlador de base de datos, establecer la conexión, enviar consultas SQL y cerrar conexiones. También incluye tres ejemplos de código para conectarse a MySQL y SQL Server y realizar consultas desde un formulario de Java.
La interfaz PreparedStatement permite ejecutar sentencias SQL con parámetros. Las instancias de PreparedStatement contienen una sentencia SQL compilada con interrogantes para los parámetros, los cuales deben asignarse valores antes de ejecutar la sentencia usando métodos como setString(). CallableStatement extiende las funcionalidades de PreparedStatement para ejecutar procedimientos almacenados, requiriendo registrar parámetros de salida y asignar valores a los parámetros de entrada.
Este documento proporciona información sobre pruebas unitarias en Ruby utilizando la biblioteca Test::Unit. Explica los elementos básicos como test cases, test fixtures, test suites y aserciones. También cubre cómo se utiliza Test::Unit en Ruby on Rails, incluidos los entornos de prueba, la estructura de pruebas y las tareas Rake para ejecutar pruebas.
Este documento describe diferentes estructuras de control en JavaScript como condicionales, bucles y funciones. Explica el uso de if/else, switch, for, while, do/while y funciones para controlar el flujo de un programa. También cubre temas como bucles for/in, la construcción with y el paso de argumentos a funciones.
JUnit es una herramienta de código abierto para realizar pruebas unitarias de software escrito en Java. Permite automatizar la ejecución de casos de prueba para validar que las clases y métodos cumplen con su especificación. Se han desarrollado plugins para IDEs como Eclipse que facilitan la creación de casos de prueba. JUnit incluye métodos como assertEquals para comparar resultados esperados vs. obtenidos y detectar errores.
La clase Statement se usa para enviar sentencias SQL a la base de datos. Existen tres tipos de objetos Statement: Statement, PreparedStatement y CallableStatement. Statement se usa para sentencias SQL simples, PreparedStatement para sentencias precompiladas con o sin parámetros, y CallableStatement para ejecutar procedimientos almacenados. Los objetos Statement se crean usando el método createStatement de la conexión y se ejecutan con executeQuery, executeUpdate o execute dependiendo del tipo de sentencia SQL.
La clase Statement se usa para enviar sentencias SQL a la base de datos. Existen tres tipos de objetos Statement: Statement, PreparedStatement y CallableStatement. Statement se usa para sentencias SQL simples, PreparedStatement para sentencias precompiladas con o sin parámetros, y CallableStatement para ejecutar procedimientos almacenados. Los objetos Statement se crean usando el método createStatement de la conexión y permiten ejecutar consultas y actualizaciones en la base de datos.
Este documento proporciona una introducción al uso de objetos Statement en Java para interactuar con bases de datos. Define Statement como un objeto que se usa para enviar sentencias SQL a la base de datos y describe los tres tipos principales de objetos Statement. Además, explica cómo crear objetos Statement, ejecutar sentencias SQL y cerrarlos una vez que ya no se necesitan. Finalmente, incluye dos ejemplos de código que muestran cómo utilizar objetos Statement para realizar operaciones básicas en una base de datos, como consultas, inserciones y eliminaciones.
Este documento presenta 5 ejemplos para mostrar el uso de Swing en Java. El objetivo es que los estudiantes aprendan a aplicar conceptos teóricos de Swing e identificar instrucciones de Swing en NetBeans. Los ejemplos muestran el uso de campos de texto, cuadros de combinación, casillas de verificación, listas de selección múltiple y manejo de eventos de botones.
Este documento presenta varios temas básicos de Java que se verán a lo largo de varias clases. Incluye ejemplos de programas en Java sobre áreas de círculos, ámbito de variables, conversión de tipos, sentencias de control como if/else y switch, y bucles while. Los estudiantes deberán analizar los conceptos en cada ejemplo y guardar los programas realizados.
Un Statement sirve para procesar sentencias SQL estáticas y obtener resultados. Un PreparedStatement ejecuta sentencias SQL precompiladas con o sin parámetros, mientras que un CallableStatement ejecuta procedimientos almacenados. Los objetos Statement se crean usando createStatement y pueden ejecutar consultas con executeQuery, actualizaciones con executeUpdate o ambos con execute.
Este documento describe los objetos PreparedStatement y CallableStatement en Java. PreparedStatement se usa para sentencias SQL que toman parámetros de entrada, y tiene métodos para establecer valores de parámetros que se envían a la base de datos. CallableStatement hereda de PreparedStatement y permite llamar a procedimientos almacenados, estableciendo parámetros de entrada y salida. Los ejemplos muestran cómo crear un PreparedStatement, establecer parámetros y ejecutar consultas o procedimientos almacenados.
Este documento explica qué es una PreparedStatement en Java y cómo usarla. Una PreparedStatement es una sentencia SQL precompilada que se puede ejecutar de forma más rápida que una sentencia normal cuando se ejecuta varias veces con diferentes valores. Explica cómo crear un objeto PreparedStatement, establecer parámetros y ejecutarlo para inserciones, actualizaciones y consultas. También incluye ejemplos de cómo usar PreparedStatement para insertar, actualizar y consultar registros de una base de datos.
Un objeto Statement se usa para enviar sentencias SQL a la base de datos y obtener los resultados. Actualmente hay tres tipos de objetos Statement, todos los cuales actúan como contenedores para la ejecución de sentencias en una conexión dada
Este documento introduce el desarrollo guiado por pruebas (TDD) y PHPUnit para realizar pruebas automatizadas de código. Explica que TDD es una metodología ágil que permite crear código testable, robusto y bien diseñado mediante la traducción de casos de uso a ejemplos de prueba. Luego, detalla cómo instalar PHPUnit y escribir pruebas unitarias mediante aserciones, proveedores de datos, manejo de excepciones y métodos setUp() y tearDown().
¿Cómo mantener tu javascript?: Buenas prácticasjaespinmora
Buenas práctias en el desarrollo de software con javascript. Código limpio, mantenible, escalable, tests,... Charla perteneciente al evento Betabeers Murcia del día 9 de Mayo de 2014
Este documento describe los fundamentos de JavaScript, incluyendo su uso en páginas web, normas de codificación, funciones, ventanas de alerta, eventos y variables. Explica cómo crear funciones y llamarlas, y cómo manejar eventos del usuario para mostrar alertas u otras acciones. También cubre tipos de datos, operadores y la creación de un programa JavaScript básico.
1. El documento describe las normas y conceptos básicos de JavaScript, incluyendo el uso de funciones, variables, constantes y operadores. 2. Explica cómo crear funciones y cómo llamarlas desde elementos del documento o desde otras funciones. 3. Proporciona ejemplos de código JavaScript para mostrar mensajes, manipular eventos y utilizar variables.
Este documento proporciona instrucciones para conectarse a bases de datos MySQL y SQL Server 2005 utilizando NetBeans IDE 6.1. Explica cómo cargar el controlador de base de datos, establecer la conexión, enviar consultas SQL y cerrar conexiones. También incluye tres ejemplos de código para conectarse a MySQL y SQL Server y realizar consultas desde un formulario de Java.
La interfaz PreparedStatement permite ejecutar sentencias SQL con parámetros. Las instancias de PreparedStatement contienen una sentencia SQL compilada con interrogantes para los parámetros, los cuales deben asignarse valores antes de ejecutar la sentencia usando métodos como setString(). CallableStatement extiende las funcionalidades de PreparedStatement para ejecutar procedimientos almacenados, requiriendo registrar parámetros de salida y asignar valores a los parámetros de entrada.
Este documento proporciona información sobre pruebas unitarias en Ruby utilizando la biblioteca Test::Unit. Explica los elementos básicos como test cases, test fixtures, test suites y aserciones. También cubre cómo se utiliza Test::Unit en Ruby on Rails, incluidos los entornos de prueba, la estructura de pruebas y las tareas Rake para ejecutar pruebas.
Este documento describe diferentes estructuras de control en JavaScript como condicionales, bucles y funciones. Explica el uso de if/else, switch, for, while, do/while y funciones para controlar el flujo de un programa. También cubre temas como bucles for/in, la construcción with y el paso de argumentos a funciones.
JUnit es una herramienta de código abierto para realizar pruebas unitarias de software escrito en Java. Permite automatizar la ejecución de casos de prueba para validar que las clases y métodos cumplen con su especificación. Se han desarrollado plugins para IDEs como Eclipse que facilitan la creación de casos de prueba. JUnit incluye métodos como assertEquals para comparar resultados esperados vs. obtenidos y detectar errores.
La clase Statement se usa para enviar sentencias SQL a la base de datos. Existen tres tipos de objetos Statement: Statement, PreparedStatement y CallableStatement. Statement se usa para sentencias SQL simples, PreparedStatement para sentencias precompiladas con o sin parámetros, y CallableStatement para ejecutar procedimientos almacenados. Los objetos Statement se crean usando el método createStatement de la conexión y se ejecutan con executeQuery, executeUpdate o execute dependiendo del tipo de sentencia SQL.
La clase Statement se usa para enviar sentencias SQL a la base de datos. Existen tres tipos de objetos Statement: Statement, PreparedStatement y CallableStatement. Statement se usa para sentencias SQL simples, PreparedStatement para sentencias precompiladas con o sin parámetros, y CallableStatement para ejecutar procedimientos almacenados. Los objetos Statement se crean usando el método createStatement de la conexión y permiten ejecutar consultas y actualizaciones en la base de datos.
Este documento proporciona una introducción al uso de objetos Statement en Java para interactuar con bases de datos. Define Statement como un objeto que se usa para enviar sentencias SQL a la base de datos y describe los tres tipos principales de objetos Statement. Además, explica cómo crear objetos Statement, ejecutar sentencias SQL y cerrarlos una vez que ya no se necesitan. Finalmente, incluye dos ejemplos de código que muestran cómo utilizar objetos Statement para realizar operaciones básicas en una base de datos, como consultas, inserciones y eliminaciones.
Este documento presenta 5 ejemplos para mostrar el uso de Swing en Java. El objetivo es que los estudiantes aprendan a aplicar conceptos teóricos de Swing e identificar instrucciones de Swing en NetBeans. Los ejemplos muestran el uso de campos de texto, cuadros de combinación, casillas de verificación, listas de selección múltiple y manejo de eventos de botones.
Este documento presenta varios temas básicos de Java que se verán a lo largo de varias clases. Incluye ejemplos de programas en Java sobre áreas de círculos, ámbito de variables, conversión de tipos, sentencias de control como if/else y switch, y bucles while. Los estudiantes deberán analizar los conceptos en cada ejemplo y guardar los programas realizados.
Un Statement sirve para procesar sentencias SQL estáticas y obtener resultados. Un PreparedStatement ejecuta sentencias SQL precompiladas con o sin parámetros, mientras que un CallableStatement ejecuta procedimientos almacenados. Los objetos Statement se crean usando createStatement y pueden ejecutar consultas con executeQuery, actualizaciones con executeUpdate o ambos con execute.
Este documento describe los objetos PreparedStatement y CallableStatement en Java. PreparedStatement se usa para sentencias SQL que toman parámetros de entrada, y tiene métodos para establecer valores de parámetros que se envían a la base de datos. CallableStatement hereda de PreparedStatement y permite llamar a procedimientos almacenados, estableciendo parámetros de entrada y salida. Los ejemplos muestran cómo crear un PreparedStatement, establecer parámetros y ejecutar consultas o procedimientos almacenados.
Este documento explica qué es una PreparedStatement en Java y cómo usarla. Una PreparedStatement es una sentencia SQL precompilada que se puede ejecutar de forma más rápida que una sentencia normal cuando se ejecuta varias veces con diferentes valores. Explica cómo crear un objeto PreparedStatement, establecer parámetros y ejecutarlo para inserciones, actualizaciones y consultas. También incluye ejemplos de cómo usar PreparedStatement para insertar, actualizar y consultar registros de una base de datos.
Un objeto Statement se usa para enviar sentencias SQL a la base de datos y obtener los resultados. Actualmente hay tres tipos de objetos Statement, todos los cuales actúan como contenedores para la ejecución de sentencias en una conexión dada
Este documento introduce el desarrollo guiado por pruebas (TDD) y PHPUnit para realizar pruebas automatizadas de código. Explica que TDD es una metodología ágil que permite crear código testable, robusto y bien diseñado mediante la traducción de casos de uso a ejemplos de prueba. Luego, detalla cómo instalar PHPUnit y escribir pruebas unitarias mediante aserciones, proveedores de datos, manejo de excepciones y métodos setUp() y tearDown().
¿Cómo mantener tu javascript?: Buenas prácticasjaespinmora
Buenas práctias en el desarrollo de software con javascript. Código limpio, mantenible, escalable, tests,... Charla perteneciente al evento Betabeers Murcia del día 9 de Mayo de 2014
Este documento describe los fundamentos de JavaScript, incluyendo su uso en páginas web, normas de codificación, funciones, ventanas de alerta, eventos y variables. Explica cómo crear funciones y llamarlas, y cómo manejar eventos del usuario para mostrar alertas u otras acciones. También cubre tipos de datos, operadores y la creación de un programa JavaScript básico.
1. El documento describe las normas y conceptos básicos de JavaScript, incluyendo el uso de funciones, variables, constantes y operadores. 2. Explica cómo crear funciones y cómo llamarlas desde elementos del documento o desde otras funciones. 3. Proporciona ejemplos de código JavaScript para mostrar mensajes, manipular eventos y utilizar variables.
Similar a REVIEWCLEANCODE9-11_GROUP4_FINAL.pptx (20)
Estilo Arquitectónico Ecléctico e Histórico, Roberto de la Roche.pdfElisaLen4
Un pequeño resumen de lo que fue el estilo arquitectónico Ecléctico, así como el estilo arquitectónico histórico, sus características, arquitectos reconocidos y edificaciones referenciales de dichas épocas.
3. PRUEBAS UNITARIAS
Test que validan el comportamiento y
funcionamiento de partes de código
específicas y son aplicadas durante la
fase de Desarrollo de software.
CHAPTER 9
5. Pruebas automatizadas
Leyes del TDD:
1. No crear código de producción hasta crear una prueba unitaria que
presente fallos.
2. No crear más de una prueba de unidad fallida.
3. Crear código de producción necesario para superar la prueba de fallo.
Impulsadas por el desarrollo guiado por pruebas y el movimiento ágil.
El TDD implica escribir el código de las pruebas previamente al código de producción.
6. Código en evolución encargado
de la eficiencia y funcionalidad
del código de producción.
Alto nivel de calidad e
importancia para asegurar
garantía del producto.
Aportan flexibilidad, facilitan el
mantenimiento y posibilidad de
reutilización.
Eliminan riesgos de errores de
difícil detección en código de
producción, posibilitan mejora
de planificación y arquitectura.
Pruebas limpias
7. ¿Qué hace que las pruebas sean
limpias?
Claridad Simplicidad Densidad de
expresión
13. Diferencias entre códigos de prueba
9-1 SerializedPage
ResponderTest.java
Difícil de entender y
puede mejorarse
Existe código duplicado
que interfiere con
expresividad de prueba.
Ejecución, emisión,
recopilación y creación de
URL demasiado compleja.
9-2 SerializedPage
ResponderTest.java
(refactorizado)
Cumple la misma
función de forma clara y
descriptiva
Patrón BUILD-OPERATE-
CHECK en la estructura del
código
Utilizan tipos de datos y funciones
necesarias, mayor legibilidad y
comprensión para los lectores.
14. ● En lugar de usar API para manipular el sistema, utilizar funciones y
utilidades que usan las API, para facilitar la lectura y escritura de las
pruebas.
● API: lenguaje de pruebas que los programadores usan parar crea
los test y facilitan el entendimiento del lector, evoluciona a través de
cambios continuos en el código.
● Código de la API de pruebas debe ser más sencillo, breve y
expresivo.
● Diferencia de estándares entre código de pruebas y producción en
términos de eficacia.
Lenguaje de prueba específico del dominio
15. Ejemplos:
● Listado 9-3 EnvironmentControllerTest.java (Prototipo de sistema de control
medioambiental)
● Esta prueba verifica que la alarma de baja temperatura, el calentador y el ventilador se
encienden cuando la temperatura sea demasiado fría.
@Test
public void turnOnLoTempAlarmAtThreashold() throws Exception
{
hw.setTemp(WAY_TOO_COLD);
controller.tic(); assertTrue(hw.heaterState());
assertTrue(hw.blowerState());
assertFalse(hw.coolerState());
assertFalse(hw.hiTempAlarm());
assertTrue(hw.loTempAlarm());
}
16. @Test
public void turnOnLoTempAlarmAtThreshold() throws Exception
{
wayTooCold();
assertEquals("HBchL", hw.getState());
}
● Función tic reemplazada por wayTooCold, en asserEqual se indica el estado activo e inactivo de los
elementos en el siguiente orden: {calentador, ventilador, enfriador, alarma de alta temperatura,
alarma de baja temperatura}.
● Conociendo el significado de las letras y el código podemos interpretar y comprender el resultado
con mayor facilidad que en la prueba pasada.
Listado 9-4 EnvironmentControllerTest.java (refactorizado)
17. ● La función getState se desarrolla en el código 9.6 por lo que la codificación no es muy eficaz y en
lugar de esta función se pudo utilizar StringBuffer para cambiar las cadenas de estado.
@Test
public void turnOnCoolerAndBlowerIfTooHot() throws Exception
{
tooHot();
assertEquals("hBChl", hw.getState());
}
@Test
public void turnOnHeaterAndBlowerIfTooCold() throws Exception
{
tooCold();
assertEquals("HBchl", hw.getState());
}
Listado 9-5 EnvironmentControllerTest.java (selección más grande)
19. public String getState()
{
String state = "";
state += heater ? "H" : "h";
state += blower ? "B" : "b";
state += cooler ? "C" : "c";
state += hiTempAlarm ? "H" : "h";
state += loTempAlarm ? "L" : "l";
return state;
}
● Sin embargo, se recomienda no utilizar los StringBuffer por ser poco atractivos en las pruebas,
evitarlos a todo lugar en código de producción y en proyectos de bajo presupuesto con pruebas de
tiempo real, por la limitación de recursos y memoria.
Listado 9-6 MockControlHardware.java
20. ● “Todas las funciones de prueba de un test solo deben tener una instrucción
de afirmación para llegar a una conclusión de forma rápida y sencilla.”
● Listado 9-7 SerializedPageResponderTest.java (afirmación única)
public void testGetPageHierarchyAsXml() throws Exception
{
givenPages("PageOne", "PageOne.ChildOne", "PageTwo");
whenRequestIsIssued("root", "type:pages");
thenResponseShouldBeXML();
}
Una afirmación por prueba
21. public void testGetPageHierarchyHasRightTags() throws Exception
{
givenPages("PageOne", "PageOne.ChildOne", "PageTwo");
whenRequestIsIssued("root", "type:pages");
thenResponseShouldContain( "PageOne", "PageTwo", "ChildOne" );
}
● Funciones que se dividen en tres partes para tener una sola afirmación, para facilitar el
entendimiento, pero se duplica código.
● Para solucionar el problema podríamos crear una nueva clase con una prueba independiente o
nuevas funciones para llamarlas, pero es más complejo que dividir el código y asignar afirmaciones
múltiples, entonces, la regla de asignar una única afirmación se reemplaza por:
● El número de afirmaciones de una prueba debe ser mínimo.
22. ● Probar un solo concepto en cada función de prueba. Evitar funciones de prueba largas que prueben
una miscelánea de cosas tras otra.
● Listado 9-8
/ ** * Pruebas varias para el método addMonths (). * /
public void testAddMonths()
{
SerialDate d1 = SerialDate.createInstance(31, 5, 2004);
SerialDate d2 = SerialDate.addMonths(1, d1);
assertEquals(30, d2.getDayOfMonth());
assertEquals(6, d2.getMonth());
assertEquals(2004, d2.getYYYY());
Un solo concepto por prueba
23. SerialDate d3 = SerialDate.addMonths(2, d1);
assertEquals(31, d3.getDayOfMonth());
assertEquals(7, d3.getMonth());
assertEquals(2004, d3.getYYYY());
SerialDate d4 = SerialDate.addMonths(1, SerialDate.addMonths(1, d1));
assertEquals(30, d4.getDayOfMonth());
assertEquals(7, d4.getMonth());
assertEquals(2004, d4.getYYYY());
}
Las tres funciones de prueba probablemente deberían ser así:
● Dado el último día de un mes con 31 días (como mayo):
1. Cuando agrega un mes, de modo que el último día de ese mes sea el 30
(como junio), entonces la fecha debe ser el 30 de ese mes, no 31.
2. Cuando agrega dos meses a esa fecha, de modo que el último mes tenga
31 días, entonces la fecha debería ser 31.
● Dado el último día de un mes con 30 días (como junio):
1. Cuando agrega un mes, de modo que el último día de ese mes tenga 31 días, entonces la fecha debe ser 30,
no 31.
24. Regla general
Cuando incrementa el mes, la fecha no puede ser mayor que el último día del mes.
Esto implica que incrementar el mes el 28 de febrero debería producir marzo 28.
Falta esa prueba y sería útil escribirla.
Entonces, no son las múltiples afirmaciones en cada sección del Listado 9-8 las que
causan el problema. Más bien, es el hecho de que se está probando más de un
concepto. Entonces probablemente la mejor opción sea en realidad minimizar el
número de afirmaciones por concepto y probar solo una concepto por función de
prueba.
Regla F.I.R.S.T
Rapidez Independecia Repetición
Validación
Automática
Puntualidad
25. ● Las pruebas son tan importantes para la salud de un proyecto como el
código de producción.
● Se debe trabajar en las pruebas hasta que sean concisas y
suficientemente expresivas.
● Es necesario inventar API de prueba que actúen como lenguaje
específico del dominio, para ayuden en la creación de pruebas.
● Mantener una limpieza regular del código de las pruebas para evitar
que se corrompa el código de producción.
Conclusiones
27. Las clases deben ser de
tamaño reducido
Mantener resultados
consistentes
Encapsulación
Organización de clase
Cohesión
El principio de
responsabilidad única
SUBTEMAS
Organizar los cambios
28. Organización de clases
Según la convención estándar de Java, una clase:
• Comienza con una lista de variables.
• Primero, constantes estáticas públicas.
• Segundo, variables estáticas privadas.
• Tercero, variables de instancia privadas.
• Las funciones públicas deben seguir a la lista de variables.
29. Encapsulamiento
• Siuna regla del mismo paquete tiene que invocar una función o acceder a
una variable , hacemos que tenga ámbito protected o de paquete
30. Las clases deben ser de tamaño
reducido
• Con las funciones medimos el tamaño contando líneas físicas. Con las clases
usamos otra medida distinta: las responsabilidades.
32. Pero…
• No solo hay que cuidar que no tenga muchos métodos, sino cuidar
especialmente que la clase no tenga muchas responsabilidades.
• Una clave para identificar las responsabilidades es asociar a las mismas con el
nombre de la clase.
• Cuanto mas ambiguo sea el nombre de una clase más probabilidades hay de
que tenga demasiadas responsabilidades.
• Otra clavees que a la hora de describir la clase no nos encontremos con
palabras como “y”, “o”, “si”, “pero”.
33. Principio de responsabilidad única
• Las clases solo deben tener una responsabilidad ypor ende, solo un motivo
para cambiar.
• Podemos extraer los tres métodos de SuperDashBoard relacionados con la
información de versiones en una clase independiente como Version. La clase
Version es una construcción que se puede reutilizar en otras aplicaciones.
34. Principio de responsabilidad única
• En conclusión: “Los sistemas deben estar formados por
muchas clases reducidas, no por algunas de gran tamaño.
Cada clase reducida encapsula una única responsabilidad,
tiene solo un motivo para cambiar ycolabora con algunas
otras para obtener los comportamientos deseados del
sistema”
35. Cohesión
• Las clases deben tener un número reducido de variables de instancia.
• Los métodos de una clase deben manipular una o varias de dichas variables.
• Cuantas más variables manipule un método, más cohesión tendrá con su
clase.
• Una clase en la que cada variable se usa en cada método tiene una cohesión
máxima.
• La idea es crear una dependencia lógica entre métodos y variables.
36. Cohesión = grado de utilización de las variables de instancia por parte de las
funciones. Queremos clases cohesionadas. Cuando se reduce el tamaño de
las funciones se aumenta el tamaño de variables de instancia (para no
pasarlas como parámetro a las subfunciones) y se pierde cohesión. En ese
caso lo mejor es dividir en subclases.
38. Mantener resultados consistentes en
clases de tamaño reducido
• La división de grandes funciones en otras más pequeña aumenta la
proliferación de clases.
• Sinecesito que dentro de una función 1 se llame a una función 2, en lugar de
mandarle a ésta las variables declaradas en la función 1, estas variables
hacerse de instancia o globales en la clase pero esto implica que se pierda
cohesión yaque acumularían más ymás variables globales que solo existen
para que otras funciones las compartan.
• Cuando esto sucede es conveniente crear otra clase.
39. ● En un sistema limpio, organizamos nuestras clases para reducir el
riesgo de cambio, puesto que en la mayoría de sistemas el cambio es
continuo.
Listado 10-9
Organizándose para el cambio
public class Sql {
public Sql(String table, Column[] columns)
public String create()
public String insert(Object[] fields)
public String selectAll()
public String findByKey(String keyColumn, String keyValue)
public String select(Column column, String pattern)
public String select(Criteria criteria)
public String preparedInsert()
private String columnList(Column[] columns)
private String valuesList(Object[] fields, final Column[] columns)
private String selectWithCriteria(String criteria)
private String placeholderList(Column[] columns)
}
40. ● Lo que podemos identificar en el listado 10-9 es que existe una clase con
varios métodos de los cuales se podrían definir varias responsabilidades,
lo cual en el SRP define que es difícil darles mantenimiento o extenderlo.
● La clase Sql del listado 10-9 podría cambiar cuando agreguemos un
nuevo tipo de declaración, además cambiaria cuando modifiquemos los
detalles de los tipos de declaración por lo que tendríamos 2
responsabilidades , con lo cual viola el SRP.
● SRP dicta que cada clase debe hacer solamente una cosa, ósea tener una
única responsabilidad.
● Si existiese el caso en el se supiera que el software no recibirá una
actualización en el futuro podríamos considerar al código del listado 10-9
como funcional.
Organizándose para el cambio
41. ● Aplicando los principios de responsabilidad única (SRP) al código del
listado 10-9 nos quedaría de la siguiente manera:
Listado 10-10
Organizándose para el cambio
abstract public class Sql {
public Sql(String table, Column[] columns)
abstract public String generate();
}
public class CreateSql extends Sql {
public CreateSql(String table, Column[] columns)
@Override public String generate()
}
public class SelectSql extends Sql {
public SelectSql(String table, Column[] columns)
@Override public String generate()
}
public class InsertSql extends Sql {
public InsertSql(String table, Column[] columns, Object[] fields)
@Override public String generate()
private String valuesList(Object[] fields, final Column[] columns)
}
42. ● Podemos observar que el código se ha vuelto mas simple y entendible,
además el riesgo de que al agregar una nueva funcional rompa otra
importante se va reduciendo.
● Adicional las clases del listado 10-10 admite otro principio clave de
diseño el cual es conocido como OCP (Principio Abierto-Cerrado) el cual
dicta que las clases deben estar abierta para extensiones en el código
pero cerradas para las posibles modificaciones del mismo.
● En el listado 10-10 cumple esto puesto que su código esta abierta para
permitir nuevas funcionalidades sin modificar las funcionalidades ya
existentes.
Organizándose para el cambio
43. ● Dentro de nuestro sistemas existen clases que tienen detalles concretos
los cuales están en riesgo cuando se necesite modificar los mismo. Para
evitar los riesgos ante este tipo de situaciones lo que podemos aplicar
es el principio de inversión de dependencia (DIR).
● El DIR explica que nuestras clases no deben de depender de detalles
concretos sino que deberían de depender de abstracciones como las
interfaces, que lo que hace la interfaz es aislar los detalles concretos
para que el código se libre de depender de estos y que se desacople.
Aislamiento del cambio
44. Ejemplo de Aislamiento del
Cambio
En la imagen podemos observar dos clases; la clase botón y la clase lampara,
podemos observar que la clase botón depende directamente de lampara es
decir que si en la clase lámpara realizamos algún cambio el botón cambiara
también.
Otro aspecto es que el código no es reutilizable puesto que botón esta
simplemente enfocado a lámpara, es decir si en un futuro se quisiera
agregar una nueva clase televisión por ejemplo, la clase botón quedaría sin
utilidad para la clase televisión.
45. Ejemplo de Aislamiento del
Cambio
En la imagen podemos observar que se agrego una interfaz, con ello la
clase botón depende únicamente de abstracciones y esto conlleva a que
pueda ser reusado varias veces.
Adicional si se realiza cambios en la clase lampara la clase botón debería
recibir ningún cambio y la clase lámpara es quien debe adaptarse a la
interfaz definida, además se pueden acoplar varias clases, como
televisor, lavadora, etc.
46. Conclusiones
● Orden dentro de la clase: Contantes estáticas, variables estáticas, variables de
instancia y funciones. De todo ello, primero lo público y después lo privado.
● El tamaño debe ser reducido, debe tener una única responsabilidad, la que
indica su nombre. Nombres a evitar son Manager, Processor, Super ya que
denotan muchas responsabilidades.You can write about the topic here
● Single Responsibility Principle, una clase debe tener un único motivo para
cambiar.
● Open/Closed Principle = las clases deben estar abiertas a extensión y cerradas a
modificación. Los cambios mejor que se hagan extendiendo o introduciendo
nuevas clases, no modificando las existentes.
● La organización ante posibles cambios de nuestra aplicación es muy útil, puesto
que esto lo hace mas legible y fácil de modificar o aumentar ciertas
funcionalidades, de lo contrario se debería realizar nuevamente las clases que no
tengan una organización adecuada.
48. ● Considerar que la construcción es un proceso diferente al uso, el
proceso de inicio siempre es una preocupación que cualquier software
debe abordar. Para ello existe una técnica de diseño llamada la
separación de preocupaciones (SoC).
● SoC nos indica que que evitemos escribir funciones largas y complejas,
por ejemplo si notamos que la función comienza a aumentar de tamaño
posiblemente la función se este ocupando de demasiadas cosas a la
vez. Lo cual lo mas prudente seria refactorizarlo.
Separar la construcción de un sistema de
su uso
49. ● Una forma de separar la construcción del uso, consiste en mover todos
los aspectos de la construcción al main, luego diseñar el resto del
sistema asumiendo que todos los objetos se han construido y
organizado de manera apropiada.
● El flujo de control es fácil de seguir. El main construye los objetos
necesarios para el sistema, luego los pasa a la aplicación, que
simplemente los usa. La aplicación no tiene conocimiento del proceso
del main o de construcción, simplemente espera que todo se haya
construido correctamente.
Separación de main
50. ● Ciertas ocasiones necesitamos que la aplicación sea responsable de la
creación de objetos, por lo que es necesario el uso del patron de diseño
Abstract Factory.
Factories
51. ● Una fabrica abstracta tiene métodos los cuales permite acceder a otras
fábricas independientes y sus familias para obtener la instancia de
algún objeto de dicha familia.
● En la fábrica abstracta se define métodos los cuales nos permitirán
tener una conexión con cada una de las familias independientes para
que sea más sencillo realizar un llamado a la familia que se necesite.
● Una fábrica independiente lo que se realiza es la implementación de la
fábrica abstracta con el objetivo de que podamos elegir a que objeto
deseamos acceder u obtener su instancia, una vez que obtenemos la
instancia de algún objeto también tenemos acceso a los métodos de
dicho objeto.
Factories
52. ● DI nos permite inyectar comportamientos a componentes haciendo que
nuestras piezas de software sean independientes y se comuniquen
únicamente a través de una interface. DI extrae responsabilidades a un
componente para delegarlas en otro, estableciendo un mecanismo a
través del cual el nuevo componente puede ser cambiado en tiempo de
ejecución. Para lograr esta tarea DI se basa en un patrón más genérico
llamado Inversión de Control (Inversion of Control).
● DI tiene como finalidad solucionar un problema común que los
programadores encuentran en la construcción de aplicaciones. Este es,
mantener los componentes o capas de una aplicación lo más
desacopladas posible,
Inyección de dependencia
53. ● Los sistemas de software son únicos en comparación con los sistemas
físicos. Sus arquitecturas pueden crecer incrementalmente, si
mantenemos la adecuada separación de preocupaciones.
● Las arquitecturas EJB no separan las preocupaciones de manera
adecuada, por lo tanto impide que el crecimiento orgánico. Esto vuelve
a EJB en una arquitectura bastante complicada y amplia. Crea
soluciones costosas y complejas.
Ampliar
54. En el desarrollo de cualquier aplicación, existen las llamadas
"preocupaciones transversales", que son actividades comunes de la mayoría
de las aplicaciones: inicio de sesión, seguridad, transacciones
PREOCUPACIONES TRANSVERSALES
55. Proxy: es un patrón de diseño estructural que proporciona un objeto que
actúa como sustituto de un objeto de servicio real utilizado por un cliente.
PROXY DE JAVA
56. AOP: una tecnología para programación orientada a aspectos, que realiza el
mantenimiento unificado de las funciones del programa a través de la
compilación previa y agentes dinámicos durante el tiempo de ejecución.
Spring AOP: El famoso framework para aplicaciones spring en su núcleo
tiene un framework para AOP. Este framework es implementado en java puro
con las anotaciones de java @Aspect o basado en esquema con un XML.
FRAMEWORKS DE JAVA PURO AOP
57. Es la extensión orientada a aspectos de java. Este esta disponible en Eclipse
Fundation. Es el lenguaje de POA más usado debido a que es particularmente
fácil de aprender y utilizar.
AspectJ Aspectos
58. Probar la arquitectura del sistema.
Optimizar la toma de decisiones.
Utilizar los estándares con prudencia cuando añadan un valor
demostrable.
Recomendaciones
59. COOL(COOrdination Language): trata los aspectos de sincronismo entre
hilos concurrentes. (Java)
RIDL (Remote Interaction and Data transfers aspect Language)
MALAJ (Multi Aspect LAnguage for Java)
KALA: Modelos transaccionales avanzados
DIE: Un lenguaje de aspectos de dominio específico para eventos de
IDE
HYPERJ
AspectG(ANTLR)
AspectMatlab
Lenguajes de dominio específico