2012-02-10 37 views
5

Estoy tratando de crear una clase singleton fácil de usar para conectarse a la base de datos mysql y hacer consultas, el código funciona bien y no he tenido ningún problema con él, pero como soy nuevo en OOP me pregunto si esto es una mala práctica o no.conexión de base de datos de php singleton, ¿es este código una mala práctica?

Aquí está la clase

class Database { 
private $databaseName = 'dbname'; 
private $host = 'localhost'; 
private $user = 'user'; 
private $password = 'pass'; 
private static $instance; //store the single instance of the database 

private function __construct(){ 
    //This will load only once regardless of how many times the class is called 
    $connection = mysql_connect($this->host, $this->user, $this->password) or die (mysql_error()); 
    $db = mysql_select_db($this->databaseName, $connection) or die(mysql_error()); 
    echo 'DB initiated<br>'; 
} 

//this function makes sure there's only 1 instance of the Database class 
public static function getInstance(){ 
    if(!self::$instance){ 
     self::$instance = new Database(); 
    } 
    return self::$instance;  
} 

public function connect() { 
    //db connection 
} 
public function query($query) { 
    //queries 
    $sql = mysql_query($query) or die(mysql_error()); 
    return $sql; 
} 

public function numrows($query) { 
    //count number of rows 
    $sql = $this->query($query); 
    return mysql_num_rows($sql); 
} 


} 

//Intantiate the class 
$database = Database::getInstance(); 

y cuando quiero usar la clase que haría:

$query = "SELECT * FROM registrations"; 
echo $database->numrows($query); 
$sql = $database->query($query); 
+0

El patrón Singleton a menudo se implementa en clases de base de datos, registradores, controladores frontales o objetos de solicitud y respuesta. – diEcho

+0

no veo ningún problema en este – jere

+0

Hay un montón de clases de DB que puedes ver. Incluso mire marcos como codeigniter para ver cómo funcionan sus clases de db. –

Respuesta

12

Los singletons son malas noticias.

  • Introducen el estado global en un programa. La mayoría de los programadores deben estar familiarizados con por qué el estado global es malo.
  • Introducen el acoplamiento hermético entre el singleton y cualquier clase que lo use. Esto significa que no puede reutilizar las clases en cuestión sin reutilizar el singleton también.
  • Hacen que las pruebas unitarias de las clases que dependen del singleton sean problemáticas porque no se puede reemplazar fácilmente el singleton con un simulacro.
  • Fomentan un estilo de codificación donde las clases intentan resolver sus propias dependencias. Esto es malo porque puede reducir la claridad con respecto a las dependencias que tiene la clase.
  • PHP tiene una arquitectura Nothing Nothing, lo que significa que los singletons de PHP no son en absoluto simples, puede haber varias instancias activas al mismo tiempo (una por solicitud abierta).
  • ¿Qué sucede si de repente descubre que en realidad necesita más de uno de los recursos proporcionados por el singleton? Es un escenario más común de lo que podría pensar

En su lugar, es mejor que mire en , ya que resuelve los problemas anteriores.

+0

¿Puede proporcionar algunos buenos artículos sobre 'dependency-injection' y alguna explicación de por qué" Registry for database "es una mala idea? (Sé que puedo googlearlo, pero algo con calidad confirmada y de fuentes confiables) – Vyktor

+0

Los registros son como Singleton en la mayoría de los aspectos (estado global, alentar a las clases a resolver dependencias, etc.). En cuanto a DI, hay muchos artículos por ahí si googleas, como dijiste. :) Creo que la documentación para el marco Symfony incluye una discusión bastante buena de DI en un contexto PHP. – GordonM

+0

¿Qué pasa con la clase de autocargador, con (extensión de mi respuesta) 'get ($ connName)' inicializará la conexión automáticamente con 'configs/$ connName.ini'? Entiendo que debe proporcionar "Modelo" con conexión desde "Controlador" y el modelo no debería hacer nada como 'DBs :: get ('exportar')', pero ¿qué hay de malo en tener la conexión predeterminada especificada? – Vyktor

0

Este patrón va a estar bien porque el producto único sólo se aplicará a la sesión del usuario actual. La decisión realmente se reduce a cuál es tu prioridad. Si desea un rendimiento más rápido para el usuario, entonces desea permitir más conexiones de base de datos por usuario, pero si desea limitar la fuerza con la que se golpea su base de datos, entonces el singleton le brinda un buen centro de la ruta.

+1

Singletons son malas noticias. Deben ser evitados. – GordonM

+0

@GordonM, muy cierto. Su abogado es la solución más prudente a largo plazo. – davidethell

2

Creo que un singleton puede estar bien para un administrador de conexión, pero no para una conexión en sí misma.

Nunca se sabe cuándo necesitará tener una conexión adicional para una parte específica de su desarrollo. Digamos que de repente necesitas agregar una sincronización con una base de datos remota.

Un administrador de conexión (que puede administrar conexiones múltiples) puede ser un singleton. Una conexión en sí misma; no.

Su administrador de conexión también debería poder cargar "Controladores", para que pueda instanciar una conexión MySQL y el día que necesite msSQL, sqLite o cualquier otra cosa, puede agregar los controladores necesarios .

2

Yo diría que depende de la forma en que use la clase. Si llama al Database::getInstance() cada vez que quiere usar una base de datos, es malo desde la perspectiva de OO, porque daña la capacidad de prueba. Si lo hace solo una vez y luego inyecta la instancia a los objetos que necesitan trabajar con la base de datos, no es tan malo usar singleton (pero aún no es necesario).

sugiero que mire la dependencia concepto de inyección: http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/ o http://fabien.potencier.org/article/11/what-is-dependency-injection

0

El único argumento positivo que he oído para el patrón de diseño Singleton en PHP era de un desarrollador que implementa una conexión de base de datos de Singleton en conjunto con un objeto Memcached. Realmente no tuve la oportunidad de ver el código y el rendimiento, pero él fue capaz de presentar un argumento coherente.

Personalmente, no creo que el patrón de diseño de Singleton sea muy relevante para PHP, que en gran parte es apátrida de todos modos (como se señaló antes, cada solicitud tendrá un singleton).

Cuestiones relacionadas