Práctica de Cola
Práctica
Es hora de practicar. Se te asigna la tarea de escribir un servicio
TaskManager` que lleve la cuenta de tus tareas. Con este servicio, el usuario puede añadir tareas, asignárselas a sí mismo, y luego completarlas en un orden secuencial. Vamos a empezar a trabajar en esta tarea juntos, y luego continuarás por tu cuenta.
Nota
En esta tarea, utilizaremos la estructura interfaz-implementación. Primero, escribiremos una interfaz que definirá los métodos que implementarán las clases herederas.
Pero primero, tenemos que crear el modelo de tarea en sí. Vamos a crear una clase Task
:
main.java
12345public class Task { private int id; private String name; private String description; }
La clase Task
contiene 3 atributos: id
, name
, y description
. Cada tarea debe tener un nombre y una descripción, y id
es un atributo necesario para cualquier estructura de datos. *Si no, ¿cómo podríamos acceder a los elementos?
Los atributos también están protegidos por el modificador de acceso private
porque no queremos que otras clases tengan acceso directo a los campos de esta clase, excepto a través del constructor o getters.
Ahora, implementemos estos getters y el constructor. Esto puede hacerse fácilmente usando la combinación de teclas control + return en un MacBook.
Después de las operaciones realizadas, tenemos la siguiente clase Task
:
Task.java
12345678910111213141516171819202122232425262728293031323334package codefinity.taskManager; public class Task { private int id; private String name; private String description; public Task(int id, String name, String description) { this.id = id; this.name = name; this.description = description; } public int getId() { return id; } public String getName() { return name; } public String getDescription() { return description; } @Override public String toString() { return "Task{" + "id=" + id + ", name='" + name + '\'' + ", description='" + description + '\'' + '}'; } }
Servicios
Tendremos un servicio de cola de tareas muy simplificado, así que implementemos un servicio que añada, marque como completada, y compruebe si hay tareas en la cola. Llamemos a esta clase TaskQueueService
. Para empezar, necesitamos definir una interfaz con estas tareas:
TaskQueueService.TaskQueueService
123456789package codefinity.taskManager; public interface TaskQueueService { void addTask(Task task); Task getNextTask(); boolean isEmpty(); }
Esta interfaz define 3 métodos que las clases de implementación deben implementar. Estos métodos incluyen añadir una tarea, pasar a la siguiente tarea (lo que implica que el usuario ya ha completado la tarea anterior), y un método para comprobar si hay tareas en la cola.
Genial, creemos ahora una clase de implementación que sobrescribirá e implementará todos estos métodos:
TaskQueueServiceImpl.TaskQueueServiceImpl
12345678910package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.Task; import java.util.LinkedList; import java.util.Queue; public class TaskQueueServiceImpl { private Queue<Task> taskQueue = new LinkedList<>(); }
Creamos un atributo private
que sólo se utilizará en esta clase de servicio.
Vale la pena hacer una pequeña digresión y hablar de las clases de servicio, que son una parte separada de la programación orientada a objetos. Las clases de servicio se crean para realizar operaciones específicas. Heredan de las interfaces de servicio y implementan sus métodos. Este enfoque para escribir una aplicación ayuda a mantenerla y extenderla mientras se adhiere a los principios SOLID, que estudiaremos en un curso aparte. Por el momento, es importante entender que tales clases se crean solamente para realizar operaciones sobre otros objetos.
Por ejemplo: Si escribimos una calculadora, tendremos una clase aparte que almacenará el valor de el número sobre el que operamos. Las operaciones propiamente dichas se realizarán utilizando una clase de servicio donde se definen sumar, restar, etc.
Espero que esto aclare el propósito de las clases de servicio para resolver la tarea que nos ocupa.
Implantación del servicio
Vamos a continuar con la ejecución de la tarea. Nuestra siguiente tarea es mostrar que esta clase implementa la interfaz TaskQueueService
. Para ello, utilizamos la palabra clave implements
y especificamos la interfaz que implementa la clase. También necesitamos override los métodos definidos por la interfaz. IntelliJ IDEA también nos permite simplificar significativamente esta tarea utilizando la combinación option + return.
Ahora, en nuestra clase, se muestran todos los métodos que necesitan ser sobreescritos. ¡Vamos a hacerlo!
TaskQueueServiceImpl.java
1234567891011121314151617181920212223242526package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.Task; import codefinity.taskManager.TaskQueueService; import java.util.LinkedList; import java.util.Queue; public class TaskQueueServiceImpl implements TaskQueueService { private Queue<Task> taskQueue = new LinkedList<>(); @Override public void addTask(Task task) { taskQueue.offer(task); } @Override public Task getNextTask() { return taskQueue.poll(); } @Override public boolean isEmpty() { return taskQueue.isEmpty(); } }
En nuestro caso, no se hizo nada excesivamente complicado. Simplemente utilizamos los métodos de la clase Queue
para implementar nuestros métodos correctamente. Así, una estructura de datos como una cola facilita la vida a todos los programadores Java.
Utilizamos el método offer()
para añadir, el método poll()
para eliminar, y el método isEmpty()
para comprobar si la cola está vacía.
Ahora es tu turno de jugar un papel en la solución de este problema. Necesitarás implementar una clase de servicio, cuya interfaz crearemos juntos:
main.java
12345package codefinity.taskManager; public interface TaskProcessorService { void processTasks(); }
Hemos creado una interfaz de servicio con un método: processTasks()
, que, cuando se invoca, debe empezar a ejecutar todas las tareas hasta que la lista de tareas esté vacía. Este método representa a un usuario comenzando a realizar tareas.
Nota
Si quieres hacer la tarea un poco más difícil, puedes añadir un método para procesar una sola tarea. En ese caso, necesitas crear un método separado,
processTask()
, en esta interfaz. Este método debe procesar la primera tarea de la lista.
Tarea
Tu tarea es escribir una clase TaskProcessorServiceImpl
que implemente la interfaz TaskProcessorService
. Esta clase debe tener un método para procesar todas las tareas, lo que significa que debe utilizar métodos del servicio TaskQueueService
. Puedes utilizar la composición creando una instancia de esta clase dentro de la clase que necesitas implementar, por ejemplo:
main.java
1234567package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.TaskQueueService; public class TaskProcessorServiceImpl { TaskQueueService taskQueueService = new TaskQueueServiceImpl(); }
En general, ya hay una composición preparada en la parte superior para tu tarea. A continuación, sólo tienes que implementar un método utilizando una instancia de esta clase.
Después de eso, necesitas crear un constructor que inicializará este objeto de la clase taskQueueService
.
De esta forma, podrás utilizar los métodos de este objeto. También es evidente que, para procesar las tareas, necesitas pasar la cola con la que trabajará el taskProcessor
.
El resto de la tarea se deja a usted. En el archivo README.md se proporcionan sugerencias. Una vez que tu solución esté lista, haz clic en el botón "Run Tests", y las pruebas unitarias que he escrito comprobarán tu solución.
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla
Awesome!
Completion rate improved to 4
Práctica de Cola
Desliza para mostrar el menú
Práctica
Es hora de practicar. Se te asigna la tarea de escribir un servicio
TaskManager` que lleve la cuenta de tus tareas. Con este servicio, el usuario puede añadir tareas, asignárselas a sí mismo, y luego completarlas en un orden secuencial. Vamos a empezar a trabajar en esta tarea juntos, y luego continuarás por tu cuenta.
Nota
En esta tarea, utilizaremos la estructura interfaz-implementación. Primero, escribiremos una interfaz que definirá los métodos que implementarán las clases herederas.
Pero primero, tenemos que crear el modelo de tarea en sí. Vamos a crear una clase Task
:
main.java
12345public class Task { private int id; private String name; private String description; }
La clase Task
contiene 3 atributos: id
, name
, y description
. Cada tarea debe tener un nombre y una descripción, y id
es un atributo necesario para cualquier estructura de datos. *Si no, ¿cómo podríamos acceder a los elementos?
Los atributos también están protegidos por el modificador de acceso private
porque no queremos que otras clases tengan acceso directo a los campos de esta clase, excepto a través del constructor o getters.
Ahora, implementemos estos getters y el constructor. Esto puede hacerse fácilmente usando la combinación de teclas control + return en un MacBook.
Después de las operaciones realizadas, tenemos la siguiente clase Task
:
Task.java
12345678910111213141516171819202122232425262728293031323334package codefinity.taskManager; public class Task { private int id; private String name; private String description; public Task(int id, String name, String description) { this.id = id; this.name = name; this.description = description; } public int getId() { return id; } public String getName() { return name; } public String getDescription() { return description; } @Override public String toString() { return "Task{" + "id=" + id + ", name='" + name + '\'' + ", description='" + description + '\'' + '}'; } }
Servicios
Tendremos un servicio de cola de tareas muy simplificado, así que implementemos un servicio que añada, marque como completada, y compruebe si hay tareas en la cola. Llamemos a esta clase TaskQueueService
. Para empezar, necesitamos definir una interfaz con estas tareas:
TaskQueueService.TaskQueueService
123456789package codefinity.taskManager; public interface TaskQueueService { void addTask(Task task); Task getNextTask(); boolean isEmpty(); }
Esta interfaz define 3 métodos que las clases de implementación deben implementar. Estos métodos incluyen añadir una tarea, pasar a la siguiente tarea (lo que implica que el usuario ya ha completado la tarea anterior), y un método para comprobar si hay tareas en la cola.
Genial, creemos ahora una clase de implementación que sobrescribirá e implementará todos estos métodos:
TaskQueueServiceImpl.TaskQueueServiceImpl
12345678910package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.Task; import java.util.LinkedList; import java.util.Queue; public class TaskQueueServiceImpl { private Queue<Task> taskQueue = new LinkedList<>(); }
Creamos un atributo private
que sólo se utilizará en esta clase de servicio.
Vale la pena hacer una pequeña digresión y hablar de las clases de servicio, que son una parte separada de la programación orientada a objetos. Las clases de servicio se crean para realizar operaciones específicas. Heredan de las interfaces de servicio y implementan sus métodos. Este enfoque para escribir una aplicación ayuda a mantenerla y extenderla mientras se adhiere a los principios SOLID, que estudiaremos en un curso aparte. Por el momento, es importante entender que tales clases se crean solamente para realizar operaciones sobre otros objetos.
Por ejemplo: Si escribimos una calculadora, tendremos una clase aparte que almacenará el valor de el número sobre el que operamos. Las operaciones propiamente dichas se realizarán utilizando una clase de servicio donde se definen sumar, restar, etc.
Espero que esto aclare el propósito de las clases de servicio para resolver la tarea que nos ocupa.
Implantación del servicio
Vamos a continuar con la ejecución de la tarea. Nuestra siguiente tarea es mostrar que esta clase implementa la interfaz TaskQueueService
. Para ello, utilizamos la palabra clave implements
y especificamos la interfaz que implementa la clase. También necesitamos override los métodos definidos por la interfaz. IntelliJ IDEA también nos permite simplificar significativamente esta tarea utilizando la combinación option + return.
Ahora, en nuestra clase, se muestran todos los métodos que necesitan ser sobreescritos. ¡Vamos a hacerlo!
TaskQueueServiceImpl.java
1234567891011121314151617181920212223242526package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.Task; import codefinity.taskManager.TaskQueueService; import java.util.LinkedList; import java.util.Queue; public class TaskQueueServiceImpl implements TaskQueueService { private Queue<Task> taskQueue = new LinkedList<>(); @Override public void addTask(Task task) { taskQueue.offer(task); } @Override public Task getNextTask() { return taskQueue.poll(); } @Override public boolean isEmpty() { return taskQueue.isEmpty(); } }
En nuestro caso, no se hizo nada excesivamente complicado. Simplemente utilizamos los métodos de la clase Queue
para implementar nuestros métodos correctamente. Así, una estructura de datos como una cola facilita la vida a todos los programadores Java.
Utilizamos el método offer()
para añadir, el método poll()
para eliminar, y el método isEmpty()
para comprobar si la cola está vacía.
Ahora es tu turno de jugar un papel en la solución de este problema. Necesitarás implementar una clase de servicio, cuya interfaz crearemos juntos:
main.java
12345package codefinity.taskManager; public interface TaskProcessorService { void processTasks(); }
Hemos creado una interfaz de servicio con un método: processTasks()
, que, cuando se invoca, debe empezar a ejecutar todas las tareas hasta que la lista de tareas esté vacía. Este método representa a un usuario comenzando a realizar tareas.
Nota
Si quieres hacer la tarea un poco más difícil, puedes añadir un método para procesar una sola tarea. En ese caso, necesitas crear un método separado,
processTask()
, en esta interfaz. Este método debe procesar la primera tarea de la lista.
Tarea
Tu tarea es escribir una clase TaskProcessorServiceImpl
que implemente la interfaz TaskProcessorService
. Esta clase debe tener un método para procesar todas las tareas, lo que significa que debe utilizar métodos del servicio TaskQueueService
. Puedes utilizar la composición creando una instancia de esta clase dentro de la clase que necesitas implementar, por ejemplo:
main.java
1234567package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.TaskQueueService; public class TaskProcessorServiceImpl { TaskQueueService taskQueueService = new TaskQueueServiceImpl(); }
En general, ya hay una composición preparada en la parte superior para tu tarea. A continuación, sólo tienes que implementar un método utilizando una instancia de esta clase.
Después de eso, necesitas crear un constructor que inicializará este objeto de la clase taskQueueService
.
De esta forma, podrás utilizar los métodos de este objeto. También es evidente que, para procesar las tareas, necesitas pasar la cola con la que trabajará el taskProcessor
.
El resto de la tarea se deja a usted. En el archivo README.md se proporcionan sugerencias. Una vez que tu solución esté lista, haz clic en el botón "Run Tests", y las pruebas unitarias que he escrito comprobarán tu solución.
¡Gracias por tus comentarios!