entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Buenas tardes y saludos desde España.

Actualmente soy un programador muy novel. Me gustaría desarrollar un CMS de un blog orientado a objetos con PHP. He programado algo, pero me he topado con el siguiente problema. Necesito instanciar varios objetos para poder mostrar las cosas, y no sé si está bien eso. Este es el código.

<?php

class netConnect {
    private $host;
    private $user;
    private $pass;
    private $db;

    public function __construct(){

       $this->host = 'localhost';
       $this->user = 'root';
       $this->pass = '[email protected]';
       $this->db = 'EJEMPLO';
       $this->conn = new mysqli($this->host,$this->user,$this->pass,$this->db);
    }

    public function closeConnect(){
        $this->conn->close();
    }
 }

 class Blog extends netConnect {
   private $title;
   private $desc;
   private $kw;
   private $createD;
   private $modD;
   private $lang;
   private $socMed;
   private $favIcon;
   private $status;

     public function getBloginfo(){
       $sql="SELECT * FROM user";
       $getData = $this->conn->query($sql);
       print_r($getData);
     }
  }
  class user extends netConnect {
   private $usuario;
   private $nombre;

   public function getData(){
       $sql="SELECT * FROM user";
       $getResult = $this->conn->query($sql);

    while ($row = $getResult->fetch_array()){
        $this->usuario =$row[0];
        echo $this->usuario;
    }
    echo $this->usuario;
}

public function insData($x,$i){
    $sql="INSERT INTO user (user,nombre) VALUES ('$x','$i')";
    if($this->conn->query($sql)){
        print "Correct";
    }
  }
}

   $new = new netConnect();
   $new2 = new user();
   $new3 = new Blog();
   $new3->getBlogInfo();
   $new2->getData();
   $new2->insData('Hola','Musica');
?>

Me pregunto si el planteamiento es correcto.
SRC basado en CC-BY-SA 3.0

1 Respuesta

2votos

Leonardo-Tadei Puntos227010

Hola Netsys,

No hay una única solución correcta a la hora de diseñar un Modelo en POO. Sin embargo suele no considerarse correcto un Modelo de classe que no siga el principio SOLID.

En tu caso, lo que estás haciendo no es pensar en Objetos, sino crear clases que siguen a la base de datos, que usa principios completamente distintos de construcción. Funcione o no funcione, está seguro mal diseñado.

Fijate por ejemplo en tu asignación de responsabilidades: la clase User tiene la responsabilidad de la conexión (por herencia), la de insertar un usuario y también la de devolver la lista de todos los usuarios!

Si en tu Modelo el User solo hace ABM contra la DB, construyendo una especie de ActiveRecord, más te valdría hacer las conexiones con PDO y devolver Objetos Standard, ya que no hay ningún comportamiento asociado!

Preguntate: qué hace el User en este sistema? Qué responsabilidades tiene? Preguntate esto por cada Objeto para justificar su existencia en el Modelo... hay veces en que User no existe, sino que existe por ejemplo Publicador, y entre sus atributos hay un nombre de usuario y contraseña entre todas las cosas más que seguramente hará...

Por otra parte y como pauta, no deberías nunca tener una query en un Objeto del Modelo! Las querys estarán en las clases que se encargen de usar la DB, justamente por una cuestión de correcta asignación de responsabilidades.

Respecto a la POO y las DB, buscá los conceptos de Persistencia de Objetos y el Problema de la Impedancia de Paradigmas para darte una buena idea de cómo se termina guardando algo en el disco.

Si te interesa trabajar con un modelo de Objetos puro, te dejo un enlace una Mapeador Objeto/Relacional (ORM) que hace persistencia no invasiva y por alcance en PHP https://github.com/PegasusTech/Persistent . Es GPL así que lo podés usar libremente para cualquier propósito (se aceptan donaciones de ejemplos para mejorar la documentación). Verás que las clases no tienen ni una sola línea de código ni comentario acerca de cómo se almacenan (esto es lo de No Invasivo) y que si un Objeto tiene por composición o por agregación a otro Objeto, al persistirlo se persisten ambos y al hidratarlo se recuperan ambos (eso es lo de Por Alcance).

Yo te recomendaría primero leer algo más de teoría sobre diseño en Objetos... seguro que cualqueir código que escribas terminará funcionando, pero si estás aprendiendo y aplicás mal los conceptos, te va a costar mucho trabajo dentro de un tiempo cambiar para corregirlos.

Saludos!

0voto

netSys comentado

