Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Udfordring: Implementering af en Taskmanager-tjeneste | Avancerede Datastrukturer i Java
Practice
Projects
Quizzes & Challenges
Quizzes
Challenges
/
Java Datastrukturer

bookUdfordring: Implementering af en Taskmanager-tjeneste

Øvelse

Det er tid til at øve sig. Du har til opgave at skrive en TaskManager service, der holder styr på dine opgaver.

Med denne service kan brugeren tilføje opgaver, tildele dem til sig selv og derefter fuldføre dem i en sekventiel rækkefølge.

Lad os begynde at arbejde på denne opgave sammen, og derefter fortsætter du på egen hånd.

Men først skal du oprette selve opgave-modellen. Lad os oprette en Task-klasse:

Main.java

Main.java

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

Task-klassen indeholder tre attributter: id, name og description. Hver opgave skal have et navn og en beskrivelse, og id er en nødvendig attribut for enhver datastruktur.

Hvordan ville du ellers få adgang til elementerne? Attributterne er også beskyttet af adgangsmodifikatoren private, fordi du ikke ønsker, at andre klasser skal have direkte adgang til felterne i denne klasse, undtagen gennem konstruktøren eller getters.

Lad os nu implementere disse getters og konstruktøren. Dette kan nemt gøres ved at bruge kombinationen af Control + Return på en MacBook eller Alt + Ins på en Windows.

Efter de udførte operationer har du følgende Task-klasse:

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

Services

Du vil have en meget forenklet opgaveboard-tjeneste, så lad os implementere en tjeneste, der kan tilføje opgaver, markere dem som fuldførte og tjekke om der er opgaver i køen.

Lad os kalde denne klasse TaskQueueService. Til at begynde med skal vi definere et interface med disse opgaver:

TaskQueueService.java

TaskQueueService.java

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

Dette interface definerer 3 metoder, som implementeringsklasser skal implementere. Disse metoder omfatter tilføjelse af en opgave, videre til næste opgave (hvilket indebærer, at brugeren allerede har fuldført den forrige opgave), og en metode til at tjekke, om der er opgaver i køen.

Fint, lad os nu oprette en implementeringsklasse, der overskriver og implementerer alle disse 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 opretter et privat attribut, der kun vil blive brugt inden for denne serviceklasse.

Det er værd at lave en kort digression for at tale om serviceklasser, som spiller en central rolle i OOP.

Hvad er serviceklasser?

Serviceklasser er designet til at udføre specifikke operationer. De arver fra serviceinterfaces og implementerer deres metoder. Denne tilgang forbedrer vedligeholdelse og skalerbarhed af koden, samtidig med at den følger SOLID-principperne, som du vil udforske i et separat kursus.

For nu er det vigtigt at forstå, at serviceklasser udelukkende eksisterer for at udføre operationer på andre objekter.

For eksempel, Hvis du skriver en lommeregner, vil du have en separat klasse, der gemmer værdien af det tal, du arbejder med. De faktiske operationer udføres ved hjælp af en serviceklasse, hvor addition, subtraktion osv. er defineret.

Jeg håber, dette tydeliggør formålet med serviceklasser i løsningen af denne opgave.

Serviceimplementering

Vores næste skridt er eksplicit at vise, at denne klasse implementerer TaskQueueService-interfacet.

For at opnå dette bruger vi implements-nøgleordet efterfulgt af interfacets navn. Dette sikrer, at vores klasse arver den adfærd, der er defineret af interfacet.

Da interfaces kun giver metodeerklæringer, skal du overskrive og implementere disse metoder i vores klasse.

Nu vises alle metoderne, der skal overskrives, i vores klasse. Lad os fortsætte og gøre 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 vores tilfælde blev der ikke gjort noget særligt kompliceret. Vi brugte blot metoderne fra Queue-klassen til korrekt at implementere vores metoder. Dermed gør en datastruktur som en kø livet lettere for alle Java-programmører.

Vi bruger offer()-metoden til at tilføje, poll()-metoden til at fjerne, og isEmpty()-metoden til at kontrollere, om køen er tom.

Nu er det din tur til at bidrage til at løse dette problem. Du skal implementere en service-klasse, hvis interface vi vil oprette sammen:

Main.java

Main.java

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

Vi har oprettet et serviceinterface med én metode: processTasks(), som, når den kaldes, skal starte udførelsen af alle opgaver, indtil opgavelisten er tom. Denne metode repræsenterer en bruger, der begynder at udføre opgaver.

Opgave

Din opgave er at skrive en klasse TaskProcessorServiceImpl, der skal implementere TaskProcessorService-interfacet. Denne klasse skal have en metode til at behandle alle opgaver, hvilket betyder, at den skal bruge metoder fra TaskQueueService-servicen. Du kan anvende komposition ved at oprette en instans af denne klasse inden for den klasse, du skal implementere, for eksempel:

Main.java

Main.java

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

Generelt er der allerede forberedt en sammensætning øverst til din opgave. Dernæst skal du blot implementere én metode ved hjælp af en instans af denne klasse.

Herefter skal du oprette en konstruktør, der initialiserer dette objekt af klassen taskQueueService.

På denne måde kan du anvende metoderne for dette objekt. Det er også tydeligt, at du til opgavebehandling skal videregive køen, som taskProcessor skal arbejde med.

Resten af opgaven er op til dig. Tips vil blive givet i README.md-filen. Når din løsning er klar, skal du klikke på "Run Tests"-knappen, og de enhedstests, jeg har skrevet, vil kontrollere din løsning.

  1. Først skal du bruge sammensætning og oprette en instans af klassen TaskQueue. Tilføj derefter også dens initialisering i konstruktøren.
  2. Dernæst skal du implementere interfacet TaskProcessorImpl og overskrive dets metoder.
  3. I implementeringen af interfacet skal du bruge en isEmpty()-løkke med metoden while som betingelse.
  4. Inden i while-løkken skal du bruge metoden taskQueueService.getNextTask(), hvilket angiver, at opgaven er færdigbehandlet. Udskriv information til skærmen med System.out.println() - "Processing Task: " + task.
  5. Når løkken er færdig, udskriv "All tasks processed." til skærmen.
  6. Kør testene og kontroller korrektheden af din løsning.
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 alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 2. Kapitel 3

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

bookUdfordring: Implementering af en Taskmanager-tjeneste

Stryg for at vise menuen

Øvelse

Det er tid til at øve sig. Du har til opgave at skrive en TaskManager service, der holder styr på dine opgaver.

Med denne service kan brugeren tilføje opgaver, tildele dem til sig selv og derefter fuldføre dem i en sekventiel rækkefølge.

Lad os begynde at arbejde på denne opgave sammen, og derefter fortsætter du på egen hånd.

Men først skal du oprette selve opgave-modellen. Lad os oprette en Task-klasse:

Main.java

Main.java

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

Task-klassen indeholder tre attributter: id, name og description. Hver opgave skal have et navn og en beskrivelse, og id er en nødvendig attribut for enhver datastruktur.

Hvordan ville du ellers få adgang til elementerne? Attributterne er også beskyttet af adgangsmodifikatoren private, fordi du ikke ønsker, at andre klasser skal have direkte adgang til felterne i denne klasse, undtagen gennem konstruktøren eller getters.

Lad os nu implementere disse getters og konstruktøren. Dette kan nemt gøres ved at bruge kombinationen af Control + Return på en MacBook eller Alt + Ins på en Windows.

Efter de udførte operationer har du følgende Task-klasse:

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

Services

Du vil have en meget forenklet opgaveboard-tjeneste, så lad os implementere en tjeneste, der kan tilføje opgaver, markere dem som fuldførte og tjekke om der er opgaver i køen.

Lad os kalde denne klasse TaskQueueService. Til at begynde med skal vi definere et interface med disse opgaver:

TaskQueueService.java

TaskQueueService.java

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

Dette interface definerer 3 metoder, som implementeringsklasser skal implementere. Disse metoder omfatter tilføjelse af en opgave, videre til næste opgave (hvilket indebærer, at brugeren allerede har fuldført den forrige opgave), og en metode til at tjekke, om der er opgaver i køen.

