Archive

You are currently browsing the archives for the Yazılım Mimarileri category.

Kas

18

Sihirli PHP __set ve __get metotları

By Hüseyin Bora

Bu makalede PHP de edindiğim bazı kolaylık ve deneyimleri aktarmaya çalışacağım
Profesyonel PHP programcılarının çoğu farklı bir dil üzerinde çalışıp PHP ye geçmiş kişiler olarak nitelendirdiğimizde örneğin Java, C# olabilir PHP yine de bu diller gibi düşünmeye başlar hâlbuki PHP tam anlamıyla bir betik dilidir ve benzer neyse yönelimli dillerden ayıran belirgin özellikleri vardır.

Ben ve çalışma arkadaşlarımın PHP üzerinde nesne yönelimli projeler geliştirirken ilk başlardaki PHP üzerindeki acemiliğimizden dolayı bir takım kodları Java da ya C# da yazarcasına geliştirmişiz. Bu günde pek çok PHP programcısının benzer hatalara düştüğünü görüyorum.

PHP’nin NYP yapısı diğer NYP dillerden ayrılan ve programcının işini kolaylaştıran bir yapıya sahip.
Örneğin NYP temellerinden Kılıflama(Encapsulation) bu prensip Java da Set ve Get metotları C# da ise set ve get propertyleri yazılarak gerçekleştirilir. PHP de de Set ve Get yaklaşımı kabul edilebilirse de bu konuda PHP de __get ___set isimlerinde iki sihirli metot tanımlanmıştır. Örneğin bir sınıfın içerisinde 5 adet private üye olsun Get ve Set metotlarını kullanmak istersek sadece Get ve Set için sınıfımız da 10 adet metot bulunması gerekir. PHP nin sihirli metotları ile bu iş basit 2 metot içerisinde halledilebilir.

Örnek

Class urun
{

private $id,$name,$prince,$paytyep,$order;

public function __set($n,$v)
{
$this->$n=$v;
}

public function __get($n)
{

return $this->$n;
}
}

Örnekte de görülebileceği gibi 10 metot ile yapılacak bu iş iki sihirli metot sayesinde basit ve sistem kaynaklarını daha verimli kullanır bir şekilde tasarlanmıştır.

Kas

5

RMI Nedir Uzaktan Metot Çağrımı (RMI – Remote Method Invocation)

By Hüseyin Bora

RMI nedir ?

Bir cihaz üzerinde çalışan Java nesnelerinin, başka bir cihaz üzerinde çalışan diğer Java nesnesinin metodunu çağırmasını sağlar. Bu önemli özellik dağıtık uygulamalar geliştirilmesine izin verir. Günümüzde SOAP, REST vb Web servislerinin gelişmesiyle RMI gibi benzer teknolojilerin kullanımı Web servisleri yönüne kaymaktadır.

RMI Sunucu, İstemci mimarisi üzerine kurulu olup, arabirimler ve serileştirme ile uzak metot çağrımı başarıya ulaşır.

rmi

RMI’ uygulamak genellikle 4 adım kullanılır

1- Sunucu tarafından sağlanan uzak arabirim

2- Uzak Arabirimi uygulayan uzak sınıf

3- Sunucu cihazın ana programı

4- İstemci cihaz tarafı

Buradaki örnek sunucu tarafında List arabirimini uygulayan bir List nesnesini istemci tarafına uzak metot çağırımı ile Gerçekleştireceğiz. Yani sunucu tarafında oluşturduğumuz bir listeyi istemciye göndericeğiz.

Adım 1- Sunucu tarafından sağlanan uzak arabirimi gerçekleştirmek. Tüm uzak arabirimler Remote Arabirimini genişletmek zorundadır Remote üye tanımlamaz, tüm uzak metotlar bir RemoteException fırlatabilir.

 
/** 
* ServerIntf.java 
* @author Hüseyin Bora
*/
import java.rmi.*;
import java.util.*;
public interface ServerIntf extends Remote {
public List getList()throws RemoteException;
 }

Adım 2 – ServerIntf uzak arabirimi uygulayıp uzak nesnelere uygunluğu sağlayan UnicastRemoteObject sınıfını genişletmek zorundadır.

 
/**
 * ServerImpl.java
 * @author Hüseyin Bora
 */
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
public class ServerImpl extends UnicastRemoteObject
implements ServerIntf{
    public ServerImpl()throws RemoteException{
    }
 
public List getList() throws RemoteException {
        ArrayList al = new ArrayList();
        for(int i= 1 ; i<10; i++)
        al.add(i);
        return al;
    }

}

