JavaScript ツリー構造はCompositeパターン
ツリー構造といえばあれだ。
営業部
┗ 1課
┗ 山田
┗ 鈴木
┗ 2課
┗ 佐藤
みたいになってるやつ。
デザインパターンには、このツリー構造をうまく処理できる「Compositeパターン」というものがある。
だが、ツリー構造自体、扱う機会が特に無かったので、Compositeパターンの存在を忘れていた。
「営業部」のようなグループは、中にさらにグループ(1課とか)、あるいは個人(山田とか)を格納できる。
しかし、個人はそれ以上何も格納できない。
以下、グループ・個人共通のインターフェイス。
function Component(name) { this.children = [] this.name = name } Component.prototype.add = function (child) { this.children.push(child) return this // メソッドチェーン用 } Component.prototype.showName = function (indent) { var indent = indent || '' console.log(indent + this.name) indent = indent + ' ' // 子要素の表示はインデントを追加 for (var i = 0; i < this.children.length; i++) { this.children[i].showName(indent) } }
以下、グループを表すクラス。Componentを継承している。
function Composite(name) { Component.apply(this, arguments) } Composite.prototype = Object.create(Component.prototype) Composite.prototype.constructor = Composite
以下、個人を表すクラス。同じく、Componentを継承している。
addメソッドは、利用不可になるようオーバーライドしている。
function Leaf() { Component.apply(this, arguments) } Leaf.prototype = Object.create(Component.prototype) Leaf.prototype.constructor = Leaf Leaf.prototype.add = null
ツリー構造を作成して表示。
;(new Component('Sony Music')).add( (new Component('乃木坂46')).add( new Leaf('白石麻衣') ).add( new Leaf('西野七瀬') ) ).add( (new Component('欅坂46')).add( new Leaf('平手友梨奈') ).add( new Leaf('長濱ねる') ) ).showName()
うーん、ツリー構造自体、必要になる機会が無い。出番無いかも…。