Php Adapter Design Pattern

On Haziran 16, 2011, in Php, by Ysfkc

Merhaba arkadaşlar çok uzun bir aradan (3 ay) sonra ancak fırsat bulabildim. Bloğa yazamamamın sebeplerinden bazıları işi bıraktım ve yeni firmam da işe başladım bu zaman zarfı sürecinde yeni işime alıştım üç ay kadar ceviz.net yöneticilerinden Sercan Virlan ile beraber çalışma imkanı buldum ve şuan da yeni iş yerimde mutlu ve huzurluyum.

Konuya gelecek olursak bu yazıda daha önceki bahsettiğim singleton pattern ile paralel olan bir başka pattern, adapter pattern hakkında bilgi vermeye çalışacağım. Adapter pattern nerelerde kullanılır gerekli midir değil midir buna karar verecek olanlar sizlersiniz ama gerçek anlamda bir MVC yapısı kullancaksak artık bu oop mimarisi ve design patternlere önem vermeliyiz.

Adapter patterni şöyle izah edebiliriz bir düşüneyim ımmm bir firmada çalışan bir a elemanı var bu a elemanı bir proje geliştirmiş ve işten bir süre sonra ayrılmış daha sonra ise işe siz başlamışsınız ve o projeye ek bişeyler yapmanız isteniyor ancak a elemanı kendine göre yazdığı için ufak bir kod değişikliği demek tüm projeyi baştan sona kontrol etmek anlamına geldiği için iş biraz sıkıcı ve yorucu olacaktır. Adapter pattern ile mevcut koda ( interface, abstract class ) extends ederek türetilen yeni bir interface veya abstract class yaparak mevcut projeyi bozmadan işimizi kolay halletme yoludur diyebiliriz. Örnek vermek istedim çünkü böyle daha kolay anlaşılır diye düşündüm.

Şimdi bizim a elemanı ne yapmış olsun bir tane interface tanımlasın ve bu interface sadece girilen ismi ekrana yazdırmak için kullanılan bir arayüz olsun aşağıdaki gibi

< ?php
interface isim
{
	public function getName($name);
}
?>

Bu arayüze (interface) uygun sınıfınıda yazmış olsun.

< ?php
class name implements isim
{
	public function getName($name)
	{
		echo $name;
	}
}
?>

Evet a elemanı tasarladığı arayüz üzerine sınıfınıda yazmış oldu. Ama hiç bir zaman kendisinin işi bırakacağını ve kendisinden sonra gelen birisinin buna ekleme yapması ihtimalini düşünmeyerek kodunu tamamladı. Derken işi bıraktı biz başladık işe ve bizim bu arayüze eklemeler yapmamız gerekti. Ancak arayüzü değiştirirsek bu sefer ona bağlı tüm classlarıda yeniden düzenlemek zorunda kalacağız. Çünkü arayüzle birleştirilmiş class birleştiriliği arayüz ile birebir aynı olmak zorundadır.

Yani biz tutupda arayüzü şu hale getiremeyiz.

< ?php
interface isim
{
	public function getName($name);
	public function getData();
}
?>

Bu şekile çevrilirse arayüz buna bağlı olan tüm classlar hata verecek ve işin içinden çıkılmaz bir hal alacaktır. Peki o zaman ne yapacağız mevcut yapıyı bozmadan nasıl kendi istediğimiz özellikleri bu isim arayüzüne ekleyeciz ? Classlar nasıl ki extends ile nasıl türetiliyor ise arayüzlerde bu şekilde türetilmektedir.

Derken biz bu arayüze bir metot daha tanımlamamız gerekti bu da ne olsun getSurname() metodu olsun yani girilen bir soyadını ekrana yazsın. Ama bunu yaparkende mevcut classları bozmasın.

Bunun içinde arayüzden arayüz türeteceğiz

< ?php
interface yeni_isim extends isim
{
	public function getSurname($surname);
}
?>

Hemen buna uygun sınıfımızı da yazalım

< ?php
class new_name implements yeni_isim
{
	public function getName($name)
	{
		echo $name;
	}

	public function getSurname($surname)
	{
		echo $surname;
	}
}
?>

Evet herşey bu kadar. Yeni sınıfımızı istediğimiz arayüze kolayca adapte etmiş olduk. Bir kaç açıklama daha yapmak gerekirse Name Classı sadece getName() metodunu çalıştırır getSurname() metoduna erişim yapamaz ancak New_Name Classı ise hem getName() hem de getSurname() metotlarına ulaşabilir çünkü yeni_isim arayüzünden türetildiği için getSurname() metodunu barındırmak zorunda kaldı yeni_isim de isim arayüzünden türetildiği için aynı zamanda getName() metodunu da barındırmak zorunda kaldı.

Örnek kullanımlarını da gösterelim daha anlaşılır olsun.

< ?php
$name = new name;
$name->getName('yusuf');
$name->getSurname('koç'); // Php Hata verecektir.

$new_name = new new_name;
$new_name->getName('yusuf');
$new_name->getSurname('koç');
?>

Görüldüğü üzere Adapter Pattern bu kadar.

Tagged with:  

Php Decorate Design Pattern

On Haziran 16, 2011, in Php, by Ysfkc

Decorate design pattern ile bir sınıfa başka bir sınıfı gömerek o sınıfa yeni bir sınıfın özelliklerini katmaya decorate pattern denir.
Decorate design pattern için bir interface tanımlayalım. Bu interface sabit bir metot içereceği için basit şekilde vereceğiz tabi siz kendinize göre oluşturabilirsiniz.

< ?php
interface isimDecorate
{
	public function __construct(isim $isim);
}
?>

yukarıdaki interface de bir yapılandırıcı metot tanımladık ve bu metota adı isim olan bir sınıfın geleceğini belirttik. Şimdi de interface için uygun bir sınıf yazalım.

< ?php
class isimDecorateClass implements isimDecorate
{
	public $isim;

	public function __construct(isim $isim)
	{
		$this->isim = $isim;
	}
}
?>

yukarıdaki isim sınıfımızı mevcut arayüzümüze göre yazdık. Yapılandırıcı metoduna isim adında bir sınıfın geleceğini ve bu gelen sınıfı da isimDecorate sınıfımızın içindeki publictanımlı $isim e aktaracağız.

Şimdide isim sınıfımızı tanımlayalım.

< ?php
class isim
{
	private $ad;
	private $soyad;

	public function adTanimla($ad)
	{
		$this->ad = $ad;
		return $this;
	}

	public function soyadTanimla($soyad)
	{
		$this->soyad = $soyad;
		return $this;
	}

	public function adVeSoyadGetir()
	{
		echo 'Adınız: '.$this->ad.' Soyadınız: '.$this->soyad;
	}
}
?>

Mevcut sınıflarımızı artık hazırladığımıza göre şimdi ise nasıl kullanacağız ona görelim.

< ?php
$isim = new isim;
$isim->adTanimla('yusuf');
$isim->soyadTanimla('koç');

$isimDecorate = new isimDecorateClass($isim);
$isimDecorate->isim->adVeSoyadGetir();
?>

Evet görüldüğü üzere önce isim sınıfımızı new ile başlatıp ad ve soyad tanımladıktan sonra oluşturduğumuz bu sınıfı isimDecorate içine gömdük ve isimDecorate sınıfına isim sınıfının özelliklerini katmış olduk.

Tagged with:  

Php Factory Design Pattern

On Haziran 16, 2011, in Php, by Ysfkc

Factory design pattern bize belirtilen sınıfları new operatörüyle başlatıp döndürür. Normal bir sınıf başlatmaktan pek bir farkı olmasada burdaki amaç bir nesne arayüzü yaratarak sınıflara erişimi bu arayüz üzerinden gerçekleştirmektir.

Örnek olarak bir factory pattern sınıfı yazalım. Bu sınıf bize belirtilen nesne adına göre uygun bir dizinden ( class ) ilgili classı bulup başlatıp döndürdürsün.

< ?php
class factory
{
	const class_dir = 'classes';
	public static function load($class)
	{
		try
		{
			if (file_exists(self::class_dir.'/'.$class.'.class.php'))
			{
				include_once(self::class_dir.'/'.$class.'.class.php');
				return new $class();
			}
			else
			{
				throw new Exception('Class Bulunamadı.');
			}
		}
		catch (Exception $e)
		{
			echo $e;
		}
	}
}
?>