Adım 3- Sunucu ana programının yazılması ana program şu adımları takip eder.

1- ServerImpl nesnesi oluşturmak.

2- RMI kayıdını güncellemek.

Kayıt işlemi Naming sınıfının rebind() metodu kullanılarak gerçekleştirilir. Bu metot bir adı bir nesne referansı ile ilişkilendirir.ilk parametre sunucuyu , ikinci parametre nesne referansını alır.

/**
 * Main.java
 * @author Hüseyin Bora
 */
import java.rmi.*;
import java.net.*;
public class Main{
    public static void main(String[] args) {
        try
        {
            ServerImpl serverobject = new ServerImpl();
            Naming.rebind("Main", serverobject);
        } 
        catch (Exception ex) {
           ex.printStackTrace();
        }
    }

Adım 4- İstemci tarafının gerçekleştirilmesi istemci tarafı rmi protokolünü kullanır Naming sınıfının lookup() metodunu çağırır bu metot bir rmi URL’si alır ve uzak nesneye bir referans döndürür.

/**
 * Client.java
 * @author Bora
 */
 
import java.rmi.*;
import java.util.*;
public class Client {
    public static void main(String[] args) {
        try {
            String rmiUrl = "rmi://localhost/Main";
            ServerIntf remote = (ServerIntf) Naming.lookup(rmiUrl);
            ArrayList al = (ArrayList) remote.getList();
            Iterator it = al.iterator();
            while (it.hasNext()) 
                System.out.println(it.next().toString());
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

RMI uygulamasının çalıştırması

Adımlar

1- Javac kullanarak Java kaynak dosyalarının derlenmesi.

2- Rmic kullanarak İkame ve iskelet kodları üretmek. Java2 iskelet kodlara gerek duymaz. rmic ile ikame kod üretecekseniz classpath’te geçerli dizinin ekli olması gereklidir.

3- Rmiregistr servisini yürütmek : komut satırından : start rmiregistry

4- Uygulamayı yürütmek : istemci cihazda bulunacak class dosyaları Client.class Oluşturulmuşsa ServerImpl_Stub.class ve ServerIntf.class sunucu tarafında bulunacak dosyalar : Main.class , ServerIntf.class , ServerImpl.class oluşturmuşsa iskelet kod ServerImpl_Skel.class.

Uygulamanın istemci cihaz izerinde çalıştığında 1-9 arası sayıları ekrana yazacaktır.

 
 
 
 

 

Eki

20

ORM nedir ? PHP ORM Faces İlişkisel Nesne Eşleştirme

By Hüseyin Bora

PHP ORM Faces
ORM nedir? İlişkisel Nesne Eşleştirme (Object Relation Mapping) basit bir anlatımla veritabanındaki tablolara karşılık gelen sınıflar ve bu sınıfların özelliklerine göre SQL cümleleri üretebilen bir yazılım mimarisidir diyebiliriz.

ORM Faces Çalışma Şeması

Tablolarımıza karşılık gelen bu sınıflara genel anlamda Varlık(Entity) sınıfları adını veriyoruz. Nesne yönelimli programlamada her şey birer nesne olarak düşünülmeli O halde veri tabanındaki işlemlerimizde nesneler olarak düşünmeliyiz. İşte burada ORM bize veritabanındaki tablolarımızı nesneleştirmemizi ve CRUD(create, read, update, delete) işlemlerimizi bir nevi basitleştirmemizi sağlamakta.

Örnek vermek gerekirse veritabanımızda urun adında bir tablo olduğunu ve urun tablosu için PHP tarafında Urun adında bir varlık sınıfımızın olduğunu varsayalım. Veri tabanındaki urun tablosuna yeni bir urun eklemek için

$urun = new Urun();
$urun->adi=”CPU”
$urun->fiyat=”124”;
$urun->save();

PHP Faces ORM yapısından faydalana bilmeniz için PHP PDO eklentisini aktif durumda olmalı.
PDO eklentisini php.ini dosyasından aktif duruma getirebilirsiniz. windows işletim sistemi için uzantılar. dll şeklinde olacak şekilde ayarlanmalı.

extension = pdo.so
extension = pdo_sqlite.so
extension = sqlite.so
extension = pdo_mysql.so

Ayrıca PHP Faces ORM yı tek başına yani Faces frameworkten bağımsız bir şekilde de kullanabilirsiniz bu makalede yazılanları hem framework dâhilinde hemde sadece orm kullanarak gerçekleştirebilirsiniz.

PHP Faces ORM katmanının frameworkten ayrılmış hali için indirme bağlantısı aşağıda hemen zip dosyalarını çıkarıp çalışmaya başlayabilirsiniz.

ORM Faces in bağımsız halini burdan indirin

Varlık sınıfları
Veritabanındaki tablolarınıza karşılık gelen varlık sınıfları Entity sınıfından genişletilir.
Tablonuzu varlık sınıfı ile eşleştirirken Açıklama Notu (Annotation) kullanırsınız bu hem kodunuzun okunabilirliğini sağlar hem de XML gibi başka bir dosyadan okumanın maliyetine katlanmaz kısacası XML ile eşlemeden daha verimlidir diyebiliriz.

Açıklama Notları ile Sınıfları eşleştirmek

PHP de Annotation kavramı henüz yerleşmemesine karşın Reflicaiton ile açıklama notları kullanılabilir.

Annotationlar açıklama satırları arasına @ et işareti kullanmak sureti ile oluşturulur.
Örneğin PHP Faces ORM da tablonuz ile sınıfınızı eşlemek için sınıf tanımlamasının üzerine @table notu eklenir. @Table notunun kullanımı aşağıdaki gibidir.

/**
*  @Table(name = "urun")
*/
class Urun extends Entity{ }

Yukarıdaki açıklama satırı ile Urun sınıfını veritabanındaki urun tablosuyla eşleştirmiş olduk.
Veritabanındaki tabloların sütunları ile varlık sınıflarının private üyeleri eşleşebilir sütunlar ile sınıf üyelerinin eşleşmesini sağlamak için sınıf üyesinin tanımlandığı yerin üzerine @Column notu eklenerek kullanılır. Örneğin ürün tablosunda id, fiyat, ad sütunları bulunduğunu varsayarak.

/**
*  @Table(name = "urun")
*/
class Urun extends Entity{
/**
@Column(name = "id")
*/

private $no;
/**
@Column(name = "fiyat")
*/

private $name;
/**
@Column(name = "ad")
*/

private $adi;
}

Varlık sınıfımıza bulunması gereken iki önemli metot vardır get ve set metotları. Bu metotların eklenme sebebi ORM Update gibi SQL cümleleri oluştururken hangi bilgilin değiştirildiğini bilmek zorunda olmasıdır. Örneğin sadece adını değiştirdiğimiz bir ürünün id ve fiyat sütunlarının güncellenmemesi gerekmektedir. Kısacası ORM Hangi Sınıfların hangi alanlarının update edilmesi gerektiğini anlamalıdır. Gereksiz güncellemelerle sistemi yormamalıdır.

Get ve Set metodları aşağıdaki sınıf içerisindeki gibi kullanılabilir.

/**
*  @Table(name = "urun")
*/
class Urun extends Entity{
/**
@Column(name = "id")
*/

private $no;
/**
@Column(name = "fiyat")
*/

private $fiyat;
/**
@Column(name = "ad")
*/

private $adi;

public function set($name, $value) {
$this->$name= $value;
}

public function get($name) {

return $this->$name;
}
}

Birincil anahtar eşleştirmesi @Id notunun eşleşecek olan sınıf üyesinin tanımlandığı yerin üzerine yazılması sureti ile gerçekleştirilir. Urun @Id notu eklenmiş son hali aşağıdaki aşağıda ki gibi olacaktır

/**
*  @Table(name = "urun")
*/
class Urun extends Entity{
/**
@Id
@Column(name = "id")
*/

private $no;
/**
@Column(name = "fiyat")
*/

private $fiyat;
/**
@Column(name = "ad")
*/

private $adi;

public function set($name, $value) {
$this->$name= $value;
}

public function get($name) {

return $this->$name;
}
}

Basitlik olması adına bu örneğimizi PHP Faces framework haricinde uygulama yolunu seçiyorum dilerseniz bu örnekleri bir controller içerisinde de uygulayabilirsiniz.

Veri tabanı ile bağlantının yapılandırılması

http://php-orm-persistence.googlecode.com/files/php-orm.zip adresinden indirdiğiniz klasör içerisindeki config.php dosyasını düzenlemek üzere bir editor yardımı ile açıyoruz. Ve aşağıdaki satırları kendi veritabanı yapılandırmamıza göre değiştiriyoruz.

define("DB_CONNECTION_STRING","mysql:host=localhost;dbname=veritabaniadi");//sunucunuz ve veritabanı adı
define("DB_USER","root");//veritabanı kullanıcı adı
define("DB_PASS","abc345");//veri tabanı parolası
define("DB_CONNECTOR","PDO");//bu satırı değiştirmeyin
>require_once "facespersistence/persistence.php";// PHP ORM Persistence kütüphanesi

Şimdi yeni bir php dosyası içerisine index.php olabilir yukarıda oluşturduğumuz Urun varlık sınıfını içeren urun.php ve config.php dosyalarını dahil ediyoruz.


require_once "config.php";

require_once "urun.php";

PHP Faces varlık sınıflarını yönetebilmemiz için EntityManager adında bir sınıf sunmakta sorgulama kaydetme, silme gibi tüm işlemlerimizi bu sınıf yardımı ile gerçekleştiriyoruz. EntityManager’ın örneğini elde etmek için static getInstance metodunu kullanabilirsiniz.

Urun tablosuna yeni bir satır eklemek


require_once "config.php";

require_once "urun.php";
$urun = new Urun();
$session = EntityManager::getInstance();
$urun->adi=”LCD Monitor”;
$urun->fiyat=”450”;
$session->save($urun);

EnitityManeger’ın find metodu parametre olarak varlık sınıfı adi ve varlık sınıfını tanımlarken @Id ile tanımladığımız birincil anahtar değerlerini kabul eder. Veritabanında verilen değerle göre sorgulama yapar sorgulama sonucu bir kayıt bulunursa birinci parametre olarak verilen sınıf isminde veritabanındaki verilerle eşleşen bir nesne döndürür.

Örnek
Urun tablosundan bir kayıt seçmek ve seçilen kayıt’ı güncelleştirmek


require_once "config.php";

require_once "urun.php";
$session = EntityManager::getInstance();
$urun = $session->find(“Urun”,1);
$urun->fiyat=”399”;
$session->save($urun);

Hem yeni bir kayıt eklemek hem de var olan bir kayıt’ı güncellemek için save metodunun kullanılması sizi şaşırtmasın ORM hangi kayıtın veri tabanından depolandığının bilincindedir.


require_once "config.php";

require_once "urun.php";
$session = EntityManager::getInstance();
$urun = $session->find(“Urun”,1);
$urun->fiyat=”399”;
$session->save($urun);

EnitityManeger’ın delete metodu parametre olarak verilen varlık sınıfıyla eşleşen satırları veritabanından kaldırır.


require_once "config.php";

require_once "urun.php";
$session = EntityManager::getInstance();
$urun = $session->find(“Urun”,1);
$session->delete($urun);

Faces Orm da Varlık sınıfları arasında ilişkiler
Varlık sınıfları arasındaki ilişkiler veritabanını tasarlarken yaptığınız ilişkilendirmelere benzer Varlık sınıflarında tanımladığınız ilişkilerin tablolarda bulunması da gerekmez.

PHP faces daki 4 adet ilişkisel annotation vardır

  • @OneToOne  (bire bir)
  • @OneToMany (bire çok)
  • @ManyToOne (bir çok a bir)
  • @ManyToMany (bir çok a bir çok)

Yukarıdaki dört annotationnında üç adet parametreleri bulunmaktadır

mappedBy = “Sınıf adı”

pk = ” birincil anahtar ”

fk = ” yabancı anahtar”

Urun tablomuzda yorumlar adında bir tabloya bir e çok ilişki bulunduğunu ve yorumlar adında da bir varlık sınıfımızın olduğunu varsayalım.

bire çok ve birçok a birçok ilişkilerde çok olan taraf bir ArrayObject olarak tanımlanmalıdır.

 /**
*  @Table(name = "urun")
*/
class Urun extends Entity
{
/**
* @Id
* @Column(name = "id",type ="INT")
*/

private $id;
/**
* @Column(name = "fiyat")
*/

private $fiyat;
/**
* @Column(name = "ad")
*/

private $ad;
/**
* @OneToMany(mappedBy ="Yorumlar", pk= "id", fk= "urunno")
*/

private $yorumlar;

public function Urun(){
parent::Entity();
$this->yorumlar = new ArrayObject();
}
function get($name) {

return $this->$name;
}
function set($name,$value) {
$this->$name = $value;
}
}

Yorumlar tablosu için varlık sınıfı bir yorum bir urun için yapılabileceği için yorumlar sınıfındaki ilişki tanımlaması @OneToOne şeklinde olmalıdır.

 /**
*  @Table(name = "yorumlar")
*/
class Yorumlar extends Entity
{
/**
* @Id
* @Column(name = "no")
*/

private $no;
/**
* @Column(name = "urunno")
* @ManyToOne(mappedBy ="Urun", pk= "urunno", fk= "id")
*/

private $urunno;
/**
* @Column(name = "yorum")
*/

private $yorum;
function Yorumlar($yorum=null)
{
parent::Entity();
$this->yorum= $yorum;
}
function get($name) {

return $this->$name;
}
function set($name,$value) {
$this->$name = $value;
}
}

Urun sınıfımızın yorumlar ismindeki üyesine erişerek yeni yorumlar ekleyelim


require_once "config.php";

require_once "urun.php";

require_once "yorumlar.php";
$session = EntityManager::getInstance();
$urun = $session->find(“Urun”,1);
$urun->fiyat=222;
$urun->yorumlar->append(new Yorum(“Bu bir denemedir yorum 1));
$urun->yorumlar->append(new Yorum(“ORM gerçekten kullanışlıdır buda yorum 2));
$session->save($urun);

Yukarıdaki Tek bir save satırı veritabanında 3 SQL cümlesi işletilir Yukarıda bahsettiğim gibi ORM hangi sınıfların veritabanından hangi sınıfların dışarıdan oluşturulduğunu algılayabilme kabiliyetine sahip olmalıdır. Sonuçda urun nesnesi için update,  urun sınıfın new ile oluşturulmuş her bir yorum nesnesi için insert cümleleri oluşturulur ve işletilir.

Yorumları aşağıdaki gibi listeleyebiliriz

Foreach($urun->yorumlar as $oku)
Echo $oku->yorum;

Yorum sınıfı urun sınıfın üyesi Urun sınıfı da yorum sınıfının üyesidir yorum nesnelerinden de urun’e ulaşılabilir. Tüm ilişkili varlık sınıfı nesneleri birbiriyle öz yinelemeli bir tekrar içindedirler ve bir birlerinin örneklerini referans olarak barındırırlar

Örnekler

$urun->yorumlar[0]->id;
$urun->yorumlar[0]->urun->adi;
$yorum->urun->adi;
$yorum->urun->yorumlar[1]->yorum->urun->adi;
$yorum->urun->yorumlar[0]->yorum->yorumlar[1]->urun->adi->yorumlar[3]->yorum;

Örnek PHP Faces Entity Framework üzerinde uygulama videosu



Eyl

8

Faces MVC (Model View Controller)

By Hüseyin Bora

Model-view-controller, yazılım mühendisliği’nde kullanılan bir “mimari desen”dir. Kullanıcıya yüklü miktarda verinin sunulduğu karmaşık uygulamalarda veri ve gösterimin soyutlanması esasına dayanır. Böylelikle veriler (model) ve kullanıcı arayüzü (view) birbirini etkilemeden düzenlenebilir. Model-view-controller, bunu controller adı verilen ara bileşenle, veri gösterimi ve kullanıcı etkileşiminden, veri erişimi ve iş mantığını çıkarma suretiyle çözmektedir.


M (Model), İş Mantığını ve data işleme süreçlerini yürütür. C (Controller) tarafından gönderilen emirlere göre hareket eder. Bilgi işleme sürecinden sonra datayı C’ye, diğer modellere veya doğrudan V (View)’ye gönderir.

PHP Faces Model katmanında PDO ve ORM Kullanır


V (View) son kullanıcıya gösterilecek olan datanın sunumu ile ilgilenir. V, bu bilgiyi C veya M’den alır, aynı zamanda son kullanıcıdan gelen talepleri C’ye iletir.


C (Controller)
C ise sistemin ana kısmıdır. Gelen talepleri kontrol eder ve sistemin diğer elemanlarının (M,V) bilgiyi uygun şekilde alıp, göndermelerini sağlar.


PHP Faces içerisinde üç farklı Controller barındırır bunlar

  1. ActionController
  2. FacesController
  3. Facet

ActionController sıradan olay yönelimli olamayan bir yapıdadır

FacesController olay yönelimlidir

Facet FacesController dan türemiş FacesController u basitleştirmiştir.


PHP Faces i diğerler MCV Çatılarından  ayıran özelliği ise Controller ve View arasında bileşenlerin bulunmasıdır

PHP Faces MVC için dizin yapısı şöyledir


AppPath:
/phpfaces : Framework folder

/applications : uygulamalar

app_bir /controllers

/views

/models

app_two  /controllers

/views

/models

.htaccess