2009-02-15 41 views
5

Tengo una clase para interactuar con un servidor de memcache. Tengo diferentes funciones para insertar, eliminar y recuperar datos. Originalmente cada función realiza una llamada a memcache_connect(), sin embargo, que no era necesaria, por ejemplo .:Compartir variables entre funciones en PHP sin usar globales

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

haría tres conexiones memcache. He trabajado en torno a este mediante la creación de una construcción para la clase:

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

y luego usando $this->mem donde se necesita el recurso, por lo que cada una de las tres funciones utilizan el mismo recurso memcache_connect.

Esto está bien, sin embargo si llamo a la clase dentro de otras clases, por ejemplo .:

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

entonces todavía está haciendo dos memcache_connect llamadas, cuando sólo necesidades uno.

Puedo hacer esto con globales, pero preferiría no utilizarlos si no fuera necesario.

Ejemplo globales aplicación:

$resource = memcache_connect(...); 

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

} 

Entonces no importa cuántas veces se llama la clase no sólo será una llamada a memcache_connect.

¿Hay alguna manera de hacer esto o debería simplemente usar globales?

Respuesta

9

Me codificar otra clase con el patrón Singleton para conseguir la única instancia de Memcache. Como esto -

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

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

    return self::$instance; 
    } 
} 

y uso -

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

Es una solución razonable pero, seamos sinceros, es un proceso global. :) – cletus

+0

Esto es lo que haría. No puedes probarlo, pero seamos honestos, ¿quién prueba este tipo de cosas de todos modos? –

+0

La pregunta es cómo se puede verificar el resto del código si una parte pequeña no se puede probar. ¿O cómo implementaría un objeto MemCache simulado para otras pruebas? – okoman

5

Pass en el caso MC:

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

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

etc.

2

Creo que estás en busca de propiedades estáticas aquí.

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(...); 
    } 
} 

Esto implementa un patrón de singleton básico. En lugar de construir el objeto, llame al mc::getInstance(). Eche un vistazo al singletons.

+0

Es curioso cómo votan las personas después de haber leído no más que la primera oración de una respuesta. +1 de nuevo. – Tomalak

1

Debe usar la inyección de dependencia. El patrón singleton y las construcciones estáticas se consideran malas prácticas porque básicamente son globales (y por una buena razón: te ciñen a utilizar cualquier clase que instanciares en oposición a alguna otra).

Aquí hay algo así como lo que debe hacer para tener un mantenimiento fácil.

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. 
Cuestiones relacionadas