2009-02-15 26 views
5

Memcache sunucusuyla etkileşimde bulunmak için bir sınıfım var. Veri eklemek, silmek ve almak için farklı işlevlerim var. Başlangıçta her işlevi üç Memcache'ı bağlantılarını yapacak gereksiz ancak memcache_connect() bir çağrı, ör .:PHP'de işlevler arasında globals kullanmadan paylaşım değişkenleri

mc->insert() 
mc->get() 
mc->delete() 

yaptı. Ders için bir yapı oluşturarak çalıştı: o

function __construct() { 
    $this->mem = memcache_connect(...); 
} 

ve kaynak gerekli yerde $this->mem kullanılarak, bu üç işlevin her biri aynı memcache_connect kaynak kullanımı.

Bu Sonra yine iki memcache_connect çağrıları yapıyor .: ör diğer sınıflar içindeki sınıf

class abc 
{ 
    function __construct() { 
     $this->mc = new cache_class; 
    } 
}  
class def 
{ 
    function __construct() { 
     $this->mc = new cache_class; 
    } 
} 

diyoruz ancak eğer tamam olduğunda yalnızca ihtiyacı biri.

Bunu globals ile yapabilirim ama eğer yapmam gerekirse bunları kullanmamayı tercih ederim.

Örnek globaller uygulaması:

$resource = memcache_connect(...); 

class cache_class 
{ 
    function insert() { 
     global $resource; 
     memcache_set($resource , ...); 
    } 
    function get() { 
     global $resource; 
     return memcache_get($resource , ...); 
    } 

} 

Sonra sınıf olarak adlandırılır kaç kez olursa olsun sadece memcache_connect bir çağrı olacaktır.

Bunu yapmanın bir yolu var mı yoksa sadece globals kullanmalı mıyım? MC örneğinde

cevap

9

.

class MemCache 
{ 
    private static $instance = false; 
    private function __construct() {} 

    public static function getInstance() 
    { 
    if(self::$instance === false) 
    { 
     self::$instance = memcache_connect(); 
    } 

    return self::$instance; 
    } 
} 

ve kullanımı - - Bunun gibi

$mc = MemCache::getInstance(); 
memcache_get($mc, ...) 
... 
+0

Bu makul bir çözümdür, ancak bununla yüzleşelim, bu bir küreseldir. :) – cletus

+0

Yapacağım bu. Bunu test edemezsin, ama dürüst olalım, bu tür şeyleri kim test ediyor? –

+0

Sorunun, küçük bir parçanın test edilememesi durumunda, tüm kodun geri kalanının nasıl test edilebileceğidir. Veya diğer testler için simüle edilmiş bir MemCache nesnesini nasıl uygularsınız? – okoman

5

Geçiş:

class abc 
{ 
    function __construct($mc) { 
     $this->mc = $mc; 
    } 
}  
class def 
{ 
    function __construct($mc) { 
     $this->mc = $mc; 
    } 
} 

$mc = new cache_class; 
$abc = new abc($mc); 

vb Ben memcache tek örneğini almak için tekil deseni kullanarak başka bir sınıf kodlayacağınıza

2

Burada statik özellikler arıyoruz düşünüyorum.

class mc { 
    private static $instance; 

    public static function getInstance() { 
     if (self::$instance== null) { 
      self::$instance= new self; 
     } 
     return self::$instance; 
    } 

    private function __construct() { 
     $this->mem = memcache_connect(...); 
    } 
} 

Bu, temel bir tekil kalıbı uygular. Nesne çağrısı mc::getInstance()'u oluşturmak yerine. singletons'a bir göz atın.

+0

İnsanların, bir cevabın ilk cümlesinden başka bir şey okumadan sonra nasıl oy kullandığını görmek. Yine +1. – Tomalak

1

Bağımlılık enjeksiyonunu kullanmalısınız. Tekil patern ve statik yapılar kötü bir uygulama olarak kabul edilir çünkü bunlar aslında globals'lardır (ve iyi bir nedenden dolayı - sizi başka herhangi bir sınıfın karşısına çıkartacağınız herhangi bir sınıfı kullanarak çimentolarlar).

Kolay bakım için yapmanız gerekenler gibi bir şey.

class MemCache { 
    protected $memcache; 

    public function __construct(){ 
     $this->memcache = memcache_connect(); 
    } 
} 

class Client { 
    protected $MemCache; 

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

    public function getMemCache(){ 
     return $this->MemCache; 
    } 
} 

$MemCache = new MemCache(); 
$Client = new Client($MemCache); 
$MemCache1 = $Client->getMemCache(); 

// $MemCache and $MemCache1 are the same object. 
// memcache_connect() has not been called more than once. 
İlgili konular