Tasarım desenleri yazı dizisinin başlangıcında yer alan Factory Method ve Abstract Factory yazılarından sonra bu ikisi arasındaki farkı basit kodlarla biraz daha açmaya karar verdim. Kodu sadece PHP olarak paylaşacağım fakat PHP kullanmasanız bile bu kalıplar arasındaki ayrımı yapabilmek için yeterli olacaktır.

Factory

Factory’de yapılacak iş ve ihtiyaç bellidir. İstemci kodumuz içerisinde doğrudan makeAndroid() ya da makeIos() fonksiyonlarını çağırmamız gerekir.

<?php

class PhoneFactory {

  public function createAndroid()
  {
    return new AndroidPhone();
  }

  public function createIos()
  {
    return new IosPhone();
  }
}

Factory method

İstemci kodumuz aşağıdaki factory method yönetimi ile phonePicker türünde AndroidPicker veya IosPicker sınıflarının selectPhone metodunu kullanarak istediği telefon objesini kolayca alabilecek. Yarın bir başka telefon türü eklemek istersek kodumuzu genişletmek daha kolay olacaktır.

İstemci kod mantığı içinde Ios ya da Android

<?php

// Bir telefon seçip telefonun tipini ekrana yazarak telefon nesnesini geri döndüren bir sınıf yazalım.

class PhonePicker {

 abstract public function createPhone(): Phone;

 public function selectPhone()
 {
   $phone = $this->createPhone();
   print 'Your selected phone is an '.$phone->getType();
   /*... 
     Diğer işlemler için kodlarımız, örneğin telefonu bir kayıt defterine kaydetme vs. vs.
     ...
   */

   return $phone;
 }
}

// Telefon seçici sınıfımızı genişleten ve createPhone factory methodumuzun tanımlandığı aşağıdaki sınıfları oluşturalım.

class AndroidPicker extends PhonePicker
{
   public function createPhone() {
    return new AndroidPhone();
  }  
}

class IosPicker extends PhonePicker
{
   public function createPhone() {
    return new IosPhone();
  }  
}

/* Konuyla doğrudan ilişkili olmadığı için yazıyı uzatmamak adına IosPhone ve AndroidPhone nesne sınıflarının tanımını buraya koymuyorum

Abstract Factory

Programımızın sadece telefon değil tabletleri de desteklemesini istersek Abstract Factory bu iş için daha uygun olacaktır. Aşağıdaki örnekte Device Factory Abtract Factory’imiz var. DeviceFactory tipindeki bir factory class’ının createPhone ve createTablet metodları olması gerektiğini belirliyor. Daha sonra bundan türettiğimiz IosFactory ve AndroidFactory’lerde telefon ve tablet oluşturma metodlarını yazıyoruz.

Abstract Factory’de belirli ortak fonksiyonları olan (createIos, createandroid) benzer türdeki nesneleri (tablet ya da telefon) oluşturmak için kullanıyoruz.

<?php

interface DeviceFactory {
  public function createIos(): AbstractIos;
  public function createAndroid(): AbstractAndroid;
}

class PhoneFactory implements DeviceFactory
{
    public function createIos(): AbstractPhone
    {
        return new IosPhone();
    }

    public function createAndroid(): AbstractPhone
    {
        return new AndroidPhone();
    }
}

class TabletFactory implements DeviceFactory
{
    public function createAndroid(): AbstractTablet
    {
        return new AndroidTablet();
    }

    public function createIos(): AbstractTablet
    {
        return new IosTablet();
    }
}


interface AbstractPhone
{
    public function getType(): string;
}

interface AbstractTablet
{
    public function getType(): string;
}

class AndroidPhone() {
  public function getType(): string {
    return 'I am an android phone'    
  }
}

class IosPhone() {
  public function getType(): string {
    return 'I am an Ios phone'    
  }
}

class AndroidTablet() {
  public function getType(): string {
    return 'I am an android tablet'    
  }
}

class IosTablet() {
  public function getType(): string {
    return 'I am an Ios tablet'    
  }
}