forget for get

覚えるために忘れる

Compositeパターン

容器と中身の同一視。
ファイルシステムでは、ディレクトリとファイルが入れ子になっている。
ディレクトリとファイルは異なるものですが、「ディレクトリに入るもの」とみなしている。

Leaf(葉):MyFile
中身
Composite(複合体):MyDirectory
容器
Component:Entry
LeafとCompositeを同一視するためのスーパークラス
Client(依頼者):Main

他にも複数と単数の同一視など。

Entry.php

abstract class Entry {
  abstract function getName();
  abstract function getSize();
  function add(Entry $entry) {
    throw new Exception("FileTreatmentException");
  }
  abstract function printList($prefix=null);
  function toString() {
    return $this->getName() . "(" . $this->getSize() . ")";
  }
}

MyFile.php

class MyFile extends Entry {
    private $name;
    private $size;
    function __construct(String $name, int $size) {
        $this->name = $name;
        $this->size = $size;
    }
    function getName() {
        return $this->name;
    }
    function getSize() {
        return $this->size;
    }
    function printList($prefix=null) {
        echo $prefix . "/" . $this->toString() . "\n";
    }
}

MyDirectory.php

class MyDirectory extends Entry {
    private $name;
    private $directory = [];
    function __construct(String $name) {
        $this->name = $name;
    }
    function getName() {
        return $this->name;
    }
    function getSize() {
        $size = 0;
        foreach ($this->directory as $entry) {
            $size += $entry->getSize();
        }
        return $size;
    }
    function add(Entry $entry) {
        $this->directory[] = $entry;
        return $this;
    }
    function printList($prefix=null) {
        echo $prefix . "/" . $this->toString() . "\n";
        foreach ($this->directory as $entry) {
            $entry->printList($prefix . "/" . $this->name);
        }
    }
}

Main.php

require "../autoload.php";
echo "Making root entries...\n";
$rootdir = new MyDirectory("root");
$bindir = new MyDirectory("bin");
$tmpdir = new MyDirectory("tmp");
$usrdir = new MyDirectory("usr");
$rootdir->getName();
$rootdir->add($bindir);
$rootdir->add($tmpdir);
$rootdir->add($usrdir);
$bindir->add(new MyFile("vi", 10000));
$bindir->add(new MyFile("latex", 20000));
$rootdir->printList();