LoginSignup
6
2

More than 5 years have passed since last update.

デザインパターン勉強会 第11回:Compositeパターン

Last updated at Posted at 2017-10-24

はじめに

これは某社内で実施するデザインパターン勉強会で使用する資料です。
書籍「Java言語で学ぶデザインパターン」をベースに学習を進めますが、サンプルプログラムはC#に置き換えて解説します。

第1回:Iteratorパターン
第2回:Adapterパターン
第3回:Template Methodパターン
第4回:Factory Methodパターン
第5回:Singletonパターン
第6回:Prototypeパターン
第7回:Builderパターン
第8回:Abstract Factoryパターン
第9回:Bridgeパターン
第10回:Strategyパターン


Compositeパターンとは

Compositeパターンは、容器と中身を同一視して、再帰的な構造を作るパターンです。
木構造をイメージするとわかりやすいかと思います。

サンプルプログラムでは、PC上でファイル管理するためにフォルダの階層を作成するのをイメージしてください。


サンプルプログラム

クラス図

image.png


クラスの役割

クラス名 役割
IEntry FolderとFileを同一視するインターフェース
Folder フォルダを表すクラス
File ファイルを表すクラス
Program 動作確認用のクラス

IEntry

IEntryは、FolderクラスとFileクラスの構成を指定するためのインターフェースです。
・出力の処理を指定するOutput
で構成されています

    interface IEntry
    {
        void Output(int depth);
    }

Folder

Folderクラスはフォルダを表現しているクラスです
インターフェースの実装の他に、
フォルダ名を格納するnameフィールド
自身より下層のフォルダやファイルを持つentriesフィールドを持っています。

Outputメソッドでは、自身のNameを出力した後に自身より下層の要素のOutputメソッドを実行しています

    class Folder : IEntry
    {
        private string name;
        private List<IEntry> entries = new List<IEntry>();

        public Folder(string name)
        {
            this.name = name;
        }

        public void Output(int depth)
        {
            for(int i=0; i < depth; i++)
            {
                Console.Write("  ");
            }
            Console.WriteLine("Folder:"+name);
            foreach(IEntry entry in entries){
                entry.Output(depth+1);
            }

        }

        public void AddEntry(IEntry entry)
        {
            entries.Add(entry);
        }
    }

File

Fileクラスはファイルを表現しているクラスです
インターフェースで指定されたメソッドの他に
自身のファイル名を格納するNameフィールドを持っています。

    class File : IEntry
    {
        private string name;

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

        public void Output(int depth)
        {
            for (int i = 0; i < depth; i++)
            {
                Console.Write("  ");
            }
            Console.WriteLine("File:" + name);
        }

    }

Program

ファイルとフォルダのインスタンスを作成し、フォルダに追加します
追加する要素がファイルかフォルダかを意識せずに追加できます

    class Program
    {
        static void Main(string[] args)
        {
            var root = new Folder("root");
            var user = new Folder("user");
            var temp = new Folder("temp");
            var documents = new Folder("document");
            var game = new Folder("げぇむ");

            var gomi = new File("ごみ");
            var ika = new File("ika");
            var tako = new File("tako");
            var salmon = new File("salmon");

            //フォルダを追加
            root.AddEntry(user);
            root.AddEntry(temp);
            user.AddEntry(documents);
            user.AddEntry(game);

            //ファイルを追加
            temp.AddEntry(gomi);
            game.AddEntry(ika);
            game.AddEntry(tako);
            game.AddEntry(salmon);

            root.Output(0);

        }
    }

Program実行結果

Folder:root
  Folder:user
    Folder:document
    Folder:げぇむ
      File:ika
      File:tako
      File:salmon
  Folder:temp
    File:ごみ

まとめ

  • Compositeパターンは、容器と中身を同一視して、再帰的な構造を作るパターンです
  • 利用者は容器と中身を意識せずに使用することができます
  • ただし、利用できないメソッドがある場合は気をつける必要があります

サンプルコード

サンプルコードは以下で公開しています
https://github.com/Nanakusajp/CompositePattern

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2