Buenas Leonardo,

Muchas gracias por responderme. Tengo identificada las necesidades del objeto User por ejemplo.

En este caso según entiendo, no debería asignarle parámetros que están igualados en la tablar user de la base de datos. Sino que debe tener sus propios atributos en la clase User.
Además, de ello, debería tener una clase que herede de la clase User. Para poder incluir un Anónimo por ejemplo, un Administrador y un Editor ¿cierto?.

En el caso de los métodos, cada usuario tendría un acceso a las consultas como ABM como mencionaste como por ejemplo.
publicarPost($sql);
deletePost($sql);
publicarComentario($sql);
...

Pero según esto, me siembra la duda con lo que comentaste anteriormente:
"...Las querys estarán en las clases que se encargen de usar la DB, justamente por una cuestión de correcta asignación de responsabilidades."

Para poder acceder a esa clase debería heredar User de la clase netConnect(){} para poder realizar las funciones como publicar artículos (sentencias INSERT...)...etc?

Respecto al PDO lo estuve viendo y está muy bien sobre todo por el soporte múltiple de SGBD.

0voto

Leonardo-Tadei comentado

Hola @netSys,

por tu comentario, parecería que te salteaste toda la teoría que pudiste sobre diseño de Objetos :-(
Vayamos por partes:

Cuando diseñas Objetos, es decir, jerarquías de clases, tenés que clasificar por las responsabilidades (que implementarás como métodos) y no por lo atributos. Como las bases de datos corresponden a un paradigma diferenet, no hay manera posible de igualar entidades de ambos mundos... si bien se puede prestar a confusión que almacenes los atributos de un Objeto en campos de una tabla de una base de datos. En este punto, da lo mismo si el atributo se llama igual que el campo o si está mapeado de alguna manera y se llama distinto, como da lo mismo que se guardan los Objetos de una misma clase en una tabla o en varias.

No tiene sentido tu planteo de herencia de la clase User para implementar Anónimo, Administrador o Editor. Un diseño posible sería tener un Objeto Rol por agregación en el Objeto User, y dependiendo del Rol saber qué puede hacer. Peeeeeero, si para determinar el rol bastara con un número (1, 2, 3, etc) o con un nombre, no hay justificación alguna para que exista el Objeto Rol, ya que no tiene ningún comportamiento (método).

Siguiendo, te decía en la primer respuesta que un diseño de Objetos está definitivamente mal si los mensajes son querys como estás proponiendo. Tampoco tiene sentido decoe que cada usuario tendría acceso a ciertos métodos: todos los Objetos de una misma clase tendrán acceso a todos sus métodos. Tu confusión creo que viene de pensar en una jerarquía de clases en que los descendientes tengan métodos de acceso para cada rol en el sistema, de manera tal de que los de más arriba en la jerarquía tengan menos métodos que los de más abajo, pero podés llegar a esta conclusión solo si estás pensando en tablas de bases de datos y en que la única responsabilidad de los objetos es hacer querys, cuando justamente si modelás en base a responsabilidades, habrá un único Objeto que se encargue de hacer querys (esa será su única responsabilidad) y los demás Objetos se encargará cada uno de sus propias tareas.

Por último, estás pensando en que la única forma de que un Objeto hjaga algo sea por herencia, cuando en realidad la herencia es el mecanismo menos flexible del mundo. Un Objeto puede hacer algo porque tiene por composición o por agregación a otro Objeto que se encarga o simplemente por una colaboración, es decir, que un método instancia localmente a otro Objeto, lo usa y lo tira.

Un buen ejemplo de esto último sería el formateo de fechas: si tenés por ejemplo 5 clases que necesitan pasar fechas del formato de EEUU al español, según lo que vos estás pensando estas 5 clases tendrían que heredar del formateador de fechas! Suena menos absurdo pero estaría igual de mal que las 5 clases impementen los métodos de formateo, ya que en ese caso tendrías 5 veces repetido el código. Lo correcto es plantear una colaboración para que el método que necesite el formateo cree una instancia del formateador de fecha, use al Objeto y lo destruya: de esta forma tenés el código de formateo una sola vez, nadie hereda del formateador y muchos lo pueden usar, pero además lo instanciarán solo si hace falta. Se entiende la idea?

Dado que estás planteando como problema un blog, tal vez te sea útil ver la arquitectura de Joomla, que está bien documentada y, si bien es ya todo un framework y es un poco compleja, está muy bien diseñada.

Saludos cordiales!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta