Composite (kompozit) tasarım şablonu yapısal (Structural Patterns) tasarım şablonları grubunda yer alır. Composite bir sistemin bütünü ile parçalarının birbiriyle ilişkileri sadeleştirmek için kullanılır.
Anlatımımız biraz garip oldu bir örnek vererek açıklayalım. Grafik çizen bir uygulama yaptığımızı düşünelim her şekil için ayrı sınıf kullanıyoruz. Kare, Diktörtgen, Üçgen, Çember vs vs. Resimi çizmek için aşağıdaki gibi bir kod kullanırız.
1 2 3 4 | $kare->draw(); $ucgen->draw(); $diktorgen->draw(); $cember->draw(); |
Composite kullanırsak :
$composite->draw();
yaptığımızda butun nesnelerin draw yapmasını soyluyor ve olay çözülüyor.
Konuyu daha iyi anlayabilmek için bir örnek yapalım.
Composite sistemler 3 yapıdan oluşur. Companent, Composite ve Leaf.

Companent sınıf ana sınıftır ve Composite ve Leaf için arayüz oluşturur.
abstract class Component {
abstract function add(Component $companent);
abstract function remove(Component $companent);
abstract function display($level = 0);
abstract function count();
}Leaf herhangi bir child (alt) kontrol içermez. Dolayısıyla add ve remove gibi metodları çalıştıramaz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | class Leaf extends Component { private $title; function __construct($title) { $this->title = $title; } function add(Component $companent) { throw new Exception(__CLASS__." is not a composite"); } function remove(Component $companent) { throw new Exception(__CLASS__." is not a composite"); } function count() { return 1; } function line($level) { $yap = ""; for($i = 0; $i <= $level; $i++) { $yap .= '- '; } return $yap; } function display($level = 0) { print "{$this->line($level)} << Leaf: ".htmlspecialchars($this->title)." >>\n"; } } |
Composite databank gidir. Bünyesinde composite ve leaf nesneleri tutabilir. add ve remove methodları ise child eklemeye ve silmeye yarar. Yani ilk verdiğimiz örnekte Kare,çember,üçgen leaf resim ise compositedir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | abstract class Composite extends Component { protected $children = array(); function add(Component $companent) { $this->children[] = $companent; return $companent; } function remove(Component $companent) { $index = array_search($companent, $this->children, true); if ($index === false) { return false; } array_splice($this->children, $index, 1); return true; } function __clone() { $kids = array(); foreach ($this->children as $child) { $kids[] = clone($child); } $this->children = $kids; } function count() { $total = 1; foreach ($this->children as $child) { $total += $child->count(); } return $total; } } class Category extends Composite { protected $title; function __construct($title) { $this->title = $title; } function line($level) { $yap = ""; for($i = 0; $i <= $level; $i++) { $yap .= '- '; } return $yap; } function display($level = 0) { print "{$this->line($level)} ".htmlspecialchars($this->title)."\n"; foreach ($this->children as $child) { $child->display($level + 1); } } } |
evet şimdi bu kodları nasıl uygulayacağımıza bakalım
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $araba = new Category("Araba"); $honda = $araba->add(new Category("Honda")); $honda->add(new Category("Civic")); $honda->add(new Category("Accord")); $araba->add(new Category("Mercedes")); $bmw = $araba->add(new Category("Bmw")); $bmw_model = $bmw->add(new Category("3.20")); $bmw->add(new Category("5.20")); $bmw_model->add(new Leaf('sport')); $bmw_model->add(new Leaf('full')); $bmw->add(new Category("7.50")); $araba->display(); |
kodumuzun ekran çıktısı
- Araba
- – Honda
- – - Civic
- – - Accord
- – Mercedes
- – Bmw
- – - 3.20
- – - – << Leaf: sport >>
- – - – << Leaf: full >>
- – - 5.20
- – - 7.50
Bu sınıf için verebileceğimiz en iyi örneklerden biriside XML Parserdir. XML yapılar childlardan oluşur ve Composite sayesinde çok kolay parse edebiliriz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | <?php abstract class Component { abstract function add(Component $companent); abstract function remove(Component $companent); abstract function display($level = 0); abstract function count(); } class Leaf extends Component { private $title; function __construct($title) { $this->title = $title; } function add(Component $companent) { throw new Exception(__CLASS__." is not a composite"); } function remove(Component $companent) { throw new Exception(__CLASS__." is not a composite"); } function count() { return 1; } function line($level) { $yap = ""; for($i = 0; $i <= $level; $i++) { $yap .= '- '; } return $yap; } function display($level = 0) { print "{$this->line($level)} << Leaf: ".htmlspecialchars($this->title)." >>\n"; } } abstract class Composite extends Component { protected $children = array(); function add(Component $companent) { $this->children[] = $companent; return $companent; } function remove(Component $companent) { $index = array_search($companent, $this->children, true); if ($index === false) { return false; } array_splice($this->children, $index, 1); return true; } function __clone() { $kids = array(); foreach ($this->children as $child) { $kids[] = clone($child); } $this->children = $kids; } function count() { $total = 1; foreach ($this->children as $child) { $total += $child->count(); } return $total; } } class Category extends Composite { protected $title; function __construct($title) { $this->title = $title; } function line($level) { $yap = ""; for($i = 0; $i <= $level; $i++) { $yap .= '- '; } return $yap; } function display($level = 0) { print "{$this->line($level)} ".htmlspecialchars($this->title)."\n"; foreach ($this->children as $child) { $child->display($level + 1); } } } $araba = new Category("Araba"); $honda = $araba->add(new Category("Honda")); $honda->add(new Category("Civic")); $honda->add(new Category("Accord")); $araba->add(new Category("Mercedes")); $bmw = $araba->add(new Category("Bmw")); $bmw_model = $bmw->add(new Category("3.20")); $bmw->add(new Category("5.20")); $bmw_model->add(new Leaf('sport')); $bmw_model->add(new Leaf('full')); $bmw->add(new Category("7.50")); $araba->display(); ?> |
dosya : composite design pattern
benzer konular:















design patterns