Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Utmaning: Implementering av en Taskmanager-tjänst | Avancerade Datastrukturer i Java
Java Datastrukturer

bookUtmaning: Implementering av en Taskmanager-tjänst

Övning

Det är dags att öva. Du har som uppgift att skriva en TaskManager tjänst som håller reda på dina uppgifter.

Med denna tjänst kan användaren lägga till uppgifter, tilldela dem till sig själv och sedan slutföra dem i sekventiell ordning.

Låt oss påbörja detta arbete tillsammans, och sedan fortsätter du på egen hand.

Men först behöver du skapa själva uppgiftsmodellen. Skapa en Task-klass:

Main.java

Main.java

copy
12345
public class Task { private int id; private String name; private String description; }

Klassen Task innehåller tre attribut: id, name och description. Varje uppgift måste ha ett namn och en beskrivning, och id är ett nödvändigt attribut för varje datastruktur.

Hur skulle du annars komma åt elementen? Attributen är också skyddade av åtkomstmodifieraren private eftersom du inte vill att andra klasser ska ha direkt åtkomst till fälten i denna klass, förutom via konstruktorn eller getters.

Nu ska vi implementera dessa getters och konstruktorn. Detta kan enkelt göras med kombinationen Control + Return på en MacBook eller Alt + Ins på en Windows.

Efter de utförda operationerna har du följande Task-klass:

Task.java

Task.java

copy
12345678910111213141516171819202122232425262728293031323334
package 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 + '\'' + '}'; } }

Tjänster

Du kommer att ha en mycket förenklad task board-tjänst, så låt oss implementera en tjänst som kan lägga till uppgifter, markera dem som slutförda och kontrollera om det finns uppgifter i kön.

Vi kallar denna klass för TaskQueueService. Till att börja med behöver vi definiera ett interface med dessa uppgifter:

TaskQueueService.java

TaskQueueService.java

copy
123456789
package codefinity.taskManager; public interface TaskQueueService { void addTask(Task task); Task getNextTask(); boolean isEmpty(); }

Detta interface definierar 3 metoder som implementeringsklasser måste implementera. Dessa metoder inkluderar att lägga till en uppgift, gå vidare till nästa uppgift (vilket innebär att användaren redan har slutfört föregående uppgift), samt en metod för att kontrollera om det finns uppgifter i kön.

Utmärkt, låt oss nu skapa en implementeringsklass som kommer att åsidosätta och implementera alla dessa metoder:

TaskQueueServiceImpl.java

TaskQueueServiceImpl.java

copy
12345678910
package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.Task; import java.util.LinkedList; import java.util.Queue; public class TaskQueueServiceImpl { private Queue<Task> taskQueue = new LinkedList<>(); }

Vi skapar ett privat attribut som endast kommer att användas inom denna serviceklass.

Det är värt att göra en kort avstickare för att prata om serviceklasser, som spelar en nyckelroll inom OOP.

Vad är serviceklasser?

Serviceklasser är utformade för att utföra specifika operationer. De ärver från servicegränssnitt och implementerar deras metoder. Detta tillvägagångssätt förbättrar kodens underhållbarhet och skalbarhet samtidigt som det följer SOLID-principerna, vilka du kommer att utforska i en separat kurs.

För närvarande är det viktigt att förstå att serviceklasser enbart existerar för att utföra operationer på andra objekt.

Till exempel, Om du skriver en kalkylator kommer du att ha en separat klass som lagrar värdet av det tal du arbetar med. De faktiska operationerna utförs med hjälp av en serviceklass där addition, subtraktion och så vidare är definierade.

Jag hoppas detta klargör syftet med serviceklasser i lösningen av denna uppgift.

Implementering av service

Vårt nästa steg är att tydligt visa att denna klass implementerar gränssnittet TaskQueueService.

För att uppnå detta använder vi nyckelordet implements följt av gränssnittsnamnet. Detta säkerställer att vår klass ärver det beteende som definieras av gränssnittet.