Yukarıda tanımladığımız factory class bize belirtilen classın class_dir dizininde olup olmadığına bakarak eğer varsa bize başlatarak dönecektir eğer yok ise catch bloğu çalışarak class bulunamadı hatasını verecektir. Ayrıca yukarıdaki sınıfa göre sınıflar class_dir dizininde ve dosya adları da abc.class.php şeklinde olduğu varsayılmıştır.
Şimdi gelelim iki tane sınıf yazalım. Birtanesi girilen ismi yazsın diğer ise sadece soyadını yazsın. Örnekleri basit tutuyorum ki anlaşılabilsin diye sonra demeyin isim ve soyisimden başka bişey bilmiyor musun be adam sen diye

< ?php
class name
{
	public function getName($name)
	{
		echo $name;
	}
}
?>

Şimdide soyisim sınıfımızı tanımlayalım

< ?php
class surname
{
	public function getSurname($surname)
	{
		echo $surname;
	}
}
?>

Bu classları class_dir dizinine name.class.php ve surname.class.php olarak kaydettiğinizi varsayıyorum ve factory sınıfımızın kullanımına geçiyorum

< ?php
include_once('class_dir/factory.class.php');
$isim = factory::load('name');
$isim->getName('yusuf ');

$surname = factory::load('surname');
$surname->getSurname('koç');
?>

Yukarıda öncelikle factory sınıfımızı sayfamıza dahil ediyoruz ve ardından artık bize hangi sınıf gerekiyorsa onu factory sınıfımıza bildiriyoruz. Eğer sınıf belirtilen dizin içinde mevcutsa bize sınıfı başlatıp döndürüyor değil ise hata veriyor.

Bunun bize faydası sınıfları daha tertipli ve düzenli bir şekilde başlatma olanağı sağlıyor ve tek bir arayüz üzerinden istediğimiz değişikliğe gitmemize olanak sağlıyor.
Şöyle bir örnek verirsek sanırım daha iyi anlaşılacaktır. Farzedelim ki sınıflarınızı sayfalarınıza hep require veya include ile çağırdınız ve bir süre sonra sınıfları bir dizinde topladınız veya dizin adını değiştirdiniz. Ne yapmak lazım şimdi? Tüm sayfaları açıp require veya include satırlarını düzeltmek lazım. Ama eğer bunu factory pattern olarak düşünüp yazsaydık sadece factory classımızda değişiklik yaptığımızda tüm sitemizde uygulanmış olacaktı.

Tagged with:  

Php Prototype Design Pattern

On Haziran 16, 2011, in Php, by Ysfkc

Bazen oluşturduğumuz sınıfları tekrar tekrar kullanmak isteyebiliriz. Örneğin Ali’nin not bilgilerini getiren bir notgetir sınıfını aynı sayfada bir de Veli için kullanmak istediğimiz zaman notgetir sınıfını bu seferde Veli için new operatörü ile başlatıp erişim sağlardık.
Bu da yani tekrar new operatörü ile sınıfı başlatmak yine bellekte bir miktar yerin notgetir sınıfı için yeniden yer ayrılmasına neden olacaktı. Prototype pattern ile daha önceden new ile başlatılan sınıfın bir kopyasını alarak aynı sınıfı tekrar new operatörüyle başlatmaktan kaçınmış ve performans artışı sağlamış oluyoruz.

Bir örnekle bahsedelim hemen.

< ?php
class notgetir
{
	private $isim;
	private $not;

	public function isim($isim)
	{
		$this->isim = $isim;
		return $this;
	}

	public function not($not)
	{
		$this->not = $not;
		return $this;
	}

	public function getir()
	{
		echo $this->isim.' \'nin Notu: '.$this->not;
	}

	public function __clone() {}
}
?>

Yukarıda ismi ve notu belirtilen kişinin ismini ve not değerini ekrana yazan bir sınıf tanımladık. Burda yabancı olunulan metot __clone() dur. Bu metot bu sınıfın kopyalanabilir olmasını sağlar. Aslında yazmasakda kopyalanabilir ama bazen bazı durumlarda tanımlanan sınıfın kopyalanması başımıza iş açabilir o yüzden sınıfların kopyalanma özelliğini kapatmak için bu __clone() metodunu ya private yaparız ya da içine exception ya da exit ile bir uyarı mesajı koyabiliriz.

