Skip to content

Commit 2ce919b

Browse files
committed
refactor: Apply SRP by separating concerns into distinct classes
This commit refactors the task tracker application to adhere to the Single Responsibility Principle (SRP). The original single-file or less structured code has been broken down into four distinct classes, each with a single, well-defined responsibility: - Task.java: Represents the Task data model, encapsulating task description and completion status. Its sole responsibility is to hold task information. - Task_Tracker.java: Manages the collection of Task objects. Its responsibilities are purely related to business logic: adding tasks, marking tasks as complete, and providing access to task data. Console output has been removed from this class. - TaskConsoleView.java: Handles all console-based user interface interactions related to output. This includes displaying the menu, rendering the task list, and showing informational messages or prompts. - TaskTrackerApp.java: Serves as the application's entry point and controller. It manages the main application loop, handles user input (via Scanner), and orchestrates the interactions between the TaskTracker (model) and TaskConsoleView (view). This separation improves code modularity, enhances testability for each component, and increases maintainability by ensuring that changes to one aspect (e.g., UI presentation) are less likely to impact other unrelated aspects (e.g., task management logic).
1 parent c15d7e5 commit 2ce919b

File tree

4 files changed

+183
-75
lines changed

4 files changed

+183
-75
lines changed

Task_Tracker/Task.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package Task_Tracker;
2+
import java.util.ArrayList;
3+
import java.util.Scanner;
4+
5+
public class Task {
6+
private String description;
7+
private boolean completed;
8+
9+
public Task(String description) {
10+
this.description = description;
11+
this.completed = false;
12+
}
13+
14+
public String getDescription() {
15+
return description;
16+
}
17+
18+
public boolean isCompleted() {
19+
return completed;
20+
}
21+
22+
public void markCompleted() {
23+
completed = true;
24+
}
25+
26+
// For easier debugging or direct object printing if needed elsewhere
27+
@Override
28+
public String toString() {
29+
return description + (completed ? " - Completed" : "");
30+
}
31+
}

Task_Tracker/TaskConsoleView.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package Task_Tracker;
2+
import java.util.List;
3+
4+
public class TaskConsoleView {
5+
6+
// Responsibility: Display the list of tasks.
7+
public void displayTasks(List<Task> tasks) {
8+
System.out.println("\nTask List:");
9+
if (tasks.isEmpty()) {
10+
System.out.println("No tasks available.");
11+
return;
12+
}
13+
for (int i = 0; i < tasks.size(); i++) {
14+
Task task = tasks.get(i);
15+
// Using getDescription() and isCompleted() from Task object
16+
System.out.println((i + 1) + ". " + task.getDescription() +
17+
(task.isCompleted() ? " - Completed" : ""));
18+
}
19+
}
20+
21+
// Responsibility: Display the application menu.
22+
public void displayMenu() {
23+
System.out.println("\n1. Add Task\n2. Mark Task as Completed\n3. Display Tasks\n4. Exit");
24+
System.out.print("Choose an option: ");
25+
}
26+
27+
// Responsibility: Display a generic message.
28+
public void showMessage(String message) {
29+
System.out.println(message);
30+
}
31+
32+
// Responsibility: Return the prompt string for task description.
33+
public String getTaskDescriptionPrompt() {
34+
return "Enter task description: ";
35+
}
36+
37+
// Responsibility: Return the prompt string for task index.
38+
public String getTaskIndexPrompt() {
39+
return "Enter the index of the task to mark as completed: ";
40+
}
41+
}

Task_Tracker/TaskTrackerApp.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package Task_Tracker;
2+
import java.util.Scanner;
3+
import java.util.List;
4+
5+
public class TaskTrackerApp {
6+
public static void main(String[] args) {
7+
TaskTracker taskTracker = new TaskTracker();
8+
TaskConsoleView taskView = new TaskConsoleView();
9+
Scanner scanner = new Scanner(System.in); // Input handling primarily here
10+
11+
while (true) {
12+
taskView.displayMenu();
13+
14+
int choice = -1;
15+
if (scanner.hasNextInt()) {
16+
choice = scanner.nextInt();
17+
} else {
18+
taskView.showMessage("Invalid input. Please enter a number.");
19+
scanner.next(); // Consume invalid input
20+
continue; // Go back to the start of the loop
21+
}
22+
scanner.nextLine(); // Consume the newline character
23+
24+
switch (choice) {
25+
case 1:
26+
taskView.showMessage(taskView.getTaskDescriptionPrompt()); // Show prompt via view
27+
String description = scanner.nextLine();
28+
if (taskTracker.addTask(description)) {
29+
taskView.showMessage("Task added: " + description);
30+
} else {
31+
// This case might be relevant if addTask could fail for other reasons in a more complex app
32+
taskView.showMessage("Failed to add task.");
33+
}
34+
break;
35+
36+
case 2:
37+
if (taskTracker.getTasks().isEmpty()) {
38+
taskView.showMessage("No tasks to mark. Add a task first.");
39+
break;
40+
}
41+
taskView.showMessage(taskView.getTaskIndexPrompt()); // Show prompt via view
42+
int indexToMarkInput = -1;
43+
if (scanner.hasNextInt()) {
44+
indexToMarkInput = scanner.nextInt();
45+
scanner.nextLine(); // Consume newline
46+
47+
int actualIndex = indexToMarkInput - 1; // Adjust for 0-based indexing
48+
Task taskToMark = taskTracker.getTask(actualIndex);
49+
50+
if (taskToMark != null) { // Check if task exists at index
51+
if (taskToMark.isCompleted()){
52+
taskView.showMessage("Task '" + taskToMark.getDescription() + "' is already completed.");
53+
} else {
54+
if (taskTracker.markTaskCompleted(actualIndex)) {
55+
taskView.showMessage("Task marked as completed: " + taskToMark.getDescription());
56+
} else {
57+
// This path should ideally not be hit if getTask returned non-null
58+
// and markTaskCompleted only fails on bad index, which we checked.
59+
// Kept for robustness in case logic changes.
60+
taskView.showMessage("Failed to mark task as completed.");
61+
}
62+
}
63+
} else {
64+
taskView.showMessage("Invalid task index.");
65+
}
66+
} else {
67+
taskView.showMessage("Invalid input for index. Please enter a number.");
68+
if(scanner.hasNextLine()) scanner.nextLine(); // Consume invalid input
69+
}
70+
break;
71+
72+
case 3:
73+
taskView.displayTasks(taskTracker.getTasks());
74+
break;
75+
76+
case 4:
77+
taskView.showMessage("Exiting the Task Tracker. Goodbye!");
78+
scanner.close(); // Close scanner on exit
79+
System.exit(0);
80+
break; // Not strictly necessary after System.exit(0) but good practice
81+
82+
default:
83+
taskView.showMessage("Invalid choice. Please choose a valid option.");
84+
}
85+
}
86+
}
87+
}