Eftersom gränssnitt endast tillhandahåller metoddeklarationer måste du överskrida och implementera dessa metoder i vår klass.

Nu visas alla metoder som behöver överskridas i vår klass. Låt oss gå vidare och göra det!

TaskQueueServiceImpl.java

TaskQueueServiceImpl.java

copy
1234567891011121314151617181920212223242526
package 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(); } }

I vårt fall har inget särskilt komplicerat gjorts. Vi använde helt enkelt metoderna från Queue-klassen för att implementera våra metoder korrekt. Därmed gör en datastruktur som kö det enklare för alla Java-programmerare.

Vi använder metoden offer() för att lägga till, metoden poll() för att ta bort och metoden isEmpty() för att kontrollera om kön är tom.

Nu är det din tur att bidra till att lösa detta problem. Du behöver implementera en tjänstklass, vars gränssnitt vi kommer att skapa tillsammans:

Main.java

Main.java

copy
12345
package codefinity.taskManager; public interface TaskProcessorService { void processTasks(); }

Vi har skapat ett servicegränssnitt med en metod: processTasks(), som, när den anropas, ska påbörja exekvering av alla uppgifter tills uppgiftslistan är tom. Denna metod representerar en användare som börjar utföra uppgifter.

Uppgift

Din uppgift är att skriva en klass TaskProcessorServiceImpl som ska implementera gränssnittet TaskProcessorService. Denna klass ska ha en metod för att bearbeta alla uppgifter, vilket innebär att den ska använda metoder från tjänsten TaskQueueService. Du kan använda komposition genom att skapa en instans av denna klass inom den klass du behöver implementera, till exempel:

Main.java

Main.java

copy
1234567
package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.TaskQueueService; public class TaskProcessorServiceImpl { TaskQueueService taskQueueService = new TaskQueueServiceImpl(); }

Generellt finns det redan en förberedd komposition högst upp för din uppgift. Därefter behöver du bara implementera en metod med hjälp av en instans av denna klass.

Efter det behöver du skapa en konstruktor som initialiserar detta objekt av klassen taskQueueService.

På så sätt kan du använda metoderna för detta objekt. Det är också tydligt att du, för att bearbeta uppgifter, behöver skicka vidare kön som taskProcessor ska arbeta med.

Resten av uppgiften är upp till dig. Ledtrådar finns i README.md-filen. När din lösning är klar, klicka på "Run Tests"-knappen så kommer de enhetstester jag har skrivit att kontrollera din lösning.

  1. Börja med att använda komposition och skapa en instans av klassen TaskQueue. Lägg sedan även till dess initialisering i konstruktorn.
  2. Implementera sedan gränssnittet TaskProcessorImpl och överskugga dess metoder.
  3. I implementationen av gränssnittet, använd en while-loop med metoden isEmpty() som villkor.
  4. Inuti while-loopen, använd metoden taskQueueService.getNextTask() och ange att uppgiften är slutförd. Skriv ut information till skärmen med System.out.println() - "Processing Task: " + task.
  5. När loopen är klar, skriv ut "All tasks processed." till skärmen.
  6. Kör testerna och kontrollera att din lösning är korrekt.
package codefinity.taskManager.taskManagerImpl;

import codefinity.taskManager.Task;
import codefinity.taskManager.TaskProcessorService;
import codefinity.taskManager.TaskQueueService;

public class TaskProcessorServiceImpl implements TaskProcessorService {
    private final TaskQueueService taskQueueImpl;

    public TaskProcessorServiceImpl(TaskQueueService taskQueueImpl) {
        this.taskQueueImpl = taskQueueImpl;
    }

    @Override
    public void processTasks() {
        while (!taskQueueImpl.isEmpty()) {
            Task task = taskQueueImpl.getNextTask();
            System.out.println("Processing Task: " + task + ";");
        }
        System.out.println("All tasks processed successfully.");
    }
}
Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 2. Kapitel 3

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Suggested prompts:

Can you explain how the TaskQueueService works in this context?

What should the output look like when processing tasks?

Is there a specific format for the Task class's toString() method?

bookUtmaning: Implementering av en Taskmanager-tjänst

Svep för att visa menyn

Övning

Det är dags att öva. Du har som uppgift att skriva en TaskManager tjänst som håller reda på dina uppgifter.

Med denna tjänst kan användaren lägga till uppgifter, tilldela dem till sig själv och sedan slutföra dem i sekventiell ordning.

Låt oss påbörja detta arbete tillsammans, och sedan fortsätter du på egen hand.

Men först behöver du skapa själva uppgiftsmodellen. Skapa en Task-klass:

Main.java

Main.java

copy
12345
public class Task { private int id; private String name; private String description; }

Klassen Task innehåller tre attribut: id, name och description. Varje uppgift måste ha ett namn och en beskrivning, och id är ett nödvändigt attribut för varje datastruktur.

Hur skulle du annars komma åt elementen? Attributen är också skyddade av åtkomstmodifieraren private eftersom du inte vill att andra klasser ska ha direkt åtkomst till fälten i denna klass, förutom via konstruktorn eller getters.

Nu ska vi implementera dessa getters och konstruktorn. Detta kan enkelt göras med kombinationen Control + Return på en MacBook eller Alt + Ins på en Windows.

Efter de utförda operationerna har du följande Task-klass:

Task.java

Task.java

copy
12345678910111213141516171819202122232425262728293031323334
package 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 + '\'' + '}'; } }

Tjänster

Du kommer att ha en mycket förenklad task board-tjänst, så låt oss implementera en tjänst som kan lägga till uppgifter, markera dem som slutförda och kontrollera om det finns uppgifter i kön.

Vi kallar denna klass för TaskQueueService. Till att börja med behöver vi definiera ett interface med dessa uppgifter:

TaskQueueService.java

TaskQueueService.java

copy
123456789
package codefinity.taskManager; public interface TaskQueueService { void addTask(Task task); Task getNextTask(); boolean isEmpty(); }

Detta interface definierar 3 metoder som implementeringsklasser måste implementera. Dessa metoder inkluderar att lägga till en uppgift, gå vidare till nästa uppgift (vilket innebär att användaren redan har slutfört föregående uppgift), samt en metod för att kontrollera om det finns uppgifter i kön.

Utmärkt, låt oss nu skapa en implementeringsklass som kommer att åsidosätta och implementera alla dessa metoder:

TaskQueueServiceImpl.java

TaskQueueServiceImpl.java

copy
12345678910
package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.Task; import java.util.LinkedList; import java.util.Queue; public class TaskQueueServiceImpl { private Queue<Task> taskQueue = new LinkedList<>(); }

Vi skapar ett privat attribut som endast kommer att användas inom denna serviceklass.

Det är värt att göra en kort avstickare för att prata om serviceklasser, som spelar en nyckelroll inom OOP.

Vad är serviceklasser?

Serviceklasser är utformade för att utföra specifika operationer. De ärver från servicegränssnitt och implementerar deras metoder. Detta tillvägagångssätt förbättrar kodens underhållbarhet och skalbarhet samtidigt som det följer SOLID-principerna, vilka du kommer att utforska i en separat kurs.

För närvarande är det viktigt att förstå att serviceklasser enbart existerar för att utföra operationer på andra objekt.

Till exempel, Om du skriver en kalkylator kommer du att ha en separat klass som lagrar värdet av det tal du arbetar med. De faktiska operationerna utförs med hjälp av en serviceklass där addition, subtraktion och så vidare är definierade.

Jag hoppas detta klargör syftet med serviceklasser i lösningen av denna uppgift.

Implementering av service

Vårt nästa steg är att tydligt visa att denna klass implementerar gränssnittet TaskQueueService.

För att uppnå detta använder vi nyckelordet implements följt av gränssnittsnamnet. Detta säkerställer att vår klass ärver det beteende som definieras av gränssnittet.

