Compositeパターン
容器と中身を同一視し、再帰的な構造を作りますよパターン。再帰キターーー。リカーシブなモノはもうそれだけでカッコイイ。大抵の場合カッコイイ。帰納、再帰カッコヨス。しかし、再帰的という言葉から自分のインスタンスを自ら生成して、それから…と、意味不明な思考の迷路に迷い込んでしまいギブアップ、んー。わざわざファイルとディレクトリの話を振ってくれているんだから落ち着いて考えなさいよ、という話。このパターンでは抽象クラスComponentに対して、そのインスタンスを持ち(集約)、抽象メソッドも全て実装したサブクラスCompositeとそうでない(一部のメソッドのみ実装するなどした)サブクラスLeafを用意し、それらのインスタンスを同一視することで再帰構造を表現する。
ポイントはComponentとCompositeとの間で集約によって親子関係を表現していること。(最悪Leafの部分は思い切って忘れて)この格好を覚えておくだけでも十分価値があると思った。いや、Leafの存在が許されることももちろん大事だけれども。
メモとしては、メソッドの定義の仕方についての話が面白かったので残しておく。
//抽象クラス
public abstract class Component {
public Component hoge(Component) {
/* hogehoge */
…(略)…
public class Composite extends Component {
//抽象クラスのメソッドをオーバーライド
public Component hoge(Component) {
/* overridehogehoge */
…(略)…
public class Leaf extends Component {
//メソッドhogeをオーバーライドしないので
//Componentクラスの/* hogehoge */が実行される
…(略)…こう書くか、あるいは
//抽象クラス
public abstract class Component {
public abstract Component hoge(Component);
…(略)…
public class Composite extends Component {
//抽象クラスのメソッドを実装
public Component hoge(Component) {
/* hogehoge */
…(略)…
public class Leaf extends Component {
//(結果的に)クラス毎に個別に実装
public Component hoge(Component) {
/* hogegege */
…(略)…こう書くか、みたいな。前者の方がスマートな印象でつい選びたくなるけど、後者の方が統一感という意味では良いのかも。まあどちらも常套手段なんだろうな。