ゲームが作れるようになるまでがんばる日記

ゲーム制作のことを中心にゲームに関することを書いています

Composite

容器と中身を同一視することにより、再帰的に扱えるようにする。
一番分かりやすい例としてはファイルシステムだろう。ファイルとディレクトリを共通のインタフェースを持つ親クラスから派生するようにする。そうすればディレクトリの中にさらにディレクトリがあっても、ファイルがあっても同じように扱うことができるし、再帰的にディレクトリの中を検索していくことができる。
その他、ウィンドウシステムも同じように考えることができる。あるウィンドウの中に項目があり、その項目を選択するとさらに別のウィンドウが開くように。
Menu.java

public abstract class Menu {
    public abstract String getName();
    public Menu add(Menu menu) { return this; }
    public void disp() {
        disp("");
    }
    protected abstract void disp(String prefix);
}

Window.java

import java.util.Vector;
import java.util.Iterator;

public class Window extends Menu {
    private String name;
    private Vector menus = new Vector();
    public Window(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public Menu add(Menu menu) {
        menus.add(menu);
        return this;
    }
    public void disp(String prefix) {
        System.out.println( prefix + getName() );
        Iterator it = menus.iterator();
        while(it.hasNext()) {
            Menu menu = (Menu)it.next();
            menu.disp( prefix + " " );
        }
    }
}

Item.java

public class Item extends Menu {
    private String name;
    public Item(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void disp(String prefix ) {
        System.out.println( prefix + getName() );
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        Window topwindow = new Window("Top");
        Window usewindow = new Window("Use");
        Item status = new Item("Status");
        topwindow.add(usewindow);
        topwindow.add(status);
        Item money = new Item("Money");
        Item weapon = new Item("Weapon");
        usewindow.add(money);
        usewindow.add(weapon);
        
        topwindow.disp();
    }
}

実行結果

Top
 Use
  Money
  Weapon
 Status

このプログラム例は、トップメニューのウィンドウがあり、その中にはUseコマンドとStatusコマンドがある。Useコマンドは子ウィンドウになっており、MoneyコマンドとWeaponコマンドがある。


注意しなければならないのは、ちゃんと木構造になるようにすること。もし、親子構造が循環してしまうと無限ループになってしまう。


参考文献:Java言語で学ぶデザインパターン入門
参考:
ギコ猫とCompositeパターン
Composite パターン - Wikipedia