Eftersom gränssnitt endast tillhandahåller metoddeklarationer måste du överskrida och implementera dessa metoder i vår klass.

Nu visas alla metoder som behöver överskridas i vår klass. Låt oss gå vidare och göra det!

TaskQueueServiceImpl.java

TaskQueueServiceImpl.java

copy
1234567891011121314151617181920212223242526
package 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(); } }

I vårt fall har inget särskilt komplicerat gjorts. Vi använde helt enkelt metoderna från Queue-klassen för att implementera våra metoder korrekt. Därmed gör en datastruktur som kö det enklare för alla Java-programmerare.

Vi använder metoden offer() för att lägga till, metoden poll() för att ta bort och metoden isEmpty() för att kontrollera om kön är tom.

Nu är det din tur att bidra till att lösa detta problem. Du behöver implementera en tjänstklass, vars gränssnitt vi kommer att skapa tillsammans:

Main.java

Main.java

copy
12345
package codefinity.taskManager; public interface TaskProcessorService { void processTasks(); }

Vi har skapat ett servicegränssnitt med en metod: processTasks(), som, när den anropas, ska påbörja exekvering av alla uppgifter tills uppgiftslistan är tom. Denna metod representerar en användare som börjar utföra uppgifter.

Uppgift

Din uppgift är att skriva en klass TaskProcessorServiceImpl som ska implementera gränssnittet TaskProcessorService. Denna klass ska ha en metod för att bearbeta alla uppgifter, vilket innebär att den ska använda metoder från tjänsten TaskQueueService. Du kan använda komposition genom att skapa en instans av denna klass inom den klass du behöver implementera, till exempel:

Main.java

Main.java

copy
1234567
package codefinity.taskManager.taskManagerImpl; import codefinity.taskManager.TaskQueueService; public class TaskProcessorServiceImpl { TaskQueueService taskQueueService = new TaskQueueServiceImpl(); }

Generellt finns det redan en förberedd komposition högst upp för din uppgift. Därefter behöver du bara implementera en metod med hjälp av en instans av denna klass.

Efter det behöver du skapa en konstruktor som initialiserar detta objekt av klassen taskQueueService.

På så sätt kan du använda metoderna för detta objekt. Det är också tydligt att du, för att bearbeta uppgifter, behöver skicka vidare kön som taskProcessor ska arbeta med.

Resten av uppgiften är upp till dig. Ledtrådar finns i README.md-filen. När din lösning är klar, klicka på "Run Tests"-knappen så kommer de enhetstester jag har skrivit att kontrollera din lösning.

  1. Börja med att använda komposition och skapa en instans av klassen TaskQueue. Lägg sedan även till dess initialisering i konstruktorn.
  2. Implementera sedan gränssnittet TaskProcessorImpl och överskugga dess metoder.
  3. I implementationen av gränssnittet, använd en while-loop med metoden isEmpty() som villkor.
  4. Inuti while-loopen, använd metoden taskQueueService.getNextTask() och ange att uppgiften är slutförd. Skriv ut information till skärmen med System.out.println() - "Processing Task: " + task.
  5. När loopen är klar, skriv ut "All tasks processed." till skärmen.
  6. Kör testerna och kontrollera att din lösning är korrekt.
package codefinity.taskManager.taskManagerImpl;

import codefinity.taskManager.Task;
import codefinity.taskManager.TaskProcessorService;
import codefinity.taskManager.TaskQueueService;

public class TaskProcessorServiceImpl implements TaskProcessorService {
    private final TaskQueueService taskQueueImpl;

    public TaskProcessorServiceImpl(TaskQueueService taskQueueImpl) {
        this.taskQueueImpl = taskQueueImpl;
    }

    @Override
    public void processTasks() {
        while (!taskQueueImpl.isEmpty()) {
            Task task = taskQueueImpl.getNextTask();
            System.out.println("Processing Task: " + task + ";");
        }
        System.out.println("All tasks processed successfully.");
    }
}
Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 2. Kapitel 3
some-alt