The Singleton Pattern

Neredeyse her nesneye dayalı(OOP) programda genellikle bir veya birden fazla kaynak bir kere oluşturulur ve tüm uygulamanın sürekliliği için paylaştırılır. Bu tasarımda amaç, hiçbir kopyası olmayan bir kaynağı oluşturmak ve bu kaynağa uygulamanın herhangi bir parçasında erişebilmektir.

Bu tasarıma en iyi örnek veritabanı bağlantısıdır. Her veritabanı işlemi için bir kaynağı oluşturmak çok verimsiz bir işlemdir. Bunu yerine kaynak uygulamanın başlangıcında oluşturulur, tüm işlemler bu kaynak kullanılarak gerçekleştirilir ve uygulamanın sonunda yok edilir. Veritabanı bağlantısı gibi açılan dosya, kuyruk(queue) veya yığın(stack) işlemleri bu tasarıma örnek olarak verilebilir.

Peki biz belirli bir sınıfın örneğinin(instance) tek ve kolayca erişilebilir olduğundan nasıl emin olacağız? Bu problem evrensel(global) bir değişken kullanılarak çözülebilir fakat bu sefer bu değişken uygulamanın herhangi bir bölümünde değiştirilebilir ve bu istenmeyen bir durumdur.(http://c2.com/cgi/wiki?GlobalVariablesAreBad) Belirli bir sınıfın her seferinde tek bir örneğine erişmek istiyorsak Singleton tasarım kullanmamız gerekir. Bu tasarımda sınıfımızın tek bir örneğine erişmek için sabit bir getInstance yöntemi(method) kullanırız.

Örnek Kodlar

Örnek olarak PHP4 ile evrensel değişken kullanılarak oluşturulmuş bir singleton tasarımı inceleyelim.

class DbConnection {
    var $connection;
    function DbConnection( $fromGetInstance=false ) {
        if (M_E != $fromGetInstance) {
            trigger_error('Bu sınıfa direk erişemezsiniz.');
        } else {
            $this->connection = mysql_connect();
        }
    }
    function &getInstance() {
        $key = 'dbConn';
        if ( !( array_key_exists( $key, $GLOBALS ) &&
              is_object( $GLOBALS[$key] ) &&
              'DbConnection' == get_class($GLOBALS[$key]) )) {
            $GLOBALS[$key] =& new DbConnection(M_E);
        }
        return $GLOBALS[$key];
    }
}

Yukarıdaki örnek kodumuzda $fromGetInstance değişkeni sınıfa direk ulaşılmasını engelleyen varsayılan bir değişkenimiz. Varsayılan değişken e‘den farklı olursa ‘Bu sınıfa direk erişemezsiniz.’ hatasını veriyoruz. getInstance yöntemi ile sınıfımız oluşturulunca new DbConnection(M_E) ile sınıfımızı oluşturuyoruz. Bu yöntemde bizim belirlediğimiz $GLOBALS evrensel değişkenine $key değişkenine dbConn değerini atıyoruz. Öncellikle önceden bu değişken oluşturulmuş mu, değişkenin değeri bir nesne mi ve nesne ise nesenemizin ismi DbConnection mı kontrollerini yapıyoruz. Bun koşullar var ise aynı değişkeni döndürüyoruz değilse sınıfmızı oluşturuyoruz. Bu örnekte gördüğümüz gibi $key değişkeni uygulamanın herhangi bir yerinde değişirse sınıfımız yeniden oluşturulacaktır.

PHP5’de Singleton tasarım örneği;

class DbConnection() {
    private static $_instance = null;
    private $_connection = null;
    private function __construct() {
        $this->_connection = mysql_connect();
    }

    /**
     * sınıfın kopyasının çıkarılamasını engelliyoruz.
     */
    private function __clone() {}
    private function __wakeup() {}

    /**
     * Sınıfın sadece tek bir örneğinin olmasını sağlıyoruz.
     */
    public static function getInstance() {
        if (!self::$_instance instanceof self) {
            self::$_instance = new self( $DBConn );
        }
        return self::$_instance;
    }
}

$DBConn = DbConnection::getInstance();

Bu örneğimizde sınıfın yapıcısını(constructor) private yaparak dışarıdan erişilmesini engelliyoruz. Sınıfımızı oluşturmak için getInstance yöntemini kullanıyoruz. Bu yöntem içerisinde sadece sınıfmızın içerisinden erişilebilen $_instance değişkeninin DbConnection sınıfı olup olmadığına bakıyoruz. Değil ise sınıfımızı oluşturuyoruz. Aynı ise $_instance değişkeni geri döndürüyoruz.

Print Friendly, PDF & Email

Bir Cevap Yazın

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