Trabajo mucho en WordPress y he notado que muchas más funciones devuelven objetos que matrices. Los resultados de la base de datos se devuelven como objetos a menos que solicite específicamente una matriz. Los errores se devuelven como objetos. Fuera de WordPress, la mayoría de las API le brindan un objeto en lugar de una matriz.
Mi pregunta es, ¿por qué usan objetos en lugar de matrices? En su mayor parte, no importa demasiado, pero en algunos casos encuentro los objetos más difíciles no solo de procesar, sino de entender. ¿Existe una razón de rendimiento para usar un objeto?
Soy un programador PHP autodidacta. Tengo un título en artes liberales. Así que perdóname si me falta un aspecto fundamental de la informática. ;)
count()
oarray_*()
funciones en ellos (al menos en lo que respecta a almacenar / devolver datos clave => valor). Nadie parece mencionarlo, ¿o me estoy perdiendo algo?count()
a un objeto.stdClass
). No estoy seguro de que esta pregunta tenga una respuesta que no sea "Porque los programadores que trabajan principalmente en OOP prefieren la semántica del uso de objetos"Respuestas:
Estas son las razones por las que prefiero los objetos en general:
Aquí hay algo para leer:
fuente
Probablemente esto no sea algo que vaya a comprender profundamente hasta que haya trabajado en un gran proyecto de software durante varios años. Muchos estudiantes recién graduados en ciencias de la computación le darán una respuesta con todas las palabras correctas (encapsulación, funcionalidad con datos y capacidad de mantenimiento), pero pocos entenderán realmente por qué es bueno tener todo eso.
Repasemos algunos ejemplos.
Piense en un método de API que devuelva una lista de publicaciones de WordPress. Todas estas publicaciones tienen autores, los autores tienen nombres, direcciones de correo electrónico, tal vez incluso perfiles con sus biografías.
Si está devolviendo todas las publicaciones en una matriz, deberá limitarse a devolver una matriz de ID de publicación:
[233, 41, 204, 111]
o devolviendo una matriz masiva que se parece a:
[ title: 'somePost', body: 'blah blah', 'author': ['name': 'billy', 'email': '[email protected]', 'profile': ['interests': ['interest1', 'interest2', ...], 'bio': 'info...']] ] [id: '2', .....]]
El primer caso de devolver una lista de ID no es muy útil para ti porque luego necesitas hacer una llamada a la API para cada ID para obtener información sobre esa publicación.
El segundo caso obtendrá mucha más información de la que necesita el 90% del tiempo y estará haciendo mucho más trabajo (especialmente si alguno de esos campos es muy complicado de construir).
Un objeto, por otro lado, puede proporcionarle acceso a toda la información que necesita, pero aún no ha obtenido esa información. La determinación de los valores de los campos se puede hacer de forma perezosa (es decir, cuando se necesita el valor y no de antemano) cuando se usa un objeto.
Vuelva al ejemplo de la matriz masiva que se devuelve. Ahora es probable que alguien construya una aplicación que repita cada valor dentro de la matriz de publicaciones y lo imprima. Si la API se actualiza para agregar solo un elemento adicional a esa matriz de publicaciones, entonces el código de la aplicación se romperá ya que imprimirá un campo nuevo que probablemente no debería. Si cambia el orden de los elementos en la matriz de publicaciones devuelta por la API, eso también romperá el código de la aplicación. Entonces, devolver una matriz crea todo tipo de posibles dependencias que un objeto no crearía.
Un objeto puede contener información dentro de él que le permitirá brindarle una funcionalidad útil. Un objeto de publicación, por ejemplo, podría ser lo suficientemente inteligente como para devolver las publicaciones anteriores o siguientes. Una matriz nunca podría hacer eso por ti.
Todos los beneficios de los objetos mencionados anteriormente ayudan a crear un sistema más flexible.
fuente
Probablemente dos razones:
No. Pero muchas otras buenas razones, por ejemplo:
¡ OOP ! = AOP :)
(Por ejemplo, en Ruby, todo es un objeto. Anteriormente PHP era un lenguaje de procedimientos / secuencias de comandos).
fuente
WordPress (y una buena cantidad de otras aplicaciones PHP) usa objetos en lugar de matrices, por razones conceptuales más que técnicas.
Un objeto (incluso si solo es una instancia de stdClass) es una representación de una cosa. En WordPress, puede ser una publicación, un comentario o un usuario. Una matriz, por otro lado, es una colección de cosas. (Por ejemplo, una lista de publicaciones).
Históricamente, PHP no ha tenido un gran soporte de objetos, por lo que las matrices se volvieron bastante poderosas desde el principio. (Por ejemplo, la capacidad de tener claves arbitrarias en lugar de tener un índice cero). Con el soporte de objetos disponible en PHP 5, los desarrolladores ahora pueden elegir entre usar matrices u objetos como almacenes de clave-valor. Personalmente, prefiero el enfoque de WordPress porque me gusta la diferencia sintáctica entre 'entidades' y 'colecciones' que proporcionan los objetos y las matrices.
fuente
Esa es realmente una buena pregunta y no es fácil de responder. Solo puedo asumir que es común en Wordpress usar
stdClass
objetos porque están usando una clase de base de datos que, por defecto, devuelve registros como unstdClass
objeto. Se acostumbraron (8 años y más) y ya está. No creo que haya mucho más pensamiento detrás del simple hecho.stdClass
los objetos no son realmente mejores que las matrices. Son más o menos lo mismo. Eso es por algunas razones históricas del lenguaje y losstdClass
objetos son realmente limitados y en realidad son solo una especie de objetos de valor en un sentido muy básico.stdClass
los objetos almacenan valores para sus miembros como lo hace una matriz por entrada. Y eso es.stdClass
objetos con miembros privados. No hay mucho beneficio, si es que lo hay, al hacerlo.stdClass
los objetos no tienen ningún método / función. Así que no hay uso de eso en Wordpress.array
, hay funciones mucho menos útiles para tratar con una lista o datos semiestructurados.Sin embargo, si está acostumbrado a las matrices, simplemente transmita:
$array = (array) $object;
Y puede acceder a los datos previamente siendo un objeto, como una matriz. O te gusta al revés:
$object = (object) $array;
Lo que solo eliminará nombres de miembros no válidos, como números. Así que ten un poco de cuidado. Pero creo que entiendes el panorama general: no hay mucha diferencia siempre que se trate de matrices y objetos de
stdClass
.Relacionado:
fuente
Probablemente alguna razón más por la que he pensado
fuente
Los objetos son mucho más poderosos que las matrices. Cada objeto como instancia de una clase puede tener funciones adjuntas. Si tiene datos que necesitan procesamiento, entonces necesita una función que realice el procesamiento. Con una matriz, tendría que llamar a esa función en esa matriz y, por lo tanto, asociar la lógica usted mismo a los datos. Con un objeto, esta asociación ya está hecha y ya no tiene que preocuparse por ella.
También debe considerar el principio OO de ocultar información. No se debe poder acceder directamente a todo lo que regresa o va a la base de datos.
fuente
StdClass
. Esos objetos no tienen nada en común con lo que resaltas. No tienen funciones, por ejemplo, y no tienen herencia. Y en el caso de Wordpress, todas las variables de clase son públicas.stdClass
objetos de forma predeterminada desde ca. 8 años. Si desea obtener una matriz, debe establecer un parámetro opcional para obtenerla.Hay varias razones para devolver objetos:
La escritura
$myObject->property
requiere menos caracteres "generales" que$myArray['element']
El objeto puede devolver datos y funcionalidad; las matrices solo pueden contener datos.
Habilitar encadenamiento:
$myobject->getData()->parseData()->toXML();
Codificación más sencilla: el autocompletado IDE puede proporcionar sugerencias sobre métodos y propiedades para el objeto.
En términos de rendimiento, las matrices suelen ser más rápidas que los objetos. Además del rendimiento, existen varias razones para utilizar matrices:
La funcionalidad proporcionada por la familia de funciones array _ * () puede reducir la cantidad de codificación necesaria en algunos casos.
Las operaciones como count () y foreach () se pueden realizar en matrices. Los objetos no ofrecen esto (a menos que implementen Iterator o Countable ).
fuente
Por lo general, no será por motivos de rendimiento. Normalmente, los objetos cuestan más que las matrices.
Para muchas API, probablemente tenga que ver con los objetos que brindan otra funcionalidad además de ser un mecanismo de almacenamiento. De lo contrario, es una cuestión de preferencia y realmente no hay ningún beneficio en devolver un objeto frente a una matriz.
fuente
Una matriz es solo un índice de valores. Mientras que un objeto contiene métodos que pueden generar el resultado para usted. Claro, a veces puede acceder a los valores de un objeto directamente, pero la "forma correcta de hacerlo" es acceder a los métodos de un objeto (una función que opera sobre los valores de ese objeto).
$obj = new MyObject; $obj->getName(); // this calls a method (function), so it can decide what to return based on conditions or other criteria $array['name']; // this is just the string "name". there is no logic to it.
A veces accedes a las variables de un objeto directamente, esto generalmente está mal visto, pero sucede con bastante frecuencia.
$obj->name; // accessing the string "name" ... not really different from an array in this case.
Sin embargo, considere que la clase MyObject no tiene una variable llamada 'nombre', sino que tiene una variable nombre y apellido.
$obj->getName(); // this would return first_name and last_name joined. $obj->name; // would fail... $obj->first_name; $obj->last_name; // would be accessing the variables of that object directly.
Este es un ejemplo muy simple, pero puede ver a dónde va. Una clase proporciona una colección de variables y las funciones que pueden operar sobre esas variables, todo dentro de una entidad lógica autónoma. Una instancia de esa entidad se llama objeto e introduce resultados lógicos y dinámicos, que una matriz simplemente no tiene.
fuente
La mayoría de las veces, los objetos son tan rápidos, si no más rápidos que las matrices, en PHP no hay una diferencia notable. la razón principal es que los objetos son más poderosos que las matrices. La programación orientada a objetos le permite crear objetos y almacenar no solo datos, sino funcionalidad en ellos, por ejemplo, en PHP, la clase MySQLi le permite tener un objeto de base de datos que puede manipular utilizando una serie de funciones incorporadas, en lugar del enfoque procedimental.
Entonces, la razón principal es que la programación orientada a objetos es un paradigma excelente. Escribí un artículo sobre por qué usar POO es una buena idea y, para explicar el concepto, puedes echarle un vistazo aquí: http://tomsbigbox.com/an-introduction-to-oop/
Como ventaja menor, también escribe menos para obtener datos de un objeto - $ test-> data es mejor que $ test ['data'].
fuente
No estoy familiarizado con la prensa escrita. Muchas respuestas aquí sugieren que una de las ventajas de los objetos es su capacidad para contener código funcional. Cuando se devuelve un objeto de una función / llamada a la API, no debe contener funciones de utilidad. Solo propiedades.
La fortaleza de devolver objetos es que cualquier cosa que se encuentre detrás de la API puede cambiar sin romper su código.
Ejemplo: obtiene una matriz de datos con pares clave / valor, la clave representa la columna DB. Si se cambia el nombre de la columna DB, su código se romperá.
fuente
Estoy ejecutando la siguiente prueba en php 5.3.10 (windows):
for ($i = 0; $i < 1000000; $i++) { $x = array(); $x['a'] = 'a'; $x['b'] = 'b'; }
y
for ($i = 0; $i < 1000000; $i++) { $x = new stdClass; $x->a = 'a'; $x->b = 'b'; }
Copiado de http://atomized.org/2009/02/really-damn-slow-a-look-at-php-objects/comment-page-1/#comment-186961
Llamar a la función para 10 usuarios concurrentes y 10 veces (para obtener un promedio) luego
AKA, Object es todavía doloroso lento. OOP mantiene las cosas ordenadas, sin embargo, debe usarse con cuidado.
¿Qué aplica Wordpress ?. Bueno, ambas soluciones están usando objetos, matrices y objetos y matrices, la clase wpdb usa la última (y es el corazón de Wordpress).
fuente
Sigue el principio de boxeo y unboxing de OOP. Mientras que lenguajes como Java y C # admiten esto de forma nativa, PHP no. Sin embargo, se puede lograr, hasta cierto punto en PHP, pero no de manera elocuente ya que el lenguaje en sí no tiene construcciones que lo respalden. Tener tipos de caja en PHP podría ayudar con el encadenamiento, manteniendo todo orientado a objetos y permite la sugerencia de tipo en las firmas de métodos. La desventaja es la sobrecarga y el hecho de que ahora tiene que realizar comprobaciones adicionales utilizando la construcción "instancia de". Tener un sistema de tipos también es una ventaja cuando se utilizan herramientas de desarrollo que tienen intellisense o asistencia de código como PDT. En lugar de tener que buscar en google / bing / yahoo para el método, existe en el objeto y puede usar la herramienta para proporcionar un menú desplegable.
fuente
Aunque los puntos señalados acerca de que los objetos son más que simples datos son válidos, ya que generalmente son datos y comportamiento, hay al menos un patrón mencionado en "Patrones de arquitectura de aplicaciones empresariales" de Martin Fowler. que se aplica a este tipo de cenario en el que está transfiriendo datos de un sistema (la aplicación detrás de la API) y otro (su aplicación).
Es el objeto de transferencia de datos : un objeto que transporta datos entre procesos para reducir el número de llamadas a métodos.
Entonces, si la pregunta es si las API deben devolver un DTO o una matriz, diría que si el costo de rendimiento es insignificante, entonces debe elegir la opción que sea más fácil de mantener, que yo diría que es la opción DTO ... pero, por supuesto, también Debe considerar las habilidades y la cultura del equipo que está desarrollando su sistema y el idioma o soporte IDE para cada una de las opciones.
fuente