Help us understand the problem. What is going on with this article?

デザインパターン ~Composite~

1. はじめに

GoFのデザインパターンにおける、Compositeパターンについてまとめます。

2. Compositeパターンとは

  • Compositeという英単語は、混合物複合物という意味になります。
  • Compositeパターンは、容器と中身を同一化し、再帰的な構造を作る方式です。
  • ディレクトリとファイルをまとめてディレクトリエントリとして扱うように、容器と中身を同じ種類のものとして扱うと便利な場合があります。例えば、容器の中には中身を入れてもいいですし、さらに容器を入れることもいいです。このようにして、再帰的な構造を作ることができます。
  • GoFのデザインパターンでは、構造に関するデザインパターンに分類されます。

3. サンプルクラス図

Composite.PNG

4. サンプルプログラム

ディレクトリ、ファイルの一覧を表示するプログラムです。

4-1. Entryクラス

FileとDirectoryの基底となるクラスです。

Entry.java
public abstract class Entry {

    public abstract String getName();
    protected abstract void printList(String prefix);

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

4-2. Fileクラス

ファイルを表すクラスです。

File.java
public class File extends Entry {

    private String name;

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

    public String getName() {
        return name;
    }

    protected void printList(String prefix) {
        System.out.println(prefix + "/" + name);
    }
}

4-3. Directoryクラス

ディレクトリを表すクラスです。

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

public class Directory extends Entry {

    private String name;
    private ArrayList<Entry> directory = new ArrayList<Entry>();

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

    public String getName() {
        return name;
    }

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

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

4-4. Mainクラス

メイン処理を行うクラスです。

Main.java
public class Main {
    public static void main(String[] args) {

        Directory workspaceDir = new Directory("workspace");
        Directory compositeDir = new Directory("composite");
        Directory testDir1 = new Directory("test1");
        Directory testDir2 = new Directory("test2");
        workspaceDir.add(compositeDir);
        workspaceDir.add(testDir1);
        workspaceDir.add(testDir2);

        File directory = new File("Directory.java");
        File entity = new File("Entity.java");
        File file = new File("file.java");
        File main = new File("main.java");
        compositeDir.add(directory);
        compositeDir.add(entity);
        compositeDir.add(file);
        compositeDir.add(main);
        workspaceDir.printList();
    }
}

4-5. 実行結果

/workspace
/workspace/composite
/workspace/composite/Directory.java
/workspace/composite/Entity.java
/workspace/composite/file.java
/workspace/composite/main.java
/workspace/test1
/workspace/test2

5. メリット

全てのオブジェクト(File、Directory)は、共通の抽象クラスを持っているので、クライアントから見て、どれがFileなのかDirectoryなのか、中身を意識する必要がなく、一様に扱うことができます。
また、新たなクラス(例:SymbolicLink)を追加した場合でも、基底クラス(Entry)のインターフェースが変わらなければ、クライアントの処理には影響しません。

6. GitHub

7. デザインパターン一覧

8. 参考

今回の記事、及びサンプルプログラムは、以下の書籍を元に作成させて頂きました。

大変分かりやすく、勉強になりました。感謝申し上げます。
デザインパターンやサンプルプログラムについての説明が詳細に書かれていますので、是非書籍の方もご覧ください。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away