Task_Tracker/Task_Tracker.java

Lines changed: 24 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,46 @@
1+
package Task_Tracker;
12
import java.util.ArrayList;
2-
import java.util.Scanner;
3+
import java.util.List;
4+
import java.util.Collections;
35

4-
class Task {
5-
private String description;
6-
private boolean completed;
7-
8-
public Task(String description) {
9-
this.description = description;
10-
this.completed = false;
11-
}
12-
13-
public String getDescription() {
14-
return description;
15-
}
16-
17-
public boolean isCompleted() {
18-
return completed;
19-
}
20-
21-
public void markCompleted() {
22-
completed = true;
23-
}
24-
}
25-
26-
class TaskTracker {
6+
public class TaskTracker {
277
private ArrayList<Task> tasks;
288

299
public TaskTracker() {
3010
tasks = new ArrayList<>();
3111
}
3212

33-
public void addTask(String description) {
13+
// Responsibility: Add a task to the list.
14+
// Returns true if added successfully.
15+
public boolean addTask(String description) {
3416
Task newTask = new Task(description);
3517
tasks.add(newTask);
36-
System.out.println("Task added: " + description);
18+
return true;
3719
}
3820

39-
public void markTaskCompleted(int index) {
21+
// Responsibility: Mark a task as completed.
22+
// Returns true if task was found and marked, false otherwise.
23+
public boolean markTaskCompleted(int index) {
4024
if (index >= 0 && index < tasks.size()) {
4125
Task task = tasks.get(index);
4226
task.markCompleted();
43-
System.out.println("Task marked as completed: " + task.getDescription());
44-
} else {
45-
System.out.println("Invalid task index.");
27+
return true;
4628
}
29+
return false;
4730
}
4831

49-
public void displayTasks() {
50-
System.out.println("Task List:");
51-
for (int i = 0; i < tasks.size(); i++) {
52-
Task task = tasks.get(i);
53-
System.out.println((i + 1) + ". " + task.getDescription() +
54-
(task.isCompleted() ? " - Completed" : ""));
55-
}
32+
// Responsibility: Provide access to the list of tasks.
33+
// Returns an unmodifiable list to prevent external modification.
34+
public List<Task> getTasks() {
35+
return Collections.unmodifiableList(tasks); // Return a read-only view
5636
}
57-
}
58-
59-
public class TaskTrackerApp {
60-
public static void main(String[] args) {
61-
TaskTracker taskTracker = new TaskTracker();
62-
Scanner scanner = new Scanner(System.in);
63-
64-
while (true) {
65-
System.out.println("\n1. Add Task\n2. Mark Task as Completed\n3. Display Tasks\n4. Exit");
66-
System.out.print("Choose an option: ");
67-
68-
int choice = scanner.nextInt();
69-
scanner.nextLine(); // Consume the newline character
70-
71-
switch (choice) {
72-
case 1:
73-
System.out.print("Enter task description: ");
74-
String description = scanner.nextLine();
75-
taskTracker.addTask(description);
76-
break;
7737

78-
case 2:
79-
System.out.print("Enter the index of the task to mark as completed: ");
80-
int index = scanner.nextInt();
81-
taskTracker.markTaskCompleted(index - 1); // Adjust index for user input
82-
break;
83-
84-
case 3:
85-
taskTracker.displayTasks();
86-
break;
87-
88-
case 4:
89-
System.out.println("Exiting the Task Tracker. Goodbye!");
90-
System.exit(0);
91-
92-
default:
93-
System.out.println("Invalid choice. Please choose a valid option.");
94-
}
38+
// Responsibility: Get a specific task by index.
39+
// Returns the Task object or null if index is invalid.
40+
public Task getTask(int index) {
41+
if (index >= 0 && index < tasks.size()) {
42+
return tasks.get(index);
9543
}
44+
return null;
9645
}
97-
}
46+
}

0 commit comments

Comments
 (0)