I was assigned to design a piece of software (in java) with projects and jobs where jobs each have a status. As we learned about the GoF-patterns, the State pattern seemed like an obvious choice to me, but now I'm having some troubles with the implementation.
In my current design I have a Job-class to represent the job with a certain state and a Project-class that has a list of jobs. To represent the four possible states (AVAILABLE - UNAVAILABLE - FINISHED - FAILED), I made an enum State with the state dependent methods of job implemented in the enum.
The issues with the state-pattern I'm having are the following:
- In
Project, I would like to have a method that returns allAVAILABLEjobs of the project (and maybe even one that returns all jobs that are eitherFINISHEDorFAILED), but the state pattern doesn't mention on how to do this. We also got to hear that having methods aspublic boolean isAvailable()inJoborStateshould not be used when using the state pattern (because this is exactly what one wants to avoid when using this pattern). - There is need for a method that changes the state from an
AVAILABLEtask to eitherFINISHEDorFAILED. The problem with this is that I'm not really sure on how to implement this when using the State pattern.
I have some solutions in mind, but I would like to know whether there are other/better solutions to implement the state pattern well.
- For the first problem, I would implement a
public Collection<Job> filter(Collection<Job>)method inStatethat would return the subset of the given set with only those jobs that are of the current state. ThegetAvailableJobs()method inProjectwould be like below. The disadvantage of this approach for me is that coupling grows whenProjectneeds to know aboutStateas well. - For the second problem I could either write a
update(State newState)method where I could check whethernewStateis either finished or failed or I could write a methodfail()and a methodfinish()(both inStateof course). The problem with the second seems to be the fact that some of the state logic gets back in theTask, but I'm not sure whether theupdatemethod is the best method either.
I hope I have been clear enough and that someone can help me understand why these solutions would be good enough or bad and what possible alternatives might be.
// in Project
public Collection<Job> getAvailableJobs() {
return Status.AVAILABLE.filter(getTasks());
}
// in State
public Collection<Job> filter(Collection<Job> jobs) {
Collection<Job> result = new HashSet<>();
for(Job j : jobs)
if(j.getStatus() == this)
result.add(j);
return result;
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire