I just started learning coding (mainly Java) for about 6 months at a University and now we just covered section of Composite design pattern (with Component, Leaf and Composite classes).
My class problem requires I use the below Component Interface to make a simple director program that I can create/add/remove files/directory.
public interface Component {
public String getName();
public int getSize();
public int getCount();
public String display(String prefix);
public Component search(String name);
}
Below is the File class that I wrote to be used as Leaf
public class File implements Component {
private String name;
private int size;
public File(String name, int size){
this.name = name;
this.size = size;
}
@Override
public String getName() {
return this.name;
}
@Override
public int getSize() {
return this.size;
}
@Override
public int getCount() {
return 1;
}
@Override
public String display(String prefix) {
return this.name + " " + "(" + this.size + ")" + System.lineSeparator();
}
@Override
public Component search(String name) {
if(this.name.equals(name)){
return this;
}
else {
return null;
}
}
Below is the Component Class - Directory Class. I put line of * above the method display in question.
import java.util.ArrayList;
public class Directory implements Component {
static int count = 0;
private String name;
//Array List to store the leafs
public ArrayList<Component> children;
public Directory(String name){
this.name = name;
this.children = new ArrayList<>();
}
//Method to add leaf to Directory
public void add(Component component){
children.add(component);
}
//Method to remove leaf from Directory
public void remove(Component component){
children.remove(component);
}
@Override
public String getName() {
return this.name;
}
@Override
public int getSize() {
int size = 0;
for(Component component : children) {
size += component.getSize();
}
return size;
}
@Override
public int getCount() {
int count = 0;
for(Component component : children) {
count += component.getCount();
}
return count;
}
//***********************************
@Override
public String display(String prefix) {
String totalString = name + ": (count=" + getCount() + ", size=" + getSize() + ")" + System.lineSeparator();
for (Component component : children) {
totalString = totalString + prefix + component.display(prefix + prefix);
}
return totalString;
}
//*************************************
@Override
public Component search(String name) {
for(Component component: children) {
if (component.search(name) != null) {
return component;
}
}
return null;
}
}
My goal is, when I apply the display method, every-time the component has children, the prefix in display method should increase by 1. To clarify, below is my test method
public class Test3 {
public static void main(String[] args) {
File holiday = new File("family-holiday",201);
File wallpaper = new File("wallpaper", 421);
Directory pictures = new Directory("pictures");
Directory personal = new Directory("personal");
Directory misc = new Directory("misc");
Directory dog = new Directory("dog");
dog.add(wallpaper);
personal.add(holiday);
personal.add(misc);
pictures.add(personal);
misc.add(dog);
System.out.print(pictures.display("+"));
}
}
The result of this should be
pictures: (count=2, size=622)
\+personal: (count=2, size=622)
\++family-holiday (201)
\++misc: (count=1, size=421)
\+++dog: (count=1, size=421)
\++++wallpaper (421)
However, due to the display method when component has children, it calls (prefix + prefix) which works until the 3rd directory/files, the prefix gets doubled every time instead of an increment of one. Below is the result I got
pictures: (count=2, size=622)
\+personal: (count=2, size=622)
\++family-holiday (201)
\++misc: (count=1, size=421)
\++++dog: (count=1, size=421)
\++++++++wallpaper (421)
I have tried multiple ways that I can think of below
Add prefix at the File display : This obviously did not work if there is director inside directory
Use static parameter to count number of method getting called, since the number of times prefix should be used depends on how many level the file / director is in there, that doesn't work with full count of the number of times used by the method.
Adding prefix at MANY MANY different places .. :) Still did not work well. I can imagine it has to be the way I pass the prefix to when the loop is calling display again, but I can't figure out what it is ...
If you could please advise or guide on what I can do or what I should read on to help with this, that will be very helpful. I do apologise in advance if there is similar topics as I couldn't find them with my current knowledge of the keyword, if you could please guide me there then I'm very grateful
As I said, just pass the depth as an integer and construct the prefix within the display function.
@Override
public String display(int depth) {
String prefix = '+'.repeat(depth);
String totalString = name + ": (count=" + getCount() + ", size=" + getSize() + ")" + System.lineSeparator();
for (Component component : children) {
totalString = totalString + prefix + component.display(depth + 1);
}
return totalString;
}
...
System.out.print(pictures.display(1));