Konuyu dağıtmadan devam edelim. Şimdi biz Ali için bu sınıfı çağıralım ve verilen bilgiler doğrultusunda bu bilgileri ekrana yazsın

< ?php
$not = new notgetir;
$not->isim('Ali')->not(90)->getir();
?>

yukarıda sınıfı new operatörü ile başlattık ve hangi öğrencinin notunu istiyorsak onun ismini ve notunu set edip getir metodu ile ekrana yazdırdık. Şimdide aynı işlemi Veli için yapalım.

< ?php
$not2 = new notgetir;
$not2->isim('Veli')->not(100)->getir();
?>

Şimdi yukarıda ne yaptık aynı sınıfı tekrar new operatörü ile başlattık ve ram de bir miktar daha yer kapladık ve bu da haliyle zamanla kaynak tüketimine yol açıp performansı düşürecektir.

Aynı örneği şimdide bir prototipini oluşturarak yapalım. Aslında burda yapacağımız tek işlem daha önce Ali için başlatılmış sınıfın bir kopyasını almak.

< ?php
$not2 = clone $not;
$not2->isim('Veli')->not(100)->getir();
?>

Burda clone opetörü ile daha önce başlatılan notgetir sınıfının bir prototipini aldık yani kopyaladık böylelikle tekrar sınıfı başlatmaktan kurtulmuş olduk.
Bazılarınız $not2 = $not kısmı ile de yapılabilir bu diyebilir ama clone ile bu farklıdır. Aslında $not2 = $not demek $not2 nin $not a eşit olduğu anlamına gelir yani kopyasını almak değildir. Daha iyi anlayabilmek için aşağıdaki örneğe bakabilirsiniz.

< ?php
$not = new notgetir;
$not->isim('Ali')->not(90)->getir();

$not2 = $not;
$not2->getir();

$not3 = clone $not;
$not3->getir();
?>

Burda not2 $nota eşitleniyor ve getir metodu çağrıldığında ekrana Ali’nin notu 90 yazarken $not3 ile yine getir metodu çağrıldığında ekrana hiç bişey yazmayacaktır. Çünkü biz not3 değişkenine $not un kopyasını aldık.

Php Singleton Design Pattern

On Haziran 16, 2011, in Php, by Ysfkc

Ben gibi bir çok kişi de geliştiriği uygulamalarda zaman zaman uygulamaların büyüklüğüne göre sınıflar yazıp kullanmışızdır. Nesne yönelimli bu yazılımda en azından benim canımı sıkan olay bazen sayfalarda tek tek yazmış olduğumuz sınıfları çağırmak zorunda kalırız. Bu durum da ister istemez uygulamanın performansına etki etmektedir zira nesne yönelimli uygulamalar yazmak hoş olsada dikkat edilmediği zaman aşırı kaynak tüketimine yol açabilmektedir.

Bu yüzden bazı yazılım desenleri ortaya çıkmıştır. Benim bu yazıda size tanıtacağım yazılım deseni ise Singleton desenidir. Singleton deseni aslında bir sınıfın sadece bir kopya olmasını amaç edinmektedir. Yani bize lazım olacak bir veritabanı sınıfı uygulamada bir kez kullanmamız gerekmektedir. Çünkü veritabanı ile başka bir işlem yapmayacağızdır. Bu yüzden de birden çok veritabanı sınıf kopyası yerine daha önceden başlatılmış veritabanı sınıfını alıp kullanmaktır. Böylelikle kaynak tüketimini de boş yere harcamamış oluruz.

Singleton desenine geçmeden önce bu desen ile ilgili birşeyi atlamamamız gerekmektedir. Bu desende illaki static tanımlı erişim metodu olmak zorundadır. Static olma zorunluluğunun nedeni ise ramde tutulması içindir. Zaten bizde aynı sınıfa farklı bir yerde ihtiyaç duyduğumuzda daha önceden tanımlanmış ise ramden alacağız yoksada yeni başlatacağız.

Şimdi öncelikle bir bilgi sınıfı yazalım. Sınıf sadece girilen değerlere göre isim ve mesleği ekrana yazdırmak olacaktır.

