Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* 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>
- Loading branch information
1 parent
a612387
commit 84f7ab8
Showing
2 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
||
![texto alternativo](./etc/async-method-invocation.png "Invocación de método asíncrono") | ||
|
||
## 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) |