[Go言語]Compositeパターンを学ぼう!

こんにちは、KOUKIです。

この記事では、デザインパターンの一つであるCompositeパターンについて紹介します。

デザインパターンまとめ

シチュエーション

Compositeパターンは、構造体に関するパターンで、再帰処理を実装したい場合に有効です。

例えば、以下のディレクトリがあるとします。

このフォルダ配下に、サブフォルダやファイルを作成したいとします。

CompositeDirの配下にSample1、そして、その配下にSample2,3が続きます。また、各ディレクトリには、goファイルが格納される感じです。

これらは、ディレクトリ → ファイル、ディレクトリ → ファイル、ディレクトリ → ファイルと作成していきます。

この処理は、「自分自身を呼び出す処理が書かれている関数(再帰処理)」を呼び出すことで実現することができます。

Compositeパターン:Interface無し

Compositeパターンで、プログラミングしていきましょう。

Interface有り無しはぶっちゃけあまり関係なく、再帰処理の方に注目してください。

容器の用意

Composite は、複合物を意味します。今回は、フォルダとファイルの混合物を用意します。

FolderObjectには、自分自身とFileObjectのスライスを格納しています。これが、Compositeパターンのポイントです。

プロパティとして自分自身を含めると、再帰処理の呼び出しを容易にします。

コンストラクタの定義

次に、コンストラクタを定義しましょう。

FileObjectのメソッド

FileObjectのメソッドを実装しましょう。

FolderObjectのメソッド

FolderObjectのメソッドを実装しましょう。

createFolderが、再帰対象のメソッドです。

ここでは、FolderObjectのスライスであるFilesの中身をループで回し、処理を再帰的に呼び出しています

面白いですよね。

FolderObjectに自分自身を含めているから、こんなことができるんですよね。

使ってみよう

このプログラムは、次の様に呼び出します。

プログラムを実行してみましょう。

OKですね。ちゃんとディレクトリ → ファイルの順で、再帰的に処理を呼び出していることがわかります。

Compositeパターン:Interface有り

今度は、Interface有りバージョンで実装してみます。

Compositeインターフェース

名前はなんでも良いのですが、インターフェースを用意します。

ここに定義したcreateは、プログラム実行時に再帰的に呼び出されます。

容器の用意

容器を用意します。

コンストラクタの定義

コンストラクタを用意します。

FileObjectのメソッド

インターフェースの要件を満たすように、createメソッドを実装します。

FolderObjectのメソッド

インターフェースの要件を満たすように、createメソッドを実装します。

また、FolderObjectに、データ追加用のメソッドを実装します。

このメソッドの引数には、Componentインターフェースを指定しています。そのため、パラメータとして渡すインスタンスはcreteメソッドを持つことが保証されます。

使ってみよう

このプログラムは、以下のように利用します。

インターフェースを実装していないバージョンと比べると、結構いい感じになりましたね。プログラムを実行してみましょう。

OKですね。

まとめ

Go言語でCompositeパターンを紹介している記事があまりないので、この実装で合っているか、ぶっちゃけあまり自信ありませんw
しかし、きっと大丈夫でしょう!

Compositeパターンは、再帰処理を実装するときに活躍するので、今回紹介したプログラム以外にも、データサーチなんかにも応用ができそうです。

構造体の中に子要素があって、されにその子要素が…と続いていく処理を実装したい時、このパターンを思い出していただければと思います^^

それでは、また!

Go言語まとめ

ソースコード

Interface無し

Interface有り

コメントを残す