Exercise 2.4: Implementing Core Logic with Mock Data
1 Purpose
This exercise transitions from defining the structure of our application to breathing life into it. You will replace the method stubs from the previous exercise with functional code that uses mock data. This is a crucial step in software development, allowing us to build and test our application’s logic before connecting it to a real database or backend services.
2 What You’ll Accomplish
By the end of this exercise, you will have:
- Implemented a simple in-memory data store using an
ArrayList. - Replaced method stubs in your
TaskManagerclass with code that interacts with the in-memory store. - Gained hands-on experience with creating, retrieving, and managing objects.
- Understood the professional practice of using mock data for development and testing.
- 4. Problem-Solving and Critical Thinking:
- 4.1 Decompose complex problems into smaller, manageable components.
- 4.2 Develop and implement algorithms to solve computational problems.
- 5. Software Development Lifecycle:
- 5.2 Implement software solutions using a programming language.
- 5.3 Test and debug software applications to ensure they meet requirements.
- Learning Objectives:
- Implement methods to manipulate data in an
ArrayList. - Simulate backend functionality using in-memory data structures.
- Explain the benefits of mocking in the development process.
- Implement methods to manipulate data in an
- **Knowledge, Skills, and Abilities (KSAs) from O*NET:**
- 15-1251.00 - Computer Programmers:
- Knowledge of computer science principles and practices.
- Skill in writing computer programs for various purposes.
- Ability to apply analytical and logical thinking to solve problems.
- 15-1251.00 - Computer Programmers:
- Technologies:
- Java
- Object-Oriented Programming (OOP)
- ArrayList
- VSCode IDE
3 The “Why” Behind Mocking
In professional software development, the “frontend” (what the user sees and interacts with) and the “backend” (where data is stored and processed) are often developed by different teams at the same time. To avoid delays, frontend developers can’t wait for the backend to be finished. Instead, they work with a “mock” or “fake” backend.
This practice involves creating simple, temporary versions of backend methods that return predictable, hard-coded data. This is exactly what we’ll be doing today by using an ArrayList as a temporary, in-memory “database”.
Key benefits of this approach include:
- Parallel Work: Allows different parts of an application to be developed independently and simultaneously.
- Early Testing: You can test your application’s logic and user interface without needing a live database or network connection.
- Focus and Isolation: It lets you focus on one part of the problem at a time. When writing your
TaskManagerlogic, you don’t have to worry about database errors; you can trust your mock data source. - Rapid Prototyping: Enables you to build a functional prototype quickly to demonstrate features or get user feedback.
4 Step 1: Set Up the In-Memory “Database”
In your TaskManager class, the first step is to add a place to store your tasks. We’ll use an ArrayList for this. It’s a dynamic array that can grow as we add more tasks.
Add the following instance variable to the top of your TaskManager.java file:
import java.util.ArrayList;
import java.util.List;
public class TaskManager {
private List<Task> taskStore = new ArrayList<>();
// ... other methods will go here
}This taskStore list will act as our temporary database. Every task we create will be added to this list.
5 Step 2: Implement the addTask Method
Previously, your addTask method was likely a stub that did nothing or just printed a message. Now, let’s implement it to actually add a Task object to our taskStore.
Here’s an example implementation. You’ll notice we’re also creating a simple way to assign a unique ID to each task.
public class TaskManager {
private List<Task> taskStore = new ArrayList<>();
private Long nextTaskId = 1;
/**
* Adds a new task to the task store.
* @param task The task to be added.
*/
public void addTask(Task task) {
// Assign a unique ID and add the task to our in-memory store
task.setId(nextTaskId);
taskStore.add(task);
nextTaskId++; // Increment the ID for the next task
System.out.println("Task added: " + task.getTitle());
}
// ... other methods
}6 Step 3: Implement the getTasks Method
This method should simply return the list of all tasks currently in our taskStore. This allows other parts of our application (like a future user interface) to display the tasks.
public class TaskManager {
// ... other variables and methods
/**
* Retrieves all tasks from the store.
* @return A list of all tasks.
*/
public List<Task> getTasks() {
System.out.println("Retrieving all tasks...");
return taskStore;
}
// ... other methods
}7 Your Turn: Implement updateTask and deleteTask
Now it’s your turn to apply what you’ve learned. Using the addTask and getTasks methods as a guide, implement the following methods in your TaskManager class:
updateTask(Task updatedTask): This method should find the existing task intaskStorewith the same ID asupdatedTaskand replace it.deleteTask(Long taskId): This method should find the task with the giventaskIdintaskStoreand remove it.
Hints:
- You will need to loop through the
taskStorelist. - For
updateTask, you might need to find the index of the task to update and use theset(index, element)method of theArrayList. - For
deleteTask, theremoveIf(filter)method of theArrayListis a clean and efficient way to remove an element that matches a certain condition.
8 Step 4: Test Your Implementation
Update your main method in App.java to test your new functionality. Create a few tasks, add them to the manager, print them, update one, delete one, and print the list again to see the results.
Example main method:
public class App {
public static void main(String[] args) {
TaskManager manager = new TaskManager();
System.out.println("--- Adding Tasks ---");
manager.addTask(new Task("Buy groceries", "Milk, Bread, Eggs"));
manager.addTask(new Task("Finish Exercise 2.4", "Implement update and delete methods"));
System.out.println("\n--- Current Tasks ---");
List<Task> tasks = manager.getTasks();
for (Task task : tasks) {
System.out.println("ID: " + task.getId() + ", Title: " + task.getTitle());
}
// Your testing code for update and delete will go here!
// Example:
// Task updated = new Task(...);
// updated.setId(1); // Make sure to set the ID of the task you want to update
// manager.updateTask(updated);
// manager.deleteTask(2);
System.out.println("\n--- Final Tasks ---");
// Print tasks again to see your changes
}
}9 Reflect and Review
- 3 Things I Learned: List three new concepts or skills you learned from this exercise.
- 2 Things I Found Interesting: Mention two aspects of mocking or data management that you found particularly interesting.
- 1 Question I Still Have: Write down one question you have about the material covered.
- Why is it beneficial for developers to use mock data and stubbed methods?
- What is the difference between an
ArrayListand a simple array ([]) in Java? - How would you find a specific
Taskin thetaskStoreArrayListif you only had itsid? Describe the steps you would take in your code.