Contenido del Curso
Java Data Structures
2. Additional Data Structures
Java Data Structures
Queue Practice
Practice
It's time to practice. You are given a task to write a TaskManager
service that will keep track of your tasks. With this service, the user can add tasks, assign them to themselves, and then complete them in a sequential order. Let's start working on this task together, and then you'll continue on your own.
Note
In this assignment, we will use the interface-implementation structure. First, we'll write an interface that will define the methods to be implemented by the inheriting classes.
But first, we need to create the task model itself. Let's create a Task
class:
main.java
The Task
class contains 3 attributes: id
, name
, and description
. Each task must have a name and description, and id
is a necessary attribute for any data structure. How else would we access the elements?
The attributes are also protected by the private
access modifier because we don't want other classes to have direct access to the fields of this class, except through the constructor or getters.
Now, let's implement these getters and the constructor. This can be easily done using the combination of key control + return on a MacBook.
After the performed operations, we have the following Task
class:
Task.java
Services
We will have a very simplified task board service, so let's implement a service that will add, mark as completed, and check if there are tasks in the queue. Let's call this class TaskQueueService
. To begin with, we need to define an interface with these tasks:
TaskQueueService.TaskQueueService
This interface defines 3 methods that implementation classes must implement. These methods include adding a task, moving to the next task (implying that the user has already completed the previous task), and a method to check if there are tasks in the queue.
Great, let's now create an implementation class that will override and implement all these methods:
TaskQueueServiceImpl.TaskQueueServiceImpl
We create a private
attribute that will be used only in this service class.
It's worth making a small digression and talking about service classes, which are a separate part of OOP. Service classes are created to perform specific operations. They inherit from service interfaces and implement their methods. This approach to writing an application helps maintain and extend it while adhering to the SOLID principles, which we will study in a separate course. At the moment, it's important to understand that such classes are created solely to perform operations on other objects.
For example: If we write a calculator, we will have a separate class that will store the value of the number we operate on. The actual operations will be performed using a service class where addition, subtraction, and so on are defined.
I hope this clarifies the purpose of service classes in solving the task at hand.
Service Implementation
Let's continue the task execution. Our next task is to show that this class implements the TaskQueueService
interface. To do this, we use the keyword implements
and specify the interface that the class implements. We also need to override the methods defined by the interface. IntelliJ IDEA also allows us to significantly simplify this task using the combination option + return.
Now, in our class, all the methods that need to be overridden are shown. Let's go ahead and do it!
TaskQueueServiceImpl.java
In our case, nothing overly complicated was done. We simply used the methods of the Queue
class to implement our methods correctly. Thus, a data structure like a queue makes life easier for all Java programmers.
We use the offer()
method for adding, the poll()
method for removal, and the isEmpty()
method to check if the queue is empty.
Now it's your turn to play a role in solving this problem. You'll need to implement a service class, the interface of which we will create together:
main.java
We've created a service interface with one method: processTasks()
, which, when invoked, should start executing all tasks until the task list is empty. This method represents a user starting to perform tasks.
Note
If you want to make the task a bit more challenging, you can add a method for processing a single task. In that case, you need to create a separate method,
processTask()
, in this interface. This method should process the first task in the list.
Task
Your task is to write a class TaskProcessorServiceImpl
that should implement the TaskProcessorService
interface. This class should have a method to process all tasks, meaning it should use methods from the TaskQueueService
service. You can use composition by creating an instance of this class within the class you need to implement, for example:
main.java
In general, there is already a prepared composition at the top for your task. Next, you just need to implement one method using an instance of this class.
After that, you need to create a constructor that will initialize this object of the taskQueueService
class.
This way, you'll be able to use the methods of this object. It's also evident that, for task processing, you need to pass the queue with which the taskProcessor
will work.
The rest of the task is left to you. Hints will be provided in the README.md file. Once your solution is ready, click on the "Run Tests" button, and the unit tests I have written will check your solution.
TaskQueue
class. Then, also add its initialization in the constructor.TaskProcessorImpl
interface and override its methods.while
loop with the isEmpty()
method as the condition.while
loop, use the taskQueueService.getNextTask()
method, indicating that the task is completed. Output information to the screen using System.out.println()
- "Processing Task: " + task.¿Todo estuvo claro?
Contenido del Curso
Java Data Structures
2. Additional Data Structures
Java Data Structures
Queue Practice
Practice
It's time to practice. You are given a task to write a TaskManager
service that will keep track of your tasks. With this service, the user can add tasks, assign them to themselves, and then complete them in a sequential order. Let's start working on this task together, and then you'll continue on your own.
Note
In this assignment, we will use the interface-implementation structure. First, we'll write an interface that will define the methods to be implemented by the inheriting classes.
But first, we need to create the task model itself. Let's create a Task
class:
main.java
The Task
class contains 3 attributes: id
, name
, and description
. Each task must have a name and description, and id
is a necessary attribute for any data structure. How else would we access the elements?
The attributes are also protected by the private
access modifier because we don't want other classes to have direct access to the fields of this class, except through the constructor or getters.
Now, let's implement these getters and the constructor. This can be easily done using the combination of key control + return on a MacBook.
After the performed operations, we have the following Task
class:
Task.java
Services
We will have a very simplified task board service, so let's implement a service that will add, mark as completed, and check if there are tasks in the queue. Let's call this class TaskQueueService
. To begin with, we need to define an interface with these tasks:
TaskQueueService.TaskQueueService
This interface defines 3 methods that implementation classes must implement. These methods include adding a task, moving to the next task (implying that the user has already completed the previous task), and a method to check if there are tasks in the queue.
Great, let's now create an implementation class that will override and implement all these methods:
TaskQueueServiceImpl.TaskQueueServiceImpl
We create a private
attribute that will be used only in this service class.
It's worth making a small digression and talking about service classes, which are a separate part of OOP. Service classes are created to perform specific operations. They inherit from service interfaces and implement their methods. This approach to writing an application helps maintain and extend it while adhering to the SOLID principles, which we will study in a separate course. At the moment, it's important to understand that such classes are created solely to perform operations on other objects.
For example: If we write a calculator, we will have a separate class that will store the value of the number we operate on. The actual operations will be performed using a service class where addition, subtraction, and so on are defined.
I hope this clarifies the purpose of service classes in solving the task at hand.
Service Implementation
Let's continue the task execution. Our next task is to show that this class implements the TaskQueueService
interface. To do this, we use the keyword implements
and specify the interface that the class implements. We also need to override the methods defined by the interface. IntelliJ IDEA also allows us to significantly simplify this task using the combination option + return.
Now, in our class, all the methods that need to be overridden are shown. Let's go ahead and do it!
TaskQueueServiceImpl.java
In our case, nothing overly complicated was done. We simply used the methods of the Queue
class to implement our methods correctly. Thus, a data structure like a queue makes life easier for all Java programmers.
We use the offer()
method for adding, the poll()
method for removal, and the isEmpty()
method to check if the queue is empty.
Now it's your turn to play a role in solving this problem. You'll need to implement a service class, the interface of which we will create together:
main.java
We've created a service interface with one method: processTasks()
, which, when invoked, should start executing all tasks until the task list is empty. This method represents a user starting to perform tasks.
Note
If you want to make the task a bit more challenging, you can add a method for processing a single task. In that case, you need to create a separate method,
processTask()
, in this interface. This method should process the first task in the list.
Task
Your task is to write a class TaskProcessorServiceImpl
that should implement the TaskProcessorService
interface. This class should have a method to process all tasks, meaning it should use methods from the TaskQueueService
service. You can use composition by creating an instance of this class within the class you need to implement, for example:
main.java
In general, there is already a prepared composition at the top for your task. Next, you just need to implement one method using an instance of this class.
After that, you need to create a constructor that will initialize this object of the taskQueueService
class.
This way, you'll be able to use the methods of this object. It's also evident that, for task processing, you need to pass the queue with which the taskProcessor
will work.
The rest of the task is left to you. Hints will be provided in the README.md file. Once your solution is ready, click on the "Run Tests" button, and the unit tests I have written will check your solution.
TaskQueue
class. Then, also add its initialization in the constructor.TaskProcessorImpl
interface and override its methods.while
loop with the isEmpty()
method as the condition.while
loop, use the taskQueueService.getNextTask()
method, indicating that the task is completed. Output information to the screen using System.out.println()
- "Processing Task: " + task.¿Todo estuvo claro?