mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 10:58:42 +00:00
* Translate: Translate the aggregator-microservices readme to Spanish [Issue #2335 (Task of issue #2277 )] * Translate: Translate the aggregator-microservices readme to Spanish [Issue #2335 (Task of issue #2277 )] * Update README.md * Restored translated YAML Frontmatter keys to right words not translated and minor new changes Minor new changes are at YAML Frontmatter variables values of lines 2 and 3 where have switched the order of translated words to homogeinize the belowing structure of that order like figured at following lines 6,7 and 8 (First english term and then Spanish translation between parenthesis) * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Update localization/es/aggregator-microservices/README.md Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com> * Translated ambassador pattern README.md to Spanish(#2453) * Changed Class Diagram image path to absolute way. The original path for Class Diagram image was relative to /ambassador folder (./etc/ambassador.urm.png) when translated at line 173 of translation doesn't show the diagram image so I haved changed it to absolute format (/ambassador/etc/ambassador.urm.png) and now it shows it. * Added arrange-act-assert folder with README file without being traslated yet * Translated line by line to spanish. English lines left for review, will be removed on next commit inmediately. * Translated arrange-act-assert/README.md to Spanish and removed the English version text lines. * Changed language tag value from en to es * async-method-invocation translated to Spanish. Left the original English version lines for review and will be removed in next commit inmediately. * async-method-invocation transalation to spanish. Removed the english version after review. --------- Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
---
|
||||
title: Arrange/Act/Assert
|
||||
category: Idiom
|
||||
language: es
|
||||
tag:
|
||||
- Testing
|
||||
---
|
||||
|
||||
## También conocido como
|
||||
|
||||
Dado/Cuando/Entonces
|
||||
|
||||
## Intención
|
||||
|
||||
Arrange/Act/Assert (AAA) es un patrón para organizar UnitTests.
|
||||
Divide las UnitTests en tres pasos claros y diferenciados:
|
||||
|
||||
1. Arrange(Organizar): Realiza la configuración y la inicialización necesarias para el test.
|
||||
2. Act(Actuar): Toma las medidas necesarias para el test.
|
||||
3. Assert(Afirmar): Verifica los resultados del test.
|
||||
|
||||
## Explicacación
|
||||
|
||||
Este patrón tiene varios beneficios significativos. Crea una clara separación entre la configuración, operaciones y resultados de un test. Esta estructura hace que el código sea más fácil de leer y comprender. Si
|
||||
colocas los pasos en orden y formateas su código para separarlos, puedes escanear un test y
|
||||
comprender rápidamente lo que hace.
|
||||
|
||||
También impone un cierto grado de disciplina cuando escribes tus UnitTests. Tienes que visualizar
|
||||
claramente los tres pasos que tu test realizará. Esto hace que los tests sean más intuitivos de escribir a la vez que tienes presente un esquema.
|
||||
|
||||
Ejemplo cotidiano
|
||||
|
||||
> Necesitamos escribir un conjunto de UnitTests completo y claro para una clase.
|
||||
|
||||
En otras palabras
|
||||
|
||||
> Arrange/Act/Assert es un patrón de testeo que organiza las pruebas en tres pasos claros para facilitar su
|
||||
> mantenimiento.
|
||||
|
||||
WikiWikiWeb dice
|
||||
|
||||
> Arrange/Act/Assert es un patrón para organizar y dar formato al código en los métodos UnitTest.
|
||||
|
||||
**Código de ejemplo**
|
||||
|
||||
Veamos primero nuestra clase `Cash` para que sea testeada.
|
||||
|
||||
```java
|
||||
public class Cash {
|
||||
|
||||
private int amount;
|
||||
|
||||
Cash(int amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
void plus(int addend) {
|
||||
amount += addend;
|
||||
}
|
||||
|
||||
boolean minus(int subtrahend) {
|
||||
if (amount >= subtrahend) {
|
||||
amount -= subtrahend;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int count() {
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Luego escribimos nuestras UnitTests en función del patrón Arrange/Act/Assert. Note claramente la separación de los pasos para cada UnitTest.
|
||||
|
||||
```java
|
||||
class CashAAATest {
|
||||
|
||||
@Test
|
||||
void testPlus() {
|
||||
//Arrange
|
||||
var cash = new Cash(3);
|
||||
//Act
|
||||
cash.plus(4);
|
||||
//Assert
|
||||
assertEquals(7, cash.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMinus() {
|
||||
//Arrange
|
||||
var cash = new Cash(8);
|
||||
//Act
|
||||
var result = cash.minus(5);
|
||||
//Assert
|
||||
assertTrue(result);
|
||||
assertEquals(3, cash.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInsufficientMinus() {
|
||||
//Arrange
|
||||
var cash = new Cash(1);
|
||||
//Act
|
||||
var result = cash.minus(6);
|
||||
//Assert
|
||||
assertFalse(result);
|
||||
assertEquals(1, cash.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdate() {
|
||||
//Arrange
|
||||
var cash = new Cash(5);
|
||||
//Act
|
||||
cash.plus(6);
|
||||
var result = cash.minus(3);
|
||||
//Assert
|
||||
assertTrue(result);
|
||||
assertEquals(8, cash.count());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Aplicabilidad
|
||||
|
||||
Utilice el patrón Arrange/Act/Asert cuando
|
||||
|
||||
* Necesites estructurar tus UnitTests para que sean más fáciles de leer, mantener y mejorar.
|
||||
|
||||
## Créditos
|
||||
|
||||
* [Arrange, Act, Assert: ¿Qué son las pruebas AAA?](https://blog.ncrunch.net/post/arrange-act-assert-aaa-testing.aspx)
|
||||
* [Bill Wake: 3A – Arrange, Act, Assert](https://xp123.com/articles/3a-arrange-act-assert/)
|
||||
* [Martin Fowler: DadoCuandoEntonces](https://martinfowler.com/bliki/GivenWhenThen.html)
|
||||
* [Patrones de prueba xUnit: Refactorizando Código de prueba](https://www.amazon.com/gp/product/0131495054/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0131495054&linkId=99701e8f4af2f63d0bcf50)
|
||||
* [Principios, prácticas y patrones UnitTesting](https://www.amazon.com/gp/product/1617296279/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=1617296279&linkId=74c75cfae3a5a)accae3a5a)
|
||||
* [Desarrollo basado en pruebas: Ejemplo](https://www.amazon.com/gp/product/0321146530/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0321146530&linkId=5c63a93d8c1175b47caef50875)
|
||||
@@ -0,0 +1,168 @@
|
||||
---
|
||||
title: Async Method Invocation
|
||||
category: Concurrency
|
||||
language: es
|
||||
tag:
|
||||
- Reactive
|
||||
---
|
||||
|
||||
## Propósito
|
||||
|
||||
Asynchronous method invocation (invocación de método asincrónico) es un patrón con el que el hilo o subproceso de llamada
|
||||
no se bloquea mientras espera resultados. El patrón proporciona pocesamiento en paralelo de múltiples tareas independientes y recupera los resultados a través de
|
||||
devoluciones de llamada (callbacks) o esperando hasta que termine el procedimiento.
|
||||
|
||||
## Explicación
|
||||
|
||||
Ejemplo cotidiano
|
||||
|
||||
> Lanzar cohetes espaciales es un negocio apasionante. El comandante de la misión da la orden de lanzamiento y
|
||||
> después de un tiempo indeterminado, el cohete se lanza con éxito o falla miserablemente.
|
||||
|
||||
En otras palabras
|
||||
|
||||
> La invocación del método asíncrono inicia el procedimiento y vuelve inmediatamente antes de que la tarea termine
|
||||
> Los resultados del procedimiento se devuelven a la llamada posteriormente (callback).
|
||||
|
||||
Según Wikipedia
|
||||
|
||||
> En la programación multiproceso, la invocación de método asíncrono (AMI), también conocida como
|
||||
> llamadas de método asíncrono o el patrón asíncrono es un patrón de diseño en el que el lugar de la llamada
|
||||
> no se bloquea mientras espera que termine el código llamado. En cambio, el hilo de llamada es
|
||||
> notificado cuando llega la respuesta. Sondear para obtener una respuesta es una opción no deseada.
|
||||
|
||||
**Ejemplo programático**
|
||||
|
||||
En este ejemplo, estamos lanzando cohetes espaciales y desplegando vehículos lunares.
|
||||
|
||||
La aplicación demuestra lo que hace el patrón de invocación del método asíncrono. Las partes clave del patrón son
|
||||
`AsyncResult` que es un contenedor intermedio para un valor evaluado de forma asíncrona,
|
||||
`AsyncCallback` que se puede proporcionar para que se ejecute al finalizar la tarea y `AsyncExecutor` que
|
||||
gestiona la ejecución de las tareas asíncronas.
|
||||
|
||||
```java
|
||||
public interface AsyncResult<T> {
|
||||
boolean isCompleted();
|
||||
T getValue() throws ExecutionException;
|
||||
void await() throws InterruptedException;
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
public interface AsyncCallback<T> {
|
||||
void onComplete(T value, Optional<Exception> ex);
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
public interface AsyncExecutor {
|
||||
<T> AsyncResult<T> startProcess(Callable<T> task);
|
||||
<T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback);
|
||||
<T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException;
|
||||
}
|
||||
```
|
||||
|
||||
`ThreadAsyncExecutor` es una implementación de `AsyncExecutor`. Se destacan algunas de sus partes clave a continuación.
|
||||
|
||||
```java
|
||||
public class ThreadAsyncExecutor implements AsyncExecutor {
|
||||
|
||||
@Override
|
||||
public <T> AsyncResult<T> startProcess(Callable<T> task) {
|
||||
return startProcess(task, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback) {
|
||||
var result = new CompletableResult<>(callback);
|
||||
new Thread(
|
||||
() -> {
|
||||
try {
|
||||
result.setValue(task.call());
|
||||
} catch (Exception ex) {
|
||||
result.setException(ex);
|
||||
}
|
||||
},
|
||||
"executor-" + idx.incrementAndGet())
|
||||
.start();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T endProcess(AsyncResult<T> asyncResult)
|
||||
throws ExecutionException, InterruptedException {
|
||||
if (!asyncResult.isCompleted()) {
|
||||
asyncResult.await();
|
||||
}
|
||||
return asyncResult.getValue();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ahora está todo preparado para lanzar algunos cohetes y así poder ver cómo funciona todo.
|
||||
|
||||
```java
|
||||
public static void main(String[] args) throws Exception {
|
||||
// construye un nuevo objeto executor que ejecutará tareas asíncronas
|
||||
var executor = new ThreadAsyncExecutor();
|
||||
|
||||
// inicia algunas tareas asíncronas con diferentes tiempos de procesamiento, las dos últimas con controladores de devolución de llamada
|
||||
final var asyncResult1 = executor.startProcess(lazyval(10, 500));
|
||||
final var asyncResult2 = executor.startProcess(lazyval("test", 300));
|
||||
final var asyncResult3 = executor.startProcess(lazyval(50L, 700));
|
||||
final var asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Desplegando el rover lunar"));
|
||||
final var asyncResult5 =
|
||||
executor.startProcess(lazyval("devolución de llamada callback", 600), callback("Desplegando el rover lunar"));
|
||||
|
||||
// emula el procesamiento en el hilo o subproceso actual mientras las tareas asíncronas se ejecutan en sus propios hilos o subprocesos
|
||||
Subproceso.dormir(350); // Oye, estamos trabajando duro aquí
|
||||
log("El comandante de la misión está bebiendo café");
|
||||
|
||||
// espera a que se completen las tareas
|
||||
final var result1 = executor.endProcess(asyncResult1);
|
||||
final var result2 = executor.endProcess(asyncResult2);
|
||||
final var result3 = executor.endProcess(asyncResult3);
|
||||
asyncResult4.await();
|
||||
asyncResult5.await();
|
||||
|
||||
// registra los resultados de las tareas, las devoluciones de las llamadas se registran inmediatamente cuando se completan
|
||||
log("Cohete espacial <" + resultado1 + "> ha completado su lanzamiento");
|
||||
log("Cohete espacial <" + resultado2 + "> ha completado su lanzamiento");
|
||||
log("Cohete espacial <" + result3 + "> ha completado su lanzamiento");
|
||||
}
|
||||
```
|
||||
|
||||
Aquí está la salida de la consola del programa.
|
||||
|
||||
```java
|
||||
21:47:08.227 [executor-2] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <prueba> lanzado con éxito
|
||||
21:47:08.269 [main] INFO com.iluwatar.async.method.invocation.App - El comandante de la misión está bebiendo café
|
||||
21:47:08.318 [executor-4] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <20> lanzado con éxito
|
||||
21:47:08.335 [executor-4] INFO com.iluwatar.async.method.invocation.App Desplegando el rover lunar <20>
|
||||
21:47:08.414 [executor-1] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <10> lanzado con éxito
|
||||
21:47:08.519 [executor-5] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <devolución de llamada callback> lanzado con éxito
|
||||
21:47:08.519 [executor-5] INFO com.iluwatar.async.method.invocation.App - Implementando el vehículo lunar <devolución de llamada callback>
|
||||
21:47:08.616 [executor-3] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <50> lanzado con éxito
|
||||
21:47:08.617 [main] INFO com.iluwatar.async.method.invocation.App - Lanzamiento del cohete espacial <10> completado
|
||||
21:47:08.617 [main] INFO com.iluwatar.async.method.invocation.App - Lanzamiento de cohete espacial <prueba> completado
|
||||
21:47:08.618 [main] INFO com.iluwatar.async.method.invocation.App - Lanzamiento del cohete espacial <50> completado
|
||||
```
|
||||
|
||||
# Diagrama de clase
|
||||
|
||||

|
||||
|
||||
## Aplicabilidad
|
||||
|
||||
Utiliza el patrón de invocación del método asíncrono cuando
|
||||
|
||||
* Tienes múltiples tareas independientes que pueden ejecutarse en paralelo
|
||||
* Necesitas mejorar el desempeño de un grupo de tareas secuenciales
|
||||
* Tienes una cantidad limitada de capacidad de procesamiento o tareas de ejecución prolongada y la llamada no debe esperar a que las tareas estén listas
|
||||
|
||||
## Ejemplos cotidianos
|
||||
|
||||
* [FutureTask](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/FutureTask.html)
|
||||
* [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html)
|
||||
* [ExecutorService](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html)
|
||||
* [Patrón asíncrono basado en tareas](https://msdn.microsoft.com/en-us/library/hh873175.aspx)
|
||||
Reference in New Issue
Block a user