Fint, lad os nu oprette en implementeringsklasse, der overskriver og implementerer alle disse 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 opretter et privat attribut, der kun vil blive brugt inden for denne serviceklasse.

Det er værd at lave en kort digression for at tale om serviceklasser, som spiller en central rolle i OOP.

Hvad er serviceklasser?

Serviceklasser er designet til at udføre specifikke operationer. De arver fra serviceinterfaces og implementerer deres metoder. Denne tilgang forbedrer vedligeholdelse og skalerbarhed af koden, samtidig med at den følger SOLID-principperne, som du vil udforske i et separat kursus.

For nu er det vigtigt at forstå, at serviceklasser udelukkende eksisterer for at udføre operationer på andre objekter.

For eksempel, Hvis du skriver en lommeregner, vil du have en separat klasse, der gemmer værdien af det tal, du arbejder med. De faktiske operationer udføres ved hjælp af en serviceklasse, hvor addition, subtraktion osv. er defineret.

Jeg håber, dette tydeliggør formålet med serviceklasser i løsningen af denne opgave.

Serviceimplementering

Vores næste skridt er eksplicit at vise, at denne klasse implementerer TaskQueueService-interfacet.

For at opnå dette bruger vi implements-nøgleordet efterfulgt af interfacets navn. Dette sikrer, at vores klasse arver den adfærd, der er defineret af interfacet.

Da interfaces kun giver metodeerklæringer, skal du overskrive og implementere disse metoder i vores klasse.

Nu vises alle metoderne, der skal overskrives, i vores klasse. Lad os fortsætte og gøre 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 vores tilfælde blev der ikke gjort noget særligt kompliceret. Vi brugte blot metoderne fra Queue-klassen til korrekt at implementere vores metoder. Dermed gør en datastruktur som en kø livet lettere for alle Java-programmører.

Vi bruger offer()-metoden til at tilføje, poll()-metoden til at fjerne, og isEmpty()-metoden til at kontrollere, om køen er tom.

Nu er det din tur til at bidrage til at løse dette problem. Du skal implementere en service-klasse, hvis interface vi vil oprette sammen:

Main.java

Main.java

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

Vi har oprettet et serviceinterface med én metode: processTasks(), som, når den kaldes, skal starte udførelsen af alle opgaver, indtil opgavelisten er tom. Denne metode repræsenterer en bruger, der begynder at udføre opgaver.

Opgave

Din opgave er at skrive en klasse TaskProcessorServiceImpl, der skal implementere TaskProcessorService-interfacet. Denne klasse skal have en metode til at behandle alle opgaver, hvilket betyder, at den skal bruge metoder fra TaskQueueService-servicen. Du kan anvende komposition ved at oprette en instans af denne klasse inden for den klasse, du skal implementere, for eksempel:

Main.java

Main.java

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

Generelt er der allerede forberedt en sammensætning øverst til din opgave. Dernæst skal du blot implementere én metode ved hjælp af en instans af denne klasse.

Herefter skal du oprette en konstruktør, der initialiserer dette objekt af klassen taskQueueService.

På denne måde kan du anvende metoderne for dette objekt. Det er også tydeligt, at du til opgavebehandling skal videregive køen, som taskProcessor skal arbejde med.

Resten af opgaven er op til dig. Tips vil blive givet i README.md-filen. Når din løsning er klar, skal du klikke på "Run Tests"-knappen, og de enhedstests, jeg har skrevet, vil kontrollere din løsning.

  1. Først skal du bruge sammensætning og oprette en instans af klassen TaskQueue. Tilføj derefter også dens initialisering i konstruktøren.
  2. Dernæst skal du implementere interfacet TaskProcessorImpl og overskrive dets metoder.
  3. I implementeringen af interfacet skal du bruge en isEmpty()-løkke med metoden while som betingelse.
  4. Inden i while-løkken skal du bruge metoden taskQueueService.getNextTask(), hvilket angiver, at opgaven er færdigbehandlet. Udskriv information til skærmen med System.out.println() - "Processing Task: " + task.
  5. Når løkken er færdig, udskriv "All tasks processed." til skærmen.
  6. Kør testene og kontroller korrektheden af din løsning.
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 alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 2. Kapitel 3
some-alt