< ?php
class bilgi
{
	private $isim;
	private $meslek;

	public function isimGir($isim)
	{
		$this->isim = $isim;
		return $this;
	}	

	public function meslekGir($meslek)
	{
		$this->meslek = $meslek;
		return $this;
	}

	public function bilgiGetir()
	{
		echo 'İsim: '.$this->isim.' Mesleği: '.$this->meslek;
	}
}
?>

Sınıfımızı yukarıdaki gibi tanımladık böylece artık kendisine verilen bir isim ve mesleği ekrana yazdıracaktır. Sınıfımız ile ilgili bir gelin bir örnek yapalım.

< ?php
include_once('bilgi.class.php');
$b = new bilgi;
$b->isimGir('Yusuf Koç')->meslekGir('PHP Developer')->bilgiGetir();
?>

evet ne yaptık bilgi sınıfını kullanabilmemiz için öncelikle sayfamıza dahil ettik ve $b = new bilgi; diyerek sınıfı başlattık. İlk etapda gayet normal gibi görünsede aynı sınıfı farklı sayfalarda da kullanmak istediğimizde yeniden çalışma sayfamıza dahil edip başlatmamız gerekecek ve kaynakta yeniden yer işgal etmiş olacağız.
İşte singleton desenide burda devreye giriyor. Sadece bir tane başlatıp devamında bu sınıf çağrılmak istendiğinde mevcut başlatılmış sınıfı bize döndürüyor.

Singleton deseni için sınıfımızı yazalım.

< ?php
class Singleton
{
	private static $sinif = array();
	private static $sinifDizin = 'class';
	public static $sinifSay = 0;

	private function __construct() { }

	public static function sinifOrnegiAl($sinif)
	{
		if (!(self::$sinif[$sinif] instanceof $sinif))
		{
			include_once(self::$sinifDizin.'/'.$sinif.'.class.php');
			self::$sinif[$sinif] = new $sinif;
			self::$sinifSay++;
		}
		return self::$sinif[$sinif];
	}
}
?>

Singleton sınıfımızı kısaca açıklamak istiyorum. Öncelikle sınıf içinde kullanmak üzere bazı değişkenler tanımladık. Ayrıca sınıfımızın yapılandırıcı fonksiyonunu da private olarak tanımlayarak $s = new Singleton; gibi kullanımların önüne geçmiş olduk.

sinifOrnegiAl() metodu ile kullanmak istediğimiz sınıf adını belirtiyoruz. Burda dikkat etmemiz gereken şey ben sınıf adını vererek class/sinifadi.class.php şeklinde bir dizinde tutup ordan include ettiriyorum siz kendinize göre düzenleyebilirsiniz devam edelim if bloğunda sınıf içinde static tanımlanmış sinif nesnesinin bize bildirilen sınıfın bir örneği olup olmadığına bakıyoruz eğer bir örneği değil ise istenilen sınıfı include edip başlatıyoruz ve return ile döndürüyoruz. Ayrıca burdaki $sinifSay her kullanımda bir artırarak kullanılan toplam sınıf sayısını elde ediyoruz.

Gelelim şimdi kullanımına. Öncelikle ana sınıfımızı kullanmak istediğimiz sayfalarımıza dahil ediyoruz ve Ardından aşağıdaki gibi başlatıyoruz.

include_once('class/singleton.class.php');
$bilgi = new Singleton; // Ölümcül Hata Alırsınız. Çünkü Direk Erişimi private function __construct() ile yasakladık.
$bilgi = Singleton::sinifOrnegiAl('bilgi'); // Doğru olan bu.
$bilgi->isimGir('Yusuf Koç')->meslekGir('PHP Developer')->bilgiGetir();

yukarıda iki satır yazdım ve açıklamalarınıda yanına yazdım. Evet böylelikle bilgi sınıfımız tanımlandı ve bir daha tekrar kullanılmak için singleton sınıfı ile çağrıldığında artık daha önce başlatıldıysa direk return etcek başlatılmadıysa başlatıp öyle return etcek.
Diyeceklerim bu kadar anlatım bozuklukları olabilir gördüğünüz yerleri bana Hakkımda kısmından mail atarak bildirirseniz gerekli düzenlemeleri yaparım.
Şimdilik Hoşçakalın…

WordPress SEO