Compositeパターン

###Compositeパターンとは
容器と中身を同一視し、再帰的な構造を作る。

###Leaf(葉)の役
「中身」を表す役。
この役の中には他のものを入れることはできない。

````java
package composite;

public class File extends Entry{
	private String name;
	private int size;

	public File(String name, int size) {
		this.name = name;
		this.size = size;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public int getSize() {
		return size;
	}

	@Override
	protected void printList(String prefix) {
		System.out.println(prefix + "/" + this);
	}
}
````

###Composite(複合体)の役
「容器」を表す役。
Leaf役やComposite役を入れることができる。

````java
package composite;

import java.util.ArrayList;
import java.util.Iterator;

public class Directory extends Entry{
	private String name;
	private ArrayList<Entry> directory = new ArrayList<>();

	public Directory(String name) {
		this.name = name;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public int getSize() {
		int size = 0;
		Iterator<Entry> it = directory.iterator();
		while (it.hasNext()) {
			Entry entry = (Entry) it.next();
			size += entry.getSize();
		}
		return size;
	}

	public Entry add(Entry entry) {
		directory.add(entry);
		return this;
	}

	@Override
	protected void printList(String prefix) {
		System.out.println(prefix + "/" + this);
		Iterator<Entry> it = directory.iterator();
		while (it.hasNext()) {
			Entry entry = (Entry) it.next();
			entry.printList(prefix + "/" + name);
		}
	}
}
````

###Componentの役
Leaf役とComposite役を同一視するための役。
Component役はLeaf役とComposite役に共通のスーパークラスとして実現する。

````java
package composite;

public abstract class Entry {
	public abstract String getName();
	public abstract int getSize();
	protected abstract void printList(String prefix);

	public Entry add(Entry entry) throws FileTreatmentException {
		throw new FileTreatmentException();
	}

	public void printList() {
		printList("");
	}

	@Override
	public String toString() {
		return getName() + "(" + getSize() + ")";
	}
}
````

###Client(依頼者)の役
Compositeパターンの利用者。

````java
package composite;

public class Main {
	public static void main(String[] args) {
		try {
			System.out.println("Making root entryies...");
			Directory rootDir = new Directory("root");
			Directory binDir = new Directory("bin");
			Directory tmpDir = new Directory("tmp");
			Directory usrDir = new Directory("usr");
			rootDir.add(binDir);
			rootDir.add(tmpDir);
			rootDir.add(usrDir);
			binDir.add(new File("vi", 10000));
			binDir.add(new File("latex", 20000));
			rootDir.printList();
			
			System.out.println();
			
			System.out.println("Making user entryies...");
			Directory yuki = new Directory("yuki");
			Directory hanako = new Directory("hanako");
			Directory tomura = new Directory("tomura");
			usrDir.add(yuki);
			usrDir.add(hanako);
			usrDir.add(tomura);
			yuki.add(new File("diary.html", 100));
			yuki.add(new File("Composite.java", 200));
			hanako.add(new File("memo.tex", 300));
			tomura.add(new File("game.doc", 400));
			tomura.add(new File("junk.mail", 500));
			rootDir.printList();
		} catch (FileTreatmentException e) {
			e.printStackTrace();
		}
	}
}
````

###実行結果

![スクリーンショット 2020-09-09 11.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/55e32b72-6e82-49ab-6d21-0f7c5434a2ff.png)

https://github.com/aki0207/composite

こちらを参考にさせていただきました。
<a href="https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=sr_1_1?ie=UTF8&qid=1454743284&sr=8-1&keywords=java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80">増補改訂版Java言語で学ぶデザインパターン入門</a>