본문으로 바로가기


* FileNode.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package kr.sys4u.test;
 
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
 
public class FileNode {
    private final File file;
    private final List<FileNode> children;
 
    public FileNode(final File file) {
        if (file == null) {
            throw new IllegalArgumentException();
        }
        this.file = file;
        this.children = new ArrayList<>();
    }
 
    public File getFile() {
        return file;
    }
 
    public FileNode addChild(File child) {
        FileNode childNode = new FileNode(child);
        addChild(childNode);
        return childNode;
    }
    
    public boolean addChild(FileNode child) {
        if (child == null) {
            throw new IllegalArgumentException();
        }
        return this.children.add(child);
    }
 
    public boolean addChildren(Collection<FileNode> children) {
        if (children == null) {
            throw new IllegalArgumentException();
        }
        return this.children.addAll(children);
    }
 
    public List<FileNode> getChildren(){
        List<FileNode> cloned = new ArrayList<>();
        cloned.addAll(this.children);
        return cloned;
    }
    
    public void removeChilderen()
    {
        this.children.removeAll(this.children);
    }
}
cs


* FileTree.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package kr.sys4u.test;
 
import java.io.File;
 
public class FileTree {
 
    private final FileNode rootFileNode;
    private boolean initialized = false;
 
    public FileNode getRootFileNode() {
        if(!initialized)
        {
            initialize();
        }
        return rootFileNode;
    }
 
    public FileTree(final String rootDir) {
        if (rootDir == null) {
            throw new IllegalArgumentException();
        }
        this.rootFileNode = new FileNode(new File(rootDir));
    }
 
    public FileTree(final File rootDir) {
        if (rootDir == null) {
            throw new IllegalArgumentException();
        }
        this.rootFileNode = new FileNode(rootDir);
    }
 
    public FileTree(final FileNode rootFileNode) {
        if (rootFileNode == null) {
            throw new IllegalArgumentException();
        }
        this.rootFileNode = rootFileNode;
    }
 
    public synchronized void initialize() {
        if(initialized) {
            return ;
        }
        rootFileNode.removeChilderen();
        addChildrenRecursively(rootFileNode);
        initialized = true;
    }
 
    private void addChildrenRecursively(FileNode parentNode) {
 
        File[] childrenFile = parentNode.getFile().listFiles();
 
        for (File child : childrenFile) {
            if(child.isFile()) {
                continue;
            }
            addChildrenRecursively(parentNode.addChild(child));
        }
 
    }
 
}
 
cs


* FileTreeStringConverter.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package kr.sys4u.test;
 
import java.util.List;
 
public class FileTreeStringConverter {
    private static final String FILE_SPLIT = "└";    
    private final FileTree fileTree;
    private StringBuilder converted;
    
    public FileTreeStringConverter(FileTree fileTree) {
        if(fileTree==null) {
            throw new IllegalArgumentException();
        }        
        this.fileTree = fileTree;        
        this.converted = new StringBuilder("");
    }
    
    public String convertFileNode() {
        FileNode rootNode = fileTree.getRootFileNode();        
        converted.append(FILE_SPLIT)
                 .append(rootNode.getFile() .getAbsolutePath())
                 .append("\n");        
        List<FileNode> childNode = rootNode.getChildren();
        getChildrenRecusively(childNode,1);
        return converted.toString();
    }
    
    public void getChildrenRecusively(List<FileNode> childNode,int depth) {    
        
        for(FileNode child: childNode){
            for(int i=0;i<depth;i++){
                converted.append("\t");
            }            
            converted.append(FILE_SPLIT)
                          .append(child.getFile().getName())
                          .append("\n");        
            getChildrenRecusively(child.getChildren(), depth+1);            
        }    
        
    }
}
 
cs


결과값)



===============================



< 클래스간 구조도 >





initialize() 는 왜하는것인가?

=> instance가 state가 필요할때 사용하는것이 initialize() 이다.

=> 여기서 예를들자면 FileNode의 Structure을 가지고 있어야 한다. 받은데이터만 가지고는 structure은 만들수 없다. 

=> 그래서 initialize()가 필요함


초기화 방법에는 eager-initialization 방식과 lazy-initialization 방식이 있다.

eager-initialization방식은 바로 초기화 하는 방식이고 lazy-initialization 방식은 나중에 초기화 하는 방식이다.

그럼 언제 두방식을 고려해서 초기화 해야할까?

그전에 먼저 lazy-initialization 방식이 왜 필요한가에 대해 말할 필요가있다.

결론부터 말하자면 비용이 들게 되는경우 lazy initialize를 하게 된다.

비용이 크다는 것은 자원(cpu,memory,disk,network,시간..)이 많이 든다는 것이다. 

그렇기 때문에 비용이 너무많이 들고 지금 당장 필요하지 않다면 초기화를 뒤로 미루는 것이다.


그럼 과연 eager 방식과 lazy 방식은 언제 적용시켜서 써야할까?

-> 실행이 되면 JVM이 실행되고 class가 올라오고 main이 실행되면서 많은 것들이 실행되기 때문에 인스턴스로 생성되면서 

    굳이 바로 초기화를 해야하는가에 중점을 두고 초기화 해야한다.

    그러나 왠만하면 lazy 방식을 쓰는것이 중요하다.

    초기화는 여러번 초기화 될수 있기 때문에 내부적으로 한번만 작업하는 로직이 필요하다.

    Recursion 초기화의 경우 initialize는 lazy initialize가 좋다.

 


보완할점

1.FileTreeConverter을 인터페이스로 만들고 FileTreeStringConverter, FileTreeFileConverter..등으로 분리시켜보자 

2.FileTree없이 FileNode와 FileTreeConverter 도 암묵적으로 1대1 관계가 유지되는데 왜 이렇게는 하면 안될까?