Bileşik (Composite) Tasarım Kalıbı

Share Button

Composite design pattern, belirli bir nesne grubuna, tek bir nesneyi kullanıyormuşcasına muamele etmek için kullanılan yapısal bir tasarım desenidir.

Gerçek Hayat Örneği:

Problem:
2300 TL değerindeki Nikon D90 fotograf makinesi, 150 TL değerindeki sparkfun tripod ve 110 TL değerindeki şarjlı pil+şarj aleti seti bundle ürün halinde satışa sunulmak isteniyor.

Uygulama:
Elektronik ticaret sitelerinde ürünler, teker teker satılabildiği gibi yukarıdaki problemde belirtildiği gibi zaman zaman kit şeklinde de satılabilirler. Ancak sistemin her durumda tek ürüne de çoklu ürüne de benzer muamele uygulayarak indirim, kupon kodu kullanımı gibi diğer mevcut işlevlerini yerine getirebilmeye devam etmesi gerekmektedir. Composite tasarım deseni bu gibi durumlar için elverişli bir tasarım kalıbıdır.

Uygulamaya ilk olarak ürünümüzün özelliklerini tanımlayacak arayüz sınıfını oluşturarak başlayalım.
ProductInterface.php:

<?php
interface ProductInterface
{
    /**
     * @return string
     */
    public function getName();

    /**
     * @return string
     */
    public function getPrice();
}

Basit ürün ve bundle ürün tarafından kullanılacak ortak metodları içeren soyut ürün sınıfını oluşturalım.

AbstractProduct.php:

<?php
abstract class AbstractProduct implements ProductInterface
{
    /**
     * @var string
     */
    protected $name;
    
    /**
     * @var double
     */
    protected $price;

    /**
     * constructor
     * @param string $name
     * @param double $price
     */
    public function __construct($name, $price=null)
    {
        $this->name = $name;
        $this->price = $price;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @return double
     */
    public function getPrice()
    {
        return $this->price;
    }
}

Fotograf makinesi ve tripod gibi tekil ürünleri temsil edecek basit ürün sınıfını tanımlayalım.

SimpleProduct.php:

<?php
class SimpleProduct extends AbstractProduct
{
    
}

Şarj aleti+pil seti ve diğer basit ürünleri kit haline getirmemizi sağlayacak bundle ürün sınıfını tanımlayalım.
BundleProduct.php:

<?php
class BundleProduct extends AbstractProduct
{
    /**
     * @var array
     */
    private $products;

    /**
     * constructor
     * @param string $name
     * @param array $products
     * @param double $price
     */
    public function __construct($name, array $products, $price=null)
    {
        $this->setProducts($products);
        parent::__construct($name, $price ? $price : $this->getTotalPrice());
    }

    /**
     * @param ProductInterface $product
     */
    private function addProduct(ProductInterface $product)
    {
        $this->products[] = $product;
    }   

    /**
     * @param array $products
     */
    private function setProducts(array $products)
    {
        if(count($products) <= 1) {
            throws new ValueErrorException('Bundle products must have more than one product!');
        }
        for($products as $product) {
            $this->addProduct($product);
        }
    }

    /**
     * @return duobule
     */
    public function getTotalPrice()
    {
        return array_sum(array_map(function($product) {
            return $product->getPrice();
        }, $this->products));
    }
}

Gerekli tüm sınıf tanımlamalarını tamamladığımıza göre artık örnek problemde tanımlanan senaryoyu oluşturabiliriz.

<?php
$photoMachine = new SimpleProduct('Nikon D90', 2300);
$tripod = new SimpleProduct('SparkFun Tripod', 150);

$chargerKit = new BundleProduct('Şarjlı Pil + Şarj aleti seti', array(
    new SimpleProduct('Şarj aleti', 80),
    new SimpleProduct('Pil', 30)
));

$bundleProduct = new BundleProduct('Amatör Fotoğraf Kiti', array(
    array($photoMachine, $tripod, $chargerKit)
));

echo $bundleProduct->getPrice(); // 2560

Share Button

About İbrahim Gündüz

1983 yılında İstanbul’da doğdu. İlkokul yıllarında cobol ve basic le olan tanışması, yazılıma olan ilgisini arttırdı 2005 yılında. Uludağ Üniversitesi Teknik Bilimler Meslek Yüksek Okulu Elektronik bölümünden mezun olan Gündüz, çeşitli alanlarda faaliyet gösteren kurumlarda yazılım geliştirici olarak görev almıştır. Mesleki ilgi alanları, ölçeklenebilir sistemler, uygulama entegrasyonları ve ödeme sistemleridir. Halen Markafoni back end geliştirici olarak çalışmaktadır.

One comment

  • Mart 7, 2016 - 8:58 pm | Permalink

    Hastasıyım

  • Bir Cevap Yazın

    E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir