Eugen Gîrlescu
Eugen Gîrlescu

Reputation: 107

Move objects between classes (Java)

I have a problem like this:

A task board illustrates the progress that an Agile team is making in achieving their sprint goals. A task boards usually has a few simple things:

5 basic columns (there can be more)

Stories

To Do (Planned)

In Progress (In process, WIP, etc.)

In Review

Complete (Completed, Done, etc.)

A Row for each story

The cards that are present on the taskboard can be either a story card or a task card.

A story card always has the ‘yellow’ color and has a title, short description of the story and estimation in story points. This card can be present only on the ‘Stories’ column.

The task card has a title, detailed description of the task (acceptance criteria), estimation, color (‘green’ - normal, ‘red’ - blocked) and multiple tags (name of the developer working on the task, name of the developer reviewing the task, reason of the blocking state, etc.). This type of card can be moved between columns (other than the ‘Stories’ column where it cannot be present).

1.Identify the objects from the text,the classes should have atributtes and methods that should be extracted from the text, and create a main class in which you instantiate all the defined classes..

I am a beginner. I think that the objects are: the story and task and I need to move tasks between classes ..I tried to solve the problem like this:

I made a UserStory class:

public class UserStory {
private String title;
private String description;
private int storyPoints;
public Task task;

public UserStory(){}

public void setTitle(String title) {
    this.title = title;
}

public void setDescription(String description) {
    this.description = description;
}

public void setStoryPoints(int storyPoints) {
    this.storyPoints = storyPoints;
}

public String getTitle() {
    return title;
}



  public String getDescription() {
        return description;
    }

    public int getStoryPoints() {
        return storyPoints;
    }
}

and another 5 classes:first class is Task and another 4 classes who inherit the Task class: Planned, InProgress, InReview and Done. And for example I want to move a task from Planned to InProgress..These 2 classes looks like this:

First I have the Task superclass

    public class Task {
    public String title;
    public String color;
    public String description;
    public String workingDev;
    public String revDev;

    public Task(String title, String color, String description, String workingDev, String revDev) {
        this.title = title;
        this.color = color;
        this.description = description;
        this.workingDev = workingDev;
        this.revDev = revDev;
    }
    public Task(){};
     //getters and setters

}

Planned class:

public class Planned extends Task {

public Planned(String title, String color, String description, String workingDev, String revDev) {
    super(title, color, description, workingDev, revDev);
}

public Planned() {
}

public void moveInProgress(InProgress inProgress) {
    inProgress.InProgress();
}

public void InPlanned() {
    System.out.println("Task moved in Planned");
}

}

InProgress class:

public class InProgress extends Task {

public InProgress(String title, String color, String description, String workingDev, String revDev) {
    super(title, color, description, workingDev, revDev);
}

public InProgress() {
}

public void InProgress() {
    System.out.println("Task moved InProgress");
}

public void moveInPlanned(Planned planned){
    planned.InPlanned();
}

}

And the main class:

public class Hello {
public static void main(String[] args) {
    Planned pln = new Planned();
    InProgress prog = new InProgress();

    pln.moveInProgress(prog);
}

}

In my opinion, that's how I understood the requirement,I'm right?.. and I don't know what is the bond between the UserStory class and the Task class. a story strcuture can be something like this: As a [type of user], I want to [perform some task] so that I can [achieve some goal]. Any advice or hints would be welcome. If I was not clear please tell me, thank you

Upvotes: 0

Views: 210

Answers (1)

Polygnome
Polygnome

Reputation: 7795

"and another 4 classes who inherit the Task class: Planned, InProgress, InReview and Done".

That is a classical mistake many beginners make. "With a hammer, everything looks like a nail." Your hammer is inheritance / polymorphism and you apply it generously to every new problem. Don't worry, we all have been there.

The better approach is to prefer composition over inheritance.

Cards don't really need to know if they are in progress, done or planned or else. You already see that because you are struggling to create meaningful methods on them. They inherit from Task, but then what?

Personally, I'd go with a Board class, which has Columns (as in, a member private List<Column> columns).

And I'd only use one Card class which can move between those columns. With the above setup, its trivial to write a method on Board in the form of public void Move (Card card, Column from, Column to). You can even skip the from and have the method only be public void move(Card card, Column to). In that case, you need to first find the column the card is in, which is straight-forward.

Now, you still need to restrict movement of the cards, so that user stories are somewhat special.

You can employ inheritance here. E.g. by having two classes Task extends Card and Story extends Card. You could then make the Column class generic: Column<C extends Card>.

With that, you can have a column either accept any card or any story.

If you really want to, you can also create an enum to track the progress of the cards, but that isn't good from an extensibility PoV. What if you want to add more status?

So, in summary:

class Board {
    // 5 basic columns (there can be more)
    List<Column<Task>> columns = new ArrayList<>(5);
    
    Column<Story> stories = new Column<>("Stories");
    

    public Board() {
        var planned = new Column<Task>("To Do (Planned)");
        columns.add(planned);
        // etc.
    }

    public void move(Task card, Column<Task> from, Column<Task> to) {
        from.remove(card);
        to.add(card);
        // if you want to track state in the card, set the new state here
    }

    public void addStory(Story story) {}

    public void removeStory(Story story) {}

    public List<Columns<Task>> getColumns() {}

    public void getColumnByName(String name) {
       // implement using stream/filter/collect/findFirst/findAny
    }

    public void addColumn(Column column) {}
}

public class Card {  
    // ... 
}

public class Task extends Card {
    //
}

public class Story extends Card {
    //
}

public class Column<T extends Card> {
    private List<T> cards = new ArrayList();

    // fields like name/title etc
    // methods add/remove etc.
}

With this setup, you get quite a nice Kanban-Board thingy going. I've omitted all method implementations, but they are stright-forward to do.

You can also opt to make columns accept both Columns with Task and Stories (private List<Column ? extends Card>>), but if you are not comfortable with using generics in this way, you do not need to.

Upvotes: 1

Related Questions