Sei sulla pagina 1di 162

Teora sintcticogramatical de Objetos

Diseo evolucionado de sistemas informticos orientados a objetos desde el lenguaje natural, con ejemplos en Python y PHP

Eugenia Bahit

Copyright 2012 F. Eugenia Bahit La copia y distribucin de este libro completo, est permitida en todo el mundo, sin regalas y por cualquier medio, siempre que esta nota sea preservada. Se concede permiso para copiar y distribuir traducciones de este libro desde el espaol original a otro idioma, siempre que la traduccin sea aprobada por la autora del libro y tanto el aviso de copyright como esta nota de permiso, sean preservados en todas las copias. Creative Commons Atribucin NoComercial CompartirIgual 3.0 Registrado en SafeCreative. N de registro: 1210292587717 Impreso en Espaa por Bubok Publishing S.L. Una copia digital de este libro (copia no impresa) puede obtenerse de forma gratuita en http://orientacionaobjetos.eugeniabahit.com/

A mis alumnos, quienes da a da llenan mis tardes de esperanzas; a Richard Stallman, por haberme enseado el verdadero valor del conocimiento y a todas aquellas personas que disfrutan jugando con el ingenio y compartiendo su sabidura Happy Hacking!

Contenidos
Captulo I: Introduccin informal para perderle el miedo a la orientacin a objetos................................................................9 Cmo pensar en objetos?..................................................9 Entendiendo el paradigma de la programacin orientada a objetos...............................................................................20 Elementos y Caractersticas de la POO .........................21 Captulo II: Teora sintctico-gramatical de objetos y el diseo de objetos en lenguaje natural................................................25 Del lenguaje natural al lenguaje de programacin.............35 Captulo III: Creacin de objetos y acceso a propiedades........39 Captulo IV: Patrn de diseo compuesto (composite pattern)45 Introduccin a la Arquitectura de Software .......................45 Atributos de calidad .....................................................46 Niveles de abstraccin ......................................................48 Estilo Arquitectnico ....................................................49 Patrn Arquitectnico ...................................................50 Patrn de Diseo ..........................................................51 Composite design pattern (patrn de diseo compuesto). .52 Captulo V: Objetos compositores exclusivos, identidad, pertenencia y agregacin........................................................57 Captulo VI: Objetos relacionales simples -o multiplicadores-. 67 Captulo VII: Mapeo relacional de objetos y estructuras de almacenamiento de datos sustentables...................................73 Captulo VIII: Objetos, subtipos y herencia real......................83 Captulo IX: Modelado de objetos y agrupacin......................89 Captulo X: Bases de datos, consultas y abstraccin................91 Creando una capa de abstraccin en Python......................92 Creando una capa de abstraccin en PHP con mysqli ........94 Recetario.......................................................................95 Captulo XI: El mtodo save() en objetos simples, compuestos y relacionales..........................................................................107 Captulo XII: El mtodo destroy().........................................119 Captulo XIII: Mtodos get() estndar, para objetos simples y objetos compuestos..............................................................121 Captulo XIV: Los mtodos get() en objetos compositores de

pertenencia..........................................................................127 Captulo XV: El mtodo get() de los objetos relacionales multiplicadores....................................................................133 Captulo XVI: Factora de objetos con Factory Pattern. Objetos compuestos con mtodos get() mucho ms simples..............137 Captulo XVII: Objetos colectores de instancia nica y Singleton Pattern.................................................................................143 Caractersticas de un Singleton colector en PHP..............145 Caractersticas de un Singleton colector en Python..........147 El mtodo get() del singleton colector.............................151 Captulo XVIII: Objetos relacionales complejos (conectores lgicos relacionales).............................................................153 Los mtodos save(), get() y destroy() del conector lgico157

Eugenia Bahit - Teora sintctico-gramatical de objetos - 9

Captulo I: Introduccin informal para perderle el miedo a la orientacin a objetos


La orientacin a objetos es un paradigma de programacin que puede resultar complejo, si no se lo interpreta de forma correcta desde el inicio. Por eso, en esta primera parte, nos enfocaremos primero, en cuestiones de conceptos bsicos, para luego, ir introducindonos de a poco, en principios tericos elementalmente necesarios para implementar la orientacin a objetos en la prctica.

Cmo pensar en objetos?


Pensar en objetos, puede resultar -al inicio- una tarea difcil. Sin embargo, difcil no significa complejo. Por el contrario, pensar en objetos representa la mayor simplicidad que uno podra esperar del mundo de la programacin. Pensar en objetos, es simple... aunque lo simple, no

10 - Eugenia Bahit - Teora sintctico-gramatical de objetos

necesariamente signifique sencillo. Y qu es un objeto? Pues, como dije antes, es simple. Olvidemos los formalismos, la informtica y todo lo que nos rodea. Simplemente, olvida todo y concntrate en lo que sigue. Lo explicar de manera simple: Un objeto es una cosa. Y, si una cosa es un sustantivo, entonces un objeto es un sustantivo. Mira a tu alrededor y encontrars decenas, cientos de objetos. Tu ordenador, es un objeto. T, eres un objeto. Tu llave es un objeto. El cenicero (ese que tienes frente a ti cargado de colillas de cigarrillo), es otro objeto. Tu mascota tambin es un objeto.
Cuando pensamos en objetos, todos los sustantivos son objetos.

Sencillo cierto? Entonces, de ahora en ms, solo concntrate en pensar la vida en objetos (al menos, hasta terminar de leer este libro). Ahora qu me dices si describimos las cualidades de un objeto? Describir un objeto, es simplemente mencionar sus

Eugenia Bahit - Teora sintctico-gramatical de objetos - 11

cualidades. Las cualidades son adjetivos. Podemos decir que un adjetivo es una cualidad del sustantivo. Entonces, para describir la manera de ser de un objeto, debemos preguntarnos cmo es el objeto? Toda respuesta que comience por el objeto es, seguida de un adjetivo, ser una cualidad del objeto. Algunos ejemplos: El objeto es verde El objeto es grande El objeto es feo

Ahora, imagina que te encuentras frente a un ni o de 2 aos (nio: objeto que pregunta cosas que t das por entendidas de forma implcita). Y cada vez que le dices las cualidades de un objeto al molesto nio-objeto, ste te pregunta: -Qu es...?, seguido del adjetivo con el cul finalizaste tu frase. Entonces, tu le respondes diciendo es un/una seguido de un sustantivo. Te lo muestro con un ejemplo:

12 - Eugenia Bahit - Teora sintctico-gramatical de objetos

El objeto es verde. Qu es verde? Un color. El objeto es grande. Qu es grande? Un tamao. El objeto es feo. Qu es feo? Un aspecto.

Estos sustantivos que responden a la pregunta del nio, pueden pasar a formar parte de una locucin adjetiva que especifique con mayor precisin, las descripciones anteriores: El objeto es de color verde. El objeto es de tamao grande. El objeto es de aspecto feo.

Podemos decir entonces -y todo esto, gracias al nio-objeto-, que una cualidad, es un atributo (derivado de cualidad atribuible a un objeto) y que entonces, un objeto es un sustantivo que posee atributos, cuyas cualidades lo describen. Algunos objetos, tambin se componen de otros objetos... Adems de cualidades (locucin adjetiva seguida de un adjetivo), los objetos tienen otras cosas.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 13

Estas otras cosas, son aquellas pseudocualidades que en vez de responder a cmo es el objeto? responden a cmo est compuesto el objeto? o incluso, an ms simple Qu tiene el objeto?. La respuesta a esta pregunta, estar dada por la frase el objeto tiene..., seguida de un adjetivo cuantitativo o cuantificador (uno, varios, muchos, algunos, unas cuantas) ms un sustantivo.

Algunos ejemplos: El objeto tiene algunas antenas El objeto tiene un ojo El objeto tiene unos cuantos pelos

Los componentes de un objeto, tambin integran los atributos de ese objeto. Solo que estos atributos, son algo particulares: son otros objetos que poseen sus propias cualidades. Es decir, que estos atributos-objeto tambin respondern a la pregunta Cmo es/son ese/esos/esas? seguido del atributo-objeto (sustantivo).

14 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Ampliemos el ejemplo para que se entienda mejor: El objeto tiene algunas antenas. Cmo son esas antenas? Las antenas son de color violeta Las antenas son de longitud extensa El objeto tiene un ojo. Cmo es ese ojo? El ojo es de forma oval El ojo es de color azul El ojo es de tamao grande El objeto tiene unos cuantos pelos. Cmo son esos pelos? Los pelos son de color fucsia Los pelos son de textura rugosa Podemos decir entonces, que un objeto puede tener dos tipos de atributos: 1. Los que responden a la pregunta Cmo es el objeto? con la frase El objeto es... + locucin adjetiva + adjetivo (atributos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 15

definidos por cualidades) 2. Los que responden a la pregunta Qu tiene el objeto? con la frase El objeto tiene... + adjetivo cuantitativo (cantidad) + sustantivo (atributos definidos por las cualidades de otro objeto) Hay objetos que comparten caractersticas con otros objetos Resulta ser, que nuestro Objeto, es prcticamente igual a un nuevo objeto. Es decir, que el nuevo objeto que estamos viendo, tiene absolutamente todas las caractersticas que nuestro primer objeto. Es decir, tiene los mismos atributos. Pero tambin, tiene algunas ms. Por ejemplo, este nuevo objeto, adems de los atributos de nuestro primer objeto, tiene un pie. Es decir, que las caractersticas de nuestro nuevo objeto, sern todas las del objeto original, ms una nueva: pie.

Repasemos las caractersticas de nuestro nuevo objeto: El nuevo objeto es de color verde.

16 - Eugenia Bahit - Teora sintctico-gramatical de objetos

El nuevo objeto es de tamao grande. El nuevo objeto es de aspecto feo. El nuevo objeto tiene algunas antenas. Cmo son esas antenas? Las antenas son de color violeta Las antenas son de longitud extensa

El nuevo objeto tiene un ojo. Cmo es ese ojo? El ojo es de forma oval El ojo es de color azul El ojo es de tamao grande

El nuevo objeto tiene unos cuantos pelos. Cmo son esos pelos? Los pelos son de color fucsia Los pelos son de textura rugosa

(nuevas caractersticas) El nuevo objeto tiene un pie. Cmo es ese

Eugenia Bahit - Teora sintctico-gramatical de objetos - 17

pie? El pie es de forma rectangular El pie es de color amarillo El pie tiene 3 dedos. Cmo son esos dedos? Los dedos son de longitud mediana Los dedos son de forma alargada Los dedos son de color amarillo Podemos observar como nuestro nuevo objeto es una especie de objeto original ampliado. Es decir que el nuevo objeto, es exactamente igual al objeto original (comparte todos sus atributos) pero posee nuevas caractersticas. Est claro adems, que el objeto original y el nuevo objeto, son dos objetos diferentes cierto? No obstante, el nuevo objeto es un sub-tipo del objeto original. Ahora s, a complicarnos an ms. Los objetos, tambin tienen la capacidad de hacer cosas

18 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Ya describimos las cualidades de nuestros objetos. Pero de lo que no hemos hablado, es de aquellas cosas que los objetos pueden hacer, es decir, cules son sus capacidades. Los objetos tiene la capacidad de realizar acciones. Las acciones, son verbos. Es decir, que para conocer las capacidades de un objeto, debes preguntarte Qu puede hacer el objeto? y la respuesta a esta pregunta, estar dada por todas aquellas que comiencen por la frase el objeto puede seguida de un verbo en infinitivo.

Algunos ejemplos: El objeto original puede flotar El nuevo objeto (adems) puede saltar

Objetos y ms objetos: la parte difcil Si entendiste todo lo anterior, ahora viene la parte difcil. Viste que esto de pensando en objetos viene a colacin de la programacin orientada a objetos? Bueno, la parte difcil es que en la programacin, todo lo que acabamos de ver, se denomina de una forma particular. Pero, la

Eugenia Bahit - Teora sintctico-gramatical de objetos - 19

explicacin es la misma que te di antes. Al pan, pan. Y al vino, vino. Las cosas por su nombre Cuando antes hablamos de... Objeto: en la POO1, tambin se denomina objeto. Atributos y cualidades: en la POO se denominan propiedades. Acciones que puede realizar un objeto : en la POO, se denominan mtodos. Atributos-objeto: en la POO se denomina composicin y es una tcnica. Objetos que tienen los mismos nombres de atributos (por ejemplo: color, forma, etc.): en la POO se denomina polimorfismo, y representa la capacidad que tienen los objetos, de poseer los mismos nombres de propiedades y mtodos. El polimorfismo, es una caracterstica esencial de la POO. Sub-tipos de objetos: en la POO se denomina

Programacin orientada a objetos

20 - Eugenia Bahit - Teora sintctico-gramatical de objetos

herencia. Otra caracterstica esencial de este paradigma.

Entendiendo el paradigma de la programacin orientada a objetos


La Programacin Orientada a Objetos (POO u OOP por sus siglas en ingls), es un paradigma de programacin.
Paradigma: teora cuyo ncleo central [...] suministra la base y modelo para resolver problemas [...]. Definicin de la Real Academia Espaola, vigsimo tercera edicin

Cmo tal, nos ensea un mtodo -probado y estudiado- el cual se basa en las interacciones de objetos (todo lo descrito en el ttulo anterior, Pensar en objetos) para resolver las necesidades de un sistema informtico. Bsicamente, este paradigma se compone de 6 elementos y 7 caractersticas que veremos a continuacin.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 21

Elementos y Caractersticas de la POO


Los elementos de la POO, pueden entenderse como los materiales que necesitamos para disear y programar un sistema, mientras que las caractersticas, podran asumirse como las herramientas de las cules disponemos para construir el sistema con esos materiales. Entre los elementos principales de la POO, podremos encontrar los siguientes: Clases Las clases son los modelos sobre los cules se construirn nuestros objetos. Propiedades Las propiedades, como hemos visto antes, son las caractersticas intrnsecas del objeto. stas, se representan a modo de variables, solo que tcnicamente, pasan a denominarse propiedades. Mtodos Los mtodos son funciones (como las que utilizamos en la programacin estructurada), solo que tcnicamente se denominan mtodos, y representan acciones propias que puede realizar el

22 - Eugenia Bahit - Teora sintctico-gramatical de objetos

objeto (y no otro). Cada mtodo debe tener una -y solo una- responsabilidad. Objeto Las clases por s mismas, no son ms que modelos que nos servirn para crear objetos en concreto. Podemos decir que una clase, es el razonamiento abstracto de un objeto, mientras que el objeto, es su materializacin. A la accin de crear objetos, se la denomina instanciar una clase y dicha instancia, consiste en asignar la clase, como valor a una variable, la cual se convertir en una variable de tipo objeto, puesta que la misma, tendr como valor, a las propiedades y mtodos que hayan sido definidos en la clase. Herencia Como comentamos en el ttulo anterior, algunos objetos comparten las mismas propiedades y mtodos que otro objeto, y adems agregan nuevas propiedades y mtodos. A esto se lo denomina herencia: una clase que hereda de otra. Composicin Como comentamos anteriormente, algunos objetos se componen de las propiedades de otro (lo cual,

Eugenia Bahit - Teora sintctico-gramatical de objetos - 23

no significa que las hereden, sino simplemente eso: se componen de). Cuando la propiedad de un objeto, se compone de las caractersticas de otro objeto, dicha propiedad se transforma en una especie de propiedadobjeto. Es decir, que el tipo de datos de esta propiedad, pasa a ser de tipo objeto. Esto significa, que dicha propiedad, estar formada por subpropiedades.

24 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 25

Captulo II: Teora sintctico-gramatical de objetos y el diseo de objetos en lenguaje natural


La teora sintctico-gramatical de objetos, es un nuevo enfoque de la POO, el cual se construye sobre la base del lenguaje natural, para dise ar los objetos de un sistema informtico, sus caractersticas y forma en la que se relacionan. En los ltimos cinco aos, tras arduas horas de estudio y dedicacin, pude comprobar que diseando los objetos a partir del lenguaje natural, se logra definir y relacionar a los mismos, mediante conexiones lgicas irrefutables. Siendo el idioma el lenguaje ms evolucionado con el que la humanidad cuenta para comunicarse, hacer que los componentes de un sistema informtico sean diseados sobre la base de ste,

26 - Eugenia Bahit - Teora sintctico-gramatical de objetos

resulta la forma ms ptima y segura de lograr una comunicacin fehaciente, en el ncleo interno de un Software. La teora sintctico-gramatical de objetos, propone definir los objetos -en una primera instancia-, pura y exclusivamente en lenguaje natural, aplicando para ello, dos estructuras gramaticales nicas, que deben ser respetadas de forma estricta, a fin de asegurar conexiones lgicas irrefutables. A continuacin, veremos en qu consiste y cmo implementar dicha tcnica.

Diseando un sistema informtico en lenguaje natural Disear un sistema informtico orientado a objetos no es lo mismo que utilizar elementos de la orientacin a objetos: puedo pensar un sistema orientado a procedimientos y escribir el cdigo como si estuviese orientado a objetos. Lo anterior, no es programar orientado a objetos, sino, programar utilizando elementos de la POO. El primer paso para disear un sistema orientado a objetos -segn la teora sintctico-gramatical de

Eugenia Bahit - Teora sintctico-gramatical de objetos - 27

objetos-, es describir el objeto en lenguaje natural. Para describir los objetos en lenguaje natural, los pasos a seguir son: 1. Comenzar por el cualidades presente objeto qu mayor

2. Describir SOLO una cualidad por vez, utilizando una de las siguientes estructuras gramaticales: Estructura gramatical adjetiva: La mesa es de material metlico. Estructura gramatical sustantiva: La mesa tiene cuatro patas.

Identificar Objetos: Es el primer sustantivo ms los obtenidos de las estructuras gramaticales sustantivas: ltimo sustantivo de una estructura gramatical sustantiva, en singular. La Mesa es de color blanco. La mesa tiene cuatro patas. (el objeto ser en singular: Pata)

28 - Eugenia Bahit - Teora sintctico-gramatical de objetos

La pata es de color blanco.

Identificar propiedades: PROPIEDAD SIMPLE: En una estructura gramatical adjetiva, es el sustantivo que forma una locucin adjetiva (pertenece al objeto que le antecede). La mesa es de color blanco. (color es propiedad de mesa) La mesa tiene cuatro patas. La pata es de color blanco. (color es propiedad de pata) PROPIEDAD COMPUESTA: El ltimo sustantivo de una estructura gramatical sustantiva (es propiedad del objeto que le antecede). La mesa es de color blanco. La mesa tiene cuatro patas. (es propiedad compuesta de mesa) La pata es de color blanco. Si la definicin de los objetos, se realiza empleando

Eugenia Bahit - Teora sintctico-gramatical de objetos - 29

un sistema visual de niveles (por ejemplo, las vietas con niveles), ser sumamente sencillo, reconocer los objetos, sus propiedades, relacin y dependencias de los mismos. Definamos una habitacin con cuatro paredes cubiertas de lajas, una puerta y una ventana: La habitacin tiene cuatro paredes

(defino todas las caractersticas de las paredes, refirindome solo a una) La pared es de posicin lateral La pared tiene muchas lajas La laja es de textura rugosa La laja es de color beige La laja es de longitud 250 mm La laja es de anchura 150 mm La pared tiene una puerta La puerta es de material madera La puerta es de color cedro

30 - Eugenia Bahit - Teora sintctico-gramatical de objetos

La pared tiene una ventana La ventana tiene un marco El marco es de material aluminio El marco es de color blanco El marco tiene un vidrio El vidrio es de espesor 10 mm El vidrio es de textura lisa El vidrio es de pigmentacin blancuzca La habitacin tiene un cielo raso2 El cielo raso es de material yeso El cielo raso es de color blanco
2

La habitacin tiene un piso

Cuando sola definir las propiedades de una habitacin, me refera al cielo raso como techo. El 15 de septiembre de 2012, mientras daba un taller de orientacin a objetos para NeaExtends (en la provincia de Formosa, Argentina), uno de los asistentes, muy sabiamente me hizo notar que el techo, es la parte del exterior de la habitacin, mientras que lo que se puede visualizar desde el interior, se denomina cielo raso.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 31

El piso es de tipo flotante El piso es de material madera El piso es de color cedro Una vez realizada la descripcin de los objetos en lenguaje natural, se procede a la identificacin de objetos y propiedades: La habitacin tiene cuatro paredes La pared es de posicin lateral La pared tiene muchas lajas La laja es de textura rugosa La laja es de color beige La laja es de longitud 250 mm La laja es de anchura 150 mm La pared tiene una puerta La puerta es de material madera La puerta es de color cedro

32 - Eugenia Bahit - Teora sintctico-gramatical de objetos

La pared tiene una ventana La ventana tiene un marco El marco es de material aluminio El marco es de color blanco El marco tiene un vidrio El vidrio es de espesor 10 mm El vidrio es de textura lisa El vidrio es de pigmentacin blancuzca La habitacin tiene un cielo raso El cielo raso es de material yeso El cielo raso es de color blanco La habitacin tiene un piso El piso es de tipo flotante El piso es de material madera El piso es de color cedro

Eugenia Bahit - Teora sintctico-gramatical de objetos - 33

Notar que hemos resaltado los objetos solo una vez, mientras que las propiedades, han sido todas subrayadas y colocadas en cursiva.

34 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 35

Del lenguaje natural al lenguaje de programacin


Una vez definidos en lenguaje natural todos nuestros objetos, estamos en condiciones de transcribirlos en un lenguaje que pueda ser interpretado por el ordenador. Para ello, basaremos todos los ejemplos en Python3 y PHP4. Definicin de clases Al pasar del lenguaje natural al lenguaje de programacin, siempre comenzaremos por aquellos objetos que menor cantidad de dependencias posean.
Python: class Vidrio(object): pass PHP: class Vidrio { }

Definicin de propiedades La definicin de propiedades se har directamente

3 4

http://www.python.org http://www.php.net

36 - Eugenia Bahit - Teora sintctico-gramatical de objetos

en el mtodo constructor5 de la clase. Dado que Python y PHP son dos lenguajes de tipado dinmico6, en el mtodo constructor se asignar a cada propiedad, un valor equivalente a cero, representativo del tipo de datos. Se considerarn valores equivalentes a cero:
Equivalente a cero Equivalente a cero Equivalente a cero Equivalente a cero Equivalente a cero (en propiedades co de tipo de tipo de tipo de tipo de tipo puestas entero: 0 real: 0.0 string: '' booleano: False coleccin: por !s de un objeto) "#": arra$() "$t%on: &'

Cuando una propiedad se componga de un solo objeto, se asignar como valor de la misma, una instancia de dicho objeto:
En PHP: ne( )bjeto() En Python: )bjeto()

El mtodo constructor es aquel que se ejecuta de forma automtica para inicializar un objeto cuando ste es creado. El nombre del mtodo constructor se encuentra reservado, siendo __init__() para Python y __construct() para PHP . Tipado dinmico: dcese de aquellos lenguajes de programacin generalmente interpretados, en los cuales una misma variable puede tomar valores de distinto tipo a lo largo de la ejecucin del programa. Dichos programas, no requieren que a una variable se le defina de forma anticipada su tipo de datos y por lo tanto, no existen restricciones al respecto.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 37

Un ejemplo concreto:
Python: class *n)bjeto(object): de+ ,,init,,(sel+): sel+.entero - 0 sel+.real - 0.0 sel+.cadena - '' sel+.booleano - False sel+.objetos - &' sel+.objeto - )bjeto() PHP: class *n)bjeto { +unction ,,construct() { .t%is/0entero - 01 .t%is/0real - 0.01 .t%is/0cadena - ''1 .t%is/0booleano - False1 .t%is/0objetos - arra$()1 .t%is/0objeto - ne( )bjeto()1 } }

Asignar a una propiedad la instancia de una clase, se denomina composicin.

En los objetos, nos podremos encontrar tres tipos de propiedades: 1. Propiedades simples (de tipo nico) 2. Propiedades compuestas (compuestas por un solo objeto)

38 - Eugenia Bahit - Teora sintctico-gramatical de objetos

3. Propiedades colectoras (compuestas por una coleccin de objetos)

Eugenia Bahit - Teora sintctico-gramatical de objetos - 39

Captulo III: Creacin de objetos y acceso a propiedades


Anteriormente, comentamos que la creacin de un objeto consiste en asignar a una variable, la instancia de una clase. Es decir, que con la definicin de los objetos, solo contamos con un molde para cocinar nuestros objetos, pero an, no contamos con el objeto propiamente dicho. Crear un objeto es sumamente simple:
Python: objeto - )bjeto() PHP: .objeto - ne( )bjeto()1

Una vez creado nuestro objeto, podremos ver su estructura interna:


Python7: +ro printr i port printr printr(objeto)

Para ver la estructura interna de un objeto en Python, se recomienda descargar el mdulo python-printr de www.python-printr.org e instalarlo en /usr/lib/Python2.x/

40 - Eugenia Bahit - Teora sintctico-gramatical de objetos

PHP: print,r(.objeto)1

Veamos un ejemplo completo con vidrio, marco y ventana, para as, poder modificar el valor de sus propiedades:
Python: class Vidrio(object): de+ ,,init,,(sel+): sel+.espesor - 0 sel+.te2tura - '' sel+.pig entacion - '' class 3arco(object): de+ ,,init,,(sel+): sel+. aterial - '' sel+.color - '' sel+.vidrio - Vidrio() class Ventana(object): de+ ,,init,,(sel+): sel+. arco - 3arco() ventana = Ventana() +ro printr i port printr printr(ventana)

Eugenia Bahit - Teora sintctico-gramatical de objetos - 41

El cdigo anterior, arrojar la siguiente salida::


4Ventana object0 { arco: 43arco object0 { color: '' vidrio: 4Vidrio object0 { espesor: 0 te2tura: '' pig entacion: '' } aterial: '' } }

Mientras que el mismo ejemplo en PHP:


PHP: class Vidrio{ +unction ,,construct() { .t%is/0espesor - 01 .t%is/0te2tura - ''1 .t%is/0pig entacion - ''1 } } class 3arco { +unction ,,construct() { .t%is/0 aterial - ''1 .t%is/0color - ''1 .t%is/0vidrio - ne( Vidrio()1 } }

42 - Eugenia Bahit - Teora sintctico-gramatical de objetos

class Ventana { +unction ,,construct() { .t%is/0 arco - ne( 3arco()1 } } $ventana = new Ventana(); print_r($ventana);

Lo arrojar de la siguiente forma:


Ventana )bject ( & arco' -0 3arco )bject ( & aterial' -0 &color' -0 &vidrio' -0 Vidrio )bject ( &espesor' -0 0 &te2tura' -0 &pig entacion' -0 ) ) )

El objeto fue creado (inicializado). Sin embargo, ningn valor ha sido asociado a sus propiedades. Si las propiedades fuesen simples y quisiramos modificarlas, lo haramos de la siguiente forma:

Eugenia Bahit - Teora sintctico-gramatical de objetos - 43


Python: objeto.propiedad - 'nuevo valor' PHP: .objeto/0propiedad - 'nuevo valor'1

Pero cuando las propiedades son compuestas, debe seguirse toda la ruta de propiedades, hasta llegar a la deseada:
Python: ventana. arco.vidrio.espesor - 50 PHP: .ventana/0 arco/0vidrio/0espesor - 501

En objetos donde la dependencia es de varios niveles, modificar las propiedades de esta forma, no solo se hace difcil, sino que adems, es bastante confuso. Claro que tambin podramos crear un nuevo objeto, modificarle sus propiedades simples y reasignarlo al objeto compuesto:
Python: vidrio - Vidrio() vidrio.espesor - 50 arco - 3arco() arco.vidrio - vidrio ventana - Ventana() ventana. arco - arco

44 - Eugenia Bahit - Teora sintctico-gramatical de objetos


PHP: .vidrio - ne( Vidrio()1 .vidrio/0espesor - 501 . arco - ne( 3arco()1 . arco/0vidrio - .vidrio1 .ventana - ne( Ventana()1 .ventana/0 arco - . arco1

Pero hacindolo de esa forma, tambin podramos confundirnos y modificar -sin quererlo- la estructura interna del objeto:
Python: vidrio - Vidrio() vidrio.espesor - 50 ventana - Ventana() ventana. arco - vidrio PHP: .vidrio - ne( Vidrio()1 .vidrio/0espesor - 501 .ventana - ne( Ventana()1 .ventana/0 arco - .vidrio1

Es entonces, cuando se hace necesario en grandes relaciones de objetos, contar con una solucin a este problema. Y la misma, es provista por el patrn de diseo compuesto que veremos en el siguiente captulo.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 45

Captulo IV: Patrn de diseo compuesto (composite pattern)


Antes de hablar de patrones de diseo, es necesario familiarizarse con el estudio de la Arquitectura de Software. A continuacin, se realizar una breve introduccin, a fin de alcanzar el conocimiento mnimo necesario para poder afrontar finalmente, el estudio de este patrn de diseo compuesto.

Introduccin a la Arquitectura de Software


Qu es la arquitectura de software? Es necesario aclarar, que no existe una definicin nica, exacta, abarcadora e inequvoca de arquitectura de software. La bibliografa sobre el tema es tan extensa como la cantidad de definiciones que en ella se puede encontrar. Por lo tanto tratar, no de definir la arquitectura de software, sino ms bien, de introducir a un

46 - Eugenia Bahit - Teora sintctico-gramatical de objetos

concepto simple y sencillo que permita comprender el punto de vista desde el cual, este libro abarca a la arquitectura de software pero, sin nimo de que ello represente una definicin ms. A grandes rasgos, puede decirse que la Arquitectura de Software es la forma en la que se organizan los componentes de un sistema, interactan y se relacionan entre s y con el contexto, aplicando normas y principios de diseo y calidad, que fortalezcan y fomenten la usabilidad a la vez que dejan preparado el sistema, para su propia evolucin.

Atributos de calidad
La Calidad del Software puede definirse como los atributos implcitamente requeridos en un sistema que deben ser satisfechos. Cuando estos atributos son satisfechos, puede decirse (aunque en forma objetable), que la calidad del software es satisfactoria. Estos atributos, se gestan desde la arquitectura de software que se emplea, ya sea cumpliendo con aquellos requeridos durante la ejecucin del software, como con aquellos que forman parte del proceso de desarrollo de ste.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 47

Atributos de calidad que pueden observarse durante la ejecucin del software 1. Disponibilidad de uso 2. Confidencialidad, puesto que se debe evitar el acceso no autorizado al sistema 3. Cumplimiento de la Funcionalidad requerida 4. Desempeo del sistema con respecto a factores tales como la capacidad de respuesta 5. Confiabilidad dada por la constancia operativa y permanente del sistema 6. Seguridad externa evitando la prdida de informacin debido a errores del sistema 7. Seguridad interna siendo capaz de impedir ataques, usos no autorizados, etc. Atributos de calidad inherentes al proceso de desarrollo del software 1. Capacidad de Configuracin que el sistema otorga al usuario a fin de realizar ciertos cambios 2. Integrabilidad de los mdulos independientes del sistema 3. Integridad de la informacin asociada

48 - Eugenia Bahit - Teora sintctico-gramatical de objetos

4. Capacidad de Interoperar con otros sistemas (interoperabilidad) 5. Capacidad de permitir ser modificable a futuro (modificabilidad) 6. Ser fcilmente Mantenible (mantenibilidad) 7. Capacidad de Portabilidad, es decir que pueda ser ejecutado en diversos ambientes tanto de software como de hardware 8. Tener una estructura que facilite la Reusabilidad de la misma en futuros sistemas 9. Mantener un diseo arquitectnico Escalable que permita su ampliacin (escalabilidad) 10. Facilidad de ser Sometido a Pruebas que aseguren que el sistema falla cuando es lo que se espera (testeabilidad)

Niveles de abstraccin
Podemos decir que la AS8 se divide en tres niveles de abstraccin bien diferenciados: Estilo Arquitectnico, Patrn Arquitectnico y Patrn de Diseo. Existe una diferencia radical entre estos tres elementos, que debe marcarse a fin de evitar las grandes confusiones que inevitablemente,
8 Arquitectura de Software

Eugenia Bahit - Teora sintctico-gramatical de objetos - 49

concluyen en el mal entendimiento y en los resultados poco satisfactorios. stos, son los que en definitiva, aportarn calidad al sistema resultante. En lo sucesivo, trataremos de establecer la diferencia entre estos tres conceptos, viendo como los mismos, se relacionan entre s, formando parte de un todo: la arquitectura de software. Estilo Arquitectnico, Patrn Arquitectnico y Patrn de Diseo, representan -de lo general a lo particular- los tres niveles de abstraccin en los que se divide la Arquitectura de Software.

Estilo Arquitectnico
El estilo arquitectnico define un nivel general de la estructura del sistema y cmo ste, va a comportarse. Mary Shaw y David Garlan, en su libro Software Architecture (Prentice Hall, 1996), definen los estilos arquitectnicos como la forma de determinar el los componentes y conectores de un sistema, que pueden ser utilizados a instancias del estilo elegido, conjuntamente con un grupo de restricciones sobre como stos pueden ser combinados:
[...] an architectural style determines the vocabulary of components and connectors that

50 - Eugenia Bahit - Teora sintctico-gramatical de objetos

can be used in instances of that style, together with a set of constraints on how they can be combined [...]

Mary Shaw y David Garlan -en el mismo libro-, hacen una distincin de estilos arquitectnicos comunes, citando como tales a: 1. Pipes and filters (filtros y tuberas) 2. Data Abstraction and Object-Oriented Organization (Abstraccin de datos y organizacin orientada a objetos) 3. Event-based (estilo basado en eventos) 4. Layered Systems (Sistemas en capas) 5. Repositories (Repositorios) 6. Table Driven Interpreters Viendo la clasificacin anterior, es muy frecuente que se encuentren relaciones entre los estilos arquitectnicos y los paradigmas de programacin. Sin embargo, debe evitarse relacionarlos en forma directa.

Patrn Arquitectnico
Un patrn arquitectnico, definir entonces, una

Eugenia Bahit - Teora sintctico-gramatical de objetos - 51

plantilla para construir el Software, siendo una particularidad del estilo arquitectnico elegido. En esta definicin, es donde se incluye a MVC, patrn que a la vez, puede ser enmarcado dentro del estilo arquitectnico orientado a objetos (estilo arquitectnico basado en el paradigma de programacin orientada a objetos).

Patrn de Diseo
Dentro de niveles de abstraccin de la arquitectura de Software, los patrones de diseo representan el nivel de abstraccin ms detallado. A nivel general, nos encontramos con el Estilo Arquitectnico. En lo particular, hallamos al Patrn Arquitectnico y, finalmente, el Patrn de Diseo es el detalle. Matt Zandstra en su libro PHP Objects, Patterns and Practice (Apress, 2010) define los patrones de diseo como:
[] is a problem analyzed with good practice for its solution explained [...]

(Traduccin: un problema analizado con buenas prcticas para su solucin explicada) Un patrn de diseo, entonces, es un anlisis

52 - Eugenia Bahit - Teora sintctico-gramatical de objetos

mucho ms detallado, preciso y minucioso de una parte ms pequea del sistema, que puede incluso, trabajar en interaccin con otros patrones de diseo. Por ejemplo, un Singleton puede coexistir con un Factory y stos, a la vez, con Composite. En este sentido, un Patrn Arquitectnico como MVC, podra utilizar diversos patrones de diseo en perfecta coexistencia, para la creacin de sus componentes.

Composite design pattern (patrn de diseo compuesto)


Habiendo comprendido de qu hablamos al referirnos a un patrn de diseo, vamos a intentar implementar la solucin a nuestro anterior problema, mediante el patrn de diseo compuesto. El patrn de diseo compuesto, nos permite componer una propiedad asignndole como valor, al objeto compositor9 de forma directa (objeto que
9 En una gran parte de la bibliografa sobre programacin orientada a objetos y patrones de diseo, encontrars que al objeto compositor se lo define como componente. Definir a un objeto cuya responsabilidad es componer a otro, como componente, es un grave error, puesto que los componentes de un sistema informtico, son aquellos elementos que lo

Eugenia Bahit - Teora sintctico-gramatical de objetos - 53

compone a dicha propiedad), previniendo que por error, le sea asignado un objeto o valor, diferente al tipo del objeto esperado. Para lograrlo, dicho patrn esperar que el objeto compositor, le sea pasado como parmetro. Composite en PHP En PHP 5.x, es posible indicar a un mtodo, el tipo de objeto esperado, anteponiendo el nombre del mismo:
class 3arco { +unction ,,construct(Vidrio $vidrio=NULL) { .t%is/0 aterial - ''1 .t%is/0color - ''1 .t%is/0vidrio - .vidrio1 } }

De esta forma, si intentramos construir el objeto Marco(), pasando como parmetro un objeto que
integran y dicho sistema, no necesariamente estar orientado a objetos. Para la teora sintctico-gramatical de objetos, el idioma espaol cumple un papel fundamental. La Real Academia Espaola, define el trmino compositor como un adjetivo cuyo significado es que compone. Y en este sentido ser utilizado en este libro, a fin de no confundirlo con los componentes de un sistema informtico.

54 - Eugenia Bahit - Teora sintctico-gramatical de objetos

no sea de tipo Vidrio(), un error ser lanzado:


. arco - ne( 3arco('no so$ un vidrio')1 "#" 6atc%able +atal error: Arg !ent " passed to 3arco::,,construct() ! #t $e an in#tan%e o& Vidrio7 #tring given

Sin embargo, si un objeto Vidrio() o NULL le es pasado como parmetro, el patrn habr servido a su fin:
$vidrio = new Vidrio(); .vidrio/0espesor - 501 .vidrio/0te2tura - 'lisa'1 .vidrio/0pig entacion - 'blancu8ca'1 $!ar%o = new 'ar%o($vidrio); print,r(. arco)1 3arco )bject ( & aterial' -0 &color' -0 &vidrio' -0 Vidrio )bject ( &espesor' -0 50 &te2tura' -0 lisa &pig entacion' -0 blancu8ca ) )

Composite en Python A diferencia de PHP , en Python no podemos indicar a un mtodo, el tipo de objeto que estamos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 55

esperando. Para componer mediante !composite" en Python, la funcin isinstance(objeto, clase)10 ser necesaria:
class 3arco(object): de+ ,,init,,(sel+7 vidrio-9one): sel+. aterial - '' sel+.color - ''
i& i#in#tan%e(vidrio( Vidrio) or vidrio i# None:

sel+.vidrio - vidrio else: rai#e )ypeError(':s no es de tipo Vidrio' : t$pe(vidrio))

Si un objeto de tipo diferente a Vidrio le es pasado como parmetro, un error ser lanzado:
arco - 3arco('no so$ un vidrio') )ypeError: *type +#tr+, no e# de tipo Vidrio

De lo contrario, se ejecutar satisfactoriamente:


vidrio - Vidrio() vidrio.espesor - 50 vidrio.te2tura - 'lisa' vidrio.pig entacion - 'blancu8ca' arco - 3arco(vidrio)

En el caso de Python, el patrn compuesto nos


10 http://docs.python.org/library/functions.html#isinstance

56 - Eugenia Bahit - Teora sintctico-gramatical de objetos

salva al tiempo que, implementado de la forma anterior, nos ensucia el cdigo adems de obligarnos a caer en redundancia. Para solucionar este problema, podemos generar nuestra propia funcin compose() y as, mantener limpios nuestros constructores y evitar la redundancia en un solo paso:
de& %o!po#e(o$-( %.#): i+ isinstance(obj7 cls) or obj is 9one: return obj else: raise ;$peError(':s no es de tipo :s' : (t$pe(obj)7 cls)) class 3arco(object): de+ ,,init,,(sel+7 vidrio-9one): sel+. aterial - '' sel+.color - '' #e.&/vidrio = %o!po#e(vidrio( Vidrio)

Eugenia Bahit - Teora sintctico-gramatical de objetos - 57

Captulo V: Objetos compositores exclusivos, identidad, pertenencia y agregacin


Identidad Todos los objetos poseen una identidad que los hace nicos. Cuando se crea un objeto, ste, adopta una identidad que ser diferente a la de otro objeto, incluso cuando sus cualidades sean exactamente las mismas. Es decir, yo puedo crear dos objetos cuyas cualidades sean exactamente idnticas y, sin embargo, sern dos objetos distintos. De la misma forma que dos personas gemelas, no solo son exactamente iguales a la vista, sino que adems, comparten hasta el mismo ADN, dos objetos (o ms) que cuenten con el mismo ADN, a pesar de su igualdad, deben poder ser diferenciados ms all de la vista y contar con una identidad. Dos hermanos gemelos se diferenciarn entre s por

58 - Eugenia Bahit - Teora sintctico-gramatical de objetos

su nmero de documento (DNI, Pasaporte, etc.), mientras que el DNI de nuestros objetos, ser su ID. Por lo tanto, a toda definicin de clase, siempre se le agregar en el mtodo constructor -y como primera propiedad- la propiedad objeto_id, donde objeto ser el nombre de la clase:
Python: class Vidrio(object): de+ ,,init,,(sel+): #e.&/vidrio_id = 0 sel+.espesor - 0 sel+.te2tura - '' sel+.pig entacion - '' PHP: class Vidrio{ +unction ,,construct() { $thi#1,vidrio_id = 0; .t%is/0espesor - 01 .t%is/0te2tura - ''1 .t%is/0pig entacion - ''1 } }

Objetos compositores Todo objeto que sirve para componer a otro, se denomina objeto compositor.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 59

Entre los objetos compositores, podemos encontrar dos tipos claramente diferenciados: los compositores reutilizables y los compositores exclusivos -o de pertenencia-, en los que nos centraremos en este captulo. Objetos compositores exclusivos Se dice que un compositor es exclusivo cuando ste puede componer nicamente a un -y solo unobjeto. Cuando la propiedad de un objeto se compone de N objetos del mismo tipo pero diferente identidad (es decir, se compone de objetos similares pero no idnticos), dichos compositores sern compositores exclusivos. Para que un compositor sea considerado de pertenencia, deben necesitarse al menos dos compositores para componer la misma propiedad. Por ejemplo, puedo decir que un vidrio compone a un marco. Pero solo es 1 vidrio. Por lo tanto, no es compositor de pertenencia. Tambin puedo decir que 75 lajas componen a la misma pared. Sin embargo, puedo crear una nica laja y replicar la misma laja N veces para componer a esa pared y a otras. Es decir, puedo reutilizar una misma laja

60 - Eugenia Bahit - Teora sintctico-gramatical de objetos

para componer ms de una pared. Entonces, hablo de un compositor reutilizable. Pero cuando digo que 4 paredes componen a la misma habitacin, cada una de ellas se diferencia por sus cualidades y no puedo reutilizar la misma pared para componer ms de una habitacin. De hecho podras trasladar la pared del living al dormitorio? Es aqu cuando hablamos de objetos compositores de pertenencia: !El Objeto A pertenece al Objeto B".

El caso de Pared !abitaci"n# es exactamente el mismo $ue se da %por e&emplo% en un sistema de administraci"n de empleados# donde' !#l empleado tiene varios datos de contacto" !#l dato de contacto es de tipo tel$fono m%vil" (inalmente# podemos decir $ue' !#l dato de contacto pertenece al empleado".

Pertenencia )uando un tipo de ob&eto es considerado un compositor exclusivo# dicha caracter*stica se de(ine con una nueva

Eugenia Bahit - Teora sintctico-gramatical de objetos - 61

estructura gramatical' El +ob&eto ,- pertenece +a.al.a la- +ob&eto B!&a pared pertenece a la habitaci%n" /icha estructura gramatical# deriva en una nueva propiedad del ob&eto compositor' la propiedad ob&eto0compuesto# cu o valor# ser1 la identidad del ob&eto al cu1l compone'
Python: class "ared(object): de+ ,,init,,(sel+7 puerta-9one7 ventana-9one): sel+.pared,id - 0 sel+.lajas - &' sel+.puerta - co pose(puerta 7 "uerta) sel+.ventana - co pose(ventana 7 Ventana) #e.&/ha$ita%ion = 0 PHP: class "ared { +unction ,,construct("uerta .puerta-9*<<7 Ventana .ventana-9*<<) { .t%is/0pared,id - 01 .t%is/0lajas - arra$()1 .t%is/0puerta - .puerta1 .t%is/0ventana - .ventana1 $thi#1,ha$ita%ion = 0; } }

62 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Agregacin Cuando una propiedad se compone por varios objetos del mismo tipo, la misma se define como una coleccin. Ya sea un array en PHP como una lista en Python. Al crear el objeto, se le deben ir agregando tantos compositores como sean necesarios para componer dicha propiedad:
Python: pared,i8quierda - "ared() pared,derec%a - "ared() pared,+rontal - "ared() pared,dorsal - "ared() %abitacion - #abitacion(piso7 cielo,raso) %abitacion.paredes.append(pared,i8quierda) %abitacion.paredes.append(pared,derec%a) %abitacion.paredes.append(pared,+rontal) %abitacion.paredes.append(pared,dorsal) PHP: .pared,i8quierda - ne( "ared()1 .pared,derec%a - ne( "ared()1 .pared,+rontal - ne( "ared()1 .pared,dorsal - ne( "ared()1 .%abitacion - ne( #abitacion(.piso7 .cielo,raso)1 .%abitacion/0paredes&' - .pared,i8quierda1 .%abitacion/0paredes&' - .pared,derec%a1 .%abitacion/0paredes&' - .pared,+rontal1 .%abitacion/0paredes&' - .pared,dorsal1

Eugenia Bahit - Teora sintctico-gramatical de objetos - 63

Al igual que nos pasaba al inicializar un objeto, podramos agregar un objeto del tipo incorrecto:
Python: %abitacion - #abitacion(piso7 cielo,raso) %abitacion.paredes.append('no so$ una pared') PHP: .%abitacion - ne( #abitacion(.piso7 .cielo,raso)1 .%abitacion/0paredes&' - 'no so$ una pared'1

Y nuestro sistema, seguira adelante como si nada malo hubiese sucedido, poniendo en riesgo toda la integridad de la aplicacin. Para resolver este problema, sabemos que existe el patrn compuesto pero cmo implementarlo? Para ello, se utilizan los llamados mtodos de agregacin. Los mtodos de agregacin, no son ms que funciones que utilizando el patrn compuesto, se encargan de agregar los compositores que sean necesarios para componer la propiedad colectora. Dichos mtodos, se encuentran presentes en todo objeto que posea propiedades colectoras. Vale aclarar que los mtodos de agregacin, no deben definir un valor nulo por defecto como sucede en los mtodos constructores cuando se utiliza el patrn compuesto.

64 - Eugenia Bahit - Teora sintctico-gramatical de objetos


Python: class #abitacion(object): de+ ,,init,,(sel+7 piso7 cr) : sel+.%abitacion,id - 0 sel+.paredes - &' sel+.piso - co pose(piso7 "iso) sel+.cielo,raso - co pose(cr7 6ielo=aso) de& add_pared(#e.&( pared) : sel+.paredes.append(co pose(pared7 "ared)) PHP: class #abitacion { +unction ,,construct("iso .piso-9*<<7 6ielo=aso .cr-9*<<) { .t%is/0%abitacion,id - 01 .t%is/0paredes - arra$()1 .t%is/0piso - .piso1 .t%is/0cielo,raso - .cr1 } & n%tion add_pared(Pared $pared) 2 .t%is/0paredes&' - .pared1 } }

Con los mtodos de agregacin, el agregado de compositores resultar mucho ms seguro y sustentable:
Python: pared,i8quierda - "ared() pared,derec%a - "ared() pared,+rontal - "ared() pared,dorsal - "ared()

Eugenia Bahit - Teora sintctico-gramatical de objetos - 65


%abitacion - #abitacion(piso7 cielo,raso) %abitacion.add,pared(pared,i8quierda) %abitacion.add,pared(pared,derec%a) ha$ita%ion/add_pared(+no #oy pared+) 3 4a..ar5 %abitacion.add,pared(pared,dorsal) PHP: .pared,i8quierda - ne( "ared()1 .pared,derec%a - ne( "ared()1 .pared,+rontal - ne( "ared()1 .pared,dorsal - ne( "ared()1 .%abitacion - ne( #abitacion(.piso7 .cielo,raso)1 .%abitacion/0add,pared(.pared,i8quierda)1 .%abitacion/0add,pared(.pared,derec%a)1 $ha$ita%ion1,add_pared(+no #oy pared+); 3 4a..ar5 .%abitacion/0add,pared(.pared,dorsal)1

66 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 67

Captulo VI: Objetos relacionales simples -o multiplicadoresImagina que tienes que agregar 75 lajas a una pared. Y que en realidad, solo tienes una laja y nada ms, deseas replicarla 75 veces para componer la misma pared.
Una pared, se compone de 75 lajas idnticas (las lajas son exactamente iguales entre s). Es decir, que con tan solo crear 1 objeto laja podremos replicarlo N veces -sin necesidad de modificarlo-, para componer esa u otras paredes. Hablamos de 75 lajas con la misma identidad. Podemos decir entonces, que el objeto laja, es un objeto compositor reutilizable.

Claro est que podras colocar un bucle en el mtodo de agregacin add_laja() del objeto Pared. Pero al no ser laja un compositor exclusivo cmo sabrs la identidad de la laja que compone a una determinada pared? Y sin conocer la identidad de

68 - Eugenia Bahit - Teora sintctico-gramatical de objetos

la laja que se necesita para componer una pared cmo haras para recuperarla tras haberla creado? Para resolver este problema, es entonces, que surge la necesidad de contar con un objeto relacional multiplicador: para poder establecer la relacin existente entre 1 objeto compuesto y N objetos compositores reutilizables (objetos idnticos -misma identidad-).

Haciendo un paralelismo con el ejemplo de empleados y datos de contactos que vimos en el captulo anterior, podemos decir que el caso de Laja y Pared ser el mismo que acontezca -por ejemploen un sistema de gestin contable donde La nota de pedido tiene varios productos. Un producto podra ser Paquete de Algodn SuavecitoSuavecito x 200 gr y la misma nota de pedido, tener 40 paquetes del mismo producto. Objeto relacional simple (o multiplicador) Un objeto relacional es aquel cuya nica finalidad es la de establecer la relacin existente entre dos objetos, multiplicando N veces al compositor. Un objeto relacional simple, se conforma de cuatro

Eugenia Bahit - Teora sintctico-gramatical de objetos - 69

propiedades: INT objeto_id (presente en todos los objetos) ObjetoCompositor objeto_compositor ObjetoCompuesto objeto_compuesto INT relacion

Para establecer la relacin compositor/compuesto, incorporar un mtodo relacional set_relacion() que de forma iterativa, agregar los compositores necesarios, recurriendo al mtodo de agregacin del objeto compuesto:
Python: class <aja"ared(object): de+ ,,init,,(sel+7 co puesto7 co positor-9one): sel+.lajapared,id - 0 sel+.pared - co pose(co puesto7 "ared) sel+.laja - co pose(co positor7 <aja) sel+.relacion - 5 de+ set,relacion(sel+): t pvar - 0 (%ile t pvar 4 sel+.relacion: sel+.pared.add,laja(sel+.laja) t pvar >- 5 PHP: class <aja"ared { +unction ,,construct("ared .co puesto7

70 - Eugenia Bahit - Teora sintctico-gramatical de objetos


<aja .co positor-9*<<) { .t%is/0lajapared,id - 01 .t%is/0pared - .co puesto1 .t%is/0laja - .co positor1 .t%is/0relacion - 51 } +unction set,relacion() { .t pvar - 01 (%ile(.t pvar 4 .t%is/0relacion) { .t%is/0pared/0add,laja(.t%is/0laja)1 .t pvar>>1 } } }

Para establecer la relacin entre N lajas y pared, solo bastar con: 1. Crear el objeto compositor 2. Crear el objeto compuesto 3. Crear el objeto relacional 4. Invocar al mtodo set_relacion() para establecer la relacin entre compositor * N y compuesto.
Python: laja - <aja() laja.color - 'beige' pared - "ared(puerta7 ventana) pared.posicion - '+rontal'

Eugenia Bahit - Teora sintctico-gramatical de objetos - 71


relacional - <aja"ared(pared7 laja) relacional.relacion - ?@ relacional.set,relacion() PHP: .laja - ne( <aja()1 .laja/0color - 'beige'1 .pared - ne( "ared(.puerta7 .ventana)1 .pared/0posicion - '+rontal'1 .relacional - ne( <aja"ared(.pared7 .laja)1 .relacional.relacion - ?@ .relacional.set,relacion()

72 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 73

Captulo VII: Mapeo relacional de objetos y estructuras de almacenamiento de datos sustentables


Solo una vez que los objetos hayan sido definidos, sern mapeados relacionalmente -de forma manual-, para as obtener el diseo de la base de datos con una estructura de almacenamiento sustentable.

En la orientacin a objetos, la base de datos debe cumplir una funcin meramente complementaria, cuyo objetivo, solo ser servir de soporte para almacenar datos de forma sustentable que nos permitan recuperar -con cualquier propsitoobjetos creados. El objetivo de mapear objetos relacionalmente es "recorrer los objetos analizando su relacin, a fin de poder disear una estructura de almacenamiento

74 - Eugenia Bahit - Teora sintctico-gramatical de objetos

de datos (base de datos) sustentable al servicio de dichos objetos". Para qu mapear los objetos? Cuando uno crea objetos, los mismos son "voltiles". Es decir, se crea un objeto, se ejecuta el archivo y tras la finalizacin del script, el objeto se destruye y es eliminado de la memoria. Entonces: cmo recuperar luego ese objeto? Almacenar sus datos en una base de datos es la solucin ms prctica y viable. Por ese motivo, es que la necesitamos. El mapeo relacional debe comenzarse por los objetos que menor cantidad de dependencias posean. Comenzando entonces, por aquellos objetos sin dependencias, seguiremos en el orden de menor a mayor cantidad de dependencias. Para escribir las consultas SQL destinadas a crear las tablas de la base de datos, se debern tener en cuenta las siguientes pautas:

Todos los objetos deben tener una tabla homnima

Eugenia Bahit - Teora sintctico-gramatical de objetos - 75

Ms adelante, veremos que los nicos objetos que no tendrn una tabla homnima, sern los Singleton colectores y los subtipos simples. El nombre de la tabla, ser el nombre de la clase, en minsculas.
6lass 3i6lase

Producir:
6=EA;E ;AB<E iclase

Todas las tablas deben crearse con el motor InnoDB Esto es, debido a que nuestra base de datos, deber contemplar las relaciones derivadas del diseo de los objetos. Por tanto, la base de datos, ser una base de datos relacional. MySQL utiliza por defecto el motor MyISAM, quien no posee soporte para bases de datos relaciones. En cambio, el motor InnoDB, nos provee de un excelente soporte para la manipulacin de claves forneas (foreign keys o FK).
6=EA;E ;AB<E iclase ( ) E9CD9E-DnnoEB1

76 - Eugenia Bahit - Teora sintctico-gramatical de objetos

La propiedad objeto_id ser clave primaria de la tabla Una clave primaria, ser de tipo entero, autoincremental y no podr permitir valores nulos.
6=EA;E ;AB<E iclase ( iclase,id D9;(55) 9); 9*<< A*;),D96=E3E9; "=D3A=F GEF ) E9CD9E-DnnoEB1

Todas las propiedades simples, siempre sern campos de la tabla Es decir, cualquier propiedad cuyo valor no sea una coleccin, ni otro objeto, ser campo de la tabla, respetando el tipo de datos definido en el constructor. Los campos de la tabla debern tener s o s, el mismo nombre que las propiedades 11, sin ningn tipo de agregado o cambio.
11 Siempre digo que enseando tambin se aprende y que en vez de competir hay que saber aprender de otros. Si miras los estilos de escritura del cdigo SQL, notars que las comas (,) las coloco a la izquierda de los campos y no al final. Esto lo aprend de Magoo, un alumno del curso de Orientacin a Objetos en Python. Su tcnica me result sorprenderte ya que al colocar las comas a la izquierda del campo, es pr cticamente imposible olvidarse una.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 77


6=EA;E ;AB<E iclase ( iclase,id D9;(55) 9); 9*<< A*;),D96=E3E9; "=D3A=F GEF 7 propiedad,entero D9;(H) 7 propiedad,real EE6D3A<(I7 J) 7 propiedad,string VA=6#A=(H0) 7 propiedad,bool B))< ) E9CD9E-DnnoEB1

A fin de lograr una estructura de datos optimizada, se deber tener especial cuidado en la cantidad de dgitos o caracteres a indicar en los campos de tipo INT, DECIMAL, CHAR y VARCHAR.

Las propiedades de pertenencia, sern claves forneas con efecto en cascada Las propiedades de pertenencia, sern siempre de tipo INT(11). No podrn ser nulas y cuando la clave primaria a la que hagan referencia sea eliminada, producirn un efecto en cascada.
6=EA;E ;AB<E iclase ( iclase,id D9;(55) 9); 9*<< A*;),D96=E3E9; "=D3A=F GEF 7 propiedad,entero D9;(H) 7 propiedad,real EE6D3A<(I7 J) 7 propiedad,string VA=6#A=(H0) 7 propiedad,bool B))<

78 - Eugenia Bahit - Teora sintctico-gramatical de objetos


7 propiedad,de,pertenencia D9;(55) 9); 9*<< 7 F)=EDC9 GEF (propiedad,de,pertenencia) =EFE=E96EK tabla (ca po,id) )9 EE<E;E 6AK6AEE ) E9CD9E-DnnoEB1

Las propiedades compuestas por un solo objeto sern campos de la tabla Debern ser de tipo entero admitiendo valores nulos. Sern establecidas como claves forneas produciendo un valor nulo cuando la clave primaria sea eliminada, excepto cuando se trate de objetos relacionales, donde el efecto ser en cascada.
6=EA;E ;AB<E iclase ( iclase,id D9;(55) 9); 9*<< A*;),D96=E3E9; "=D3A=F GEF 7 propiedad,entero D9;(H) 7 propiedad,real EE6D3A<(I7 J) 7 propiedad,string VA=6#A=(H0) 7 propiedad,bool B))< 7 propiedad,de,pertenencia D9;(55) 9); 9*<< 7 F)=EDC9 GEF (propiedad,de,pertenencia) =EFE=E96EK tabla (ca po,id) )9 EE<E;E 6AK6AEE 7 propiedad,co puesta D9;(55) =EFE=E96EK tabla,co positor (ca po,id) )9 EE<E;E KE; 9*<< ) E9CD9E-DnnoEB1

En el caso de propiedades compuestas en objetos relacionales, la eliminacin se har en cascada:


6=EA;E ;AB<E co positorco puesto ( co positorco puesto,id D9;(55) 9); 9*<<

Eugenia Bahit - Teora sintctico-gramatical de objetos - 79


A*;),D96=E3E9; "=D3A=F GEF 7 co puesto D9;(55) 9); 9*<< 7 F)=EDC9 GEF (co puesto) =EFE=E96EK co puesto (co puesto,id) )9 EE<E;E 6AK6AEE 7 co positor D9;(55) 9); 9*<< 7 F)=EDC9 GEF (co positor) =EFE=E96EK co positor (co positor,id) )9 EE<E;E 6AK6AEE 7 relacion D9;(H) ) E9CD9E-DnnoEB1

Todos los campos marcados forneas, sern idexados

como

claves

Esto es, a fin de optimizar el rendimiento de la base de datos.


6=EA;E ;AB<E co positorco puesto ( co positorco puesto,id D9;(55) 9); 9*<< A*;),D96=E3E9; "=D3A=F GEF 7 co puesto D9;(55) 9); 9*<< ( 6N7E8 (%o!p e#to) 7 F)=EDC9 GEF (co puesto) =EFE=E96EK co puesto (co puesto,id) )9 EE<E;E 6AK6AEE 7 co positor D9;(55) 9); 9*<< ( 6N7E8 (%o!po#itor) 7 F)=EDC9 GEF (co positor) =EFE=E96EK co positor (co positor,id) )9 EE<E;E 6AK6AEE 7 relacion D9;(H) ) E9CD9E-DnnoEB1

Esta indexacin, deber estar presente en cualquier campo indicado como clave fornea, de cualquier tabla.

80 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Ten en cuenta que seguir todas las reglas de estilo antes mencionadas, ser la forma ms acertada de mantener un diseo simple.

Creacin de la base de datos Todas las consultas anteriores (obtenidas del mapeo relacional), debern ser escritas en un archivo SQL (database.sql). Al principio de este archivo, escribiremos tambin, la consulta SQL para crear y usar la base de datos:
6=EA;E EA;ABAKE nuevadb1 *KE nuevadb1

Es muy frecuente cometer errores de escritura que pueden afectar la sintaxis del lenguaje SQL, provocando que al ejecutar el archivo, la construccin de nuestra base de datos quede inconclusa. Para prevenir este problema, como primera lnea de nuestro script SQL, nos ocuparemos de eliminar previamente la base de datos. Esto nos permitir ejecutar el archivo tantas veces como sea necesario, con solo corregir el error de sintaxis informado por MySQL.
E=)" EA;ABAKE DF ELDK;K nuevadb1 6=EA;E EA;ABAKE nuevadb1

Eugenia Bahit - Teora sintctico-gramatical de objetos - 81


*KE nuevadb1

Finalmente, para correr el archivo y crear la base de datos, ejecutaremos el siguiente comando:
$sql /u root /p 4 database.sql

Si todo ha ido bien, ningn mensaje ser mostrado en pantalla. Para comprobar la base de datos, ingresar a MySQL:
$sql /u root /p

Mostrar todas las bases de datos para verificar que la nuestra haya sido creada:
s%o( databases1

Si nuestra base de datos se encuentra creada, la seleccionamos para ver sus tablas:
use nuevadb1 s%o( tables1

Para ver la estructura interna de cualquiera de las tablas, escribimos:


describe no bre,de,la,tabla1

Para salir, escribe:


e2it

82 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 83

Captulo VIII: Objetos, subtipos y herencia real


Como herencia entendemos a aquellos objetos que heredan de otros, adquiriendo as, sus mismas caractersticas. Pero a veces, se hace difcil discernir si realmente estamos en presencia de dos objetos diferentes, dos objetos similares o un solo objeto con una propiedad cuyo valor, marque la diferencia.

Herencia o propiedades distintivas? Por ejemplo, si hablamos de azulejos y lajas, en principio parecera que estamos hablando de dos objetos diferentes. Sin embargo ambos objetos tienen las mismas propiedades: color, textura, espesor, anchura y longitud. Ambos objetos, a la vez, cumplen la misma funcin: servir de revestimiento a las paredes. Pero color, textura, espesor, longitud y anchura no son a caso las propiedades de un tipo de revestimiento? Este es el caso de un solo objeto

84 - Eugenia Bahit - Teora sintctico-gramatical de objetos

(Revestimiento) con una propiedad cuyo valor, marcar la diferencia: tipo, la cul podr tener diferentes valores (azulejo, laja y tambin cermico, baldosa, etc.) que sern los que en definitiva, marquen la diferencia. Hablamos de un solo objeto con propiedades simples.

Herencia o polimorfismo? Sin embargo, puedo tener dos objetos con las mismas propiedades y no tener la posibilidad de unificarlos, ya que los mismos, pertenecen a grupos de objetos diferentes: un vidrio tambin puede definirse con color, textura, espesor, anchura y longitud pero sin embargo, no pertenece al grupo de los revestimientos. Este es el caso de dos objetos diferentes, sin relacin entre s.

Herencia real y subtipos En el afn de unificar objetos, podemos cometer errores que muchas veces pasan desapercibidos. Pensemos en el objeto pared: si una habitacin tiene 4 paredes, una de las paredes tiene una ventana y otra de las paredes tiene una puerta

Eugenia Bahit - Teora sintctico-gramatical de objetos - 85

realmente estamos en presencia solo de un objeto pared? Lo cierto e irrefutable es que las cuatro son paredes. De eso no hay ninguna duda. Pero la presencia de propiedades compuestas (ventana en un caso, puerta en el otro) nos est marcando claramente que estamos en presencia de subtipos del objeto. Pared, tendr como propiedades todas aquellas que hemos definido con anterioridad excepto puerta y ventana que pasarn a ser propiedades de los subtipos de pared: ParedConPuerta y ParedConVentana respectivamente. Los subtipos heredarn todas las propiedades del tipo principal, incluso la propiedad objeto_id. Por la base de datos, no habr que preocuparse en hacer un nuevo mapeo, ya que cuando existe herencia, las propiedades de los subtipos comparten la tabla con la clase madre.

Definiendo la herencia en el cdigo


Python: class 6lase#ija(6lase3adre):

86 - Eugenia Bahit - Teora sintctico-gramatical de objetos

PHP: class 6lase#ija e2tends 6lase3adre { }

Inicializando subtipos En los mtodos constructores, los subtipos deben inicializarse no solo con sus nuevas propiedades, sino adems, debern inicializar (en su propio constructor), a la clase madre:
Python: class 6lase#ija(6lase3adre): de+ ,,init,,(sel+): # per(9.a#eHi-a( #e.&)/__init__() PHP: class 6lase#ija e2tends 6lase3adre { +unction ,,construct() { parent::,,construct()1 } }

Finalmente, nuestras clases Pared, ParedConVentana y ParedConPuerta, se vern as:


Python: class "ared(object): de+ ,,init,,(sel+) : sel+.pared,id sel+.lajas - &'

Eugenia Bahit - Teora sintctico-gramatical de objetos - 87


sel+.%abitacion - 0 class "ared6onVentana("ared): de+ ,,init,,(sel+7 ventana-9one) : super("ared6onVentana7 sel+).,,init,,() sel+.ventana - co pose(ventana7 Ventana) class "ared6on"uerta("ared): de+ ,,init,,(sel+7 puerta-9one) : super("ared6on"uerta7 sel+).,,init,,() sel+.puerta - co pose(puerta7 "uerta) PHP: class "ared { +unction ,,construct() { .t%is/0pared,id - 01 .t%is/0lajas - arra$()1 .t%is/0%abitacion - 01 } } class "ared6onVentana e2tends "ared { +unction ,,construct(Ventana .ventana) { parent::,,construct()1 .t%is/0ventana - .ventana1 } } class "ared6on"uerta e2tends "ared { +unction ,,construct("uerta .puerta) { parent::,,construct()1 .t%is/0puerta - .puerta1

88 - Eugenia Bahit - Teora sintctico-gramatical de objetos


} }

Herencia: saber donde parar Podramos ponernos an ms meticulosos y decir que Puerta y Ventana son dos tipos de abertura diferentes y obtener entonces, el objeto ParedConAbertura en vez de ParedConVentana y ParedConPuerta. Sin embargo, aunque las aberturas compartan las mismas propiedades (como marco, altura, etc.), podramos caer en una herencia infinita de abertura y el diseo de los objetos, estara dejando de lado la simplicidad en nombre de la meticulosidad obsesiva.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 89

Captulo IX: Modelado de objetos y agrupacin


En breves palabras (ya que no necesitamos decir mucho) y antes de comenzar a crear los mtodos de nuestros objetos, una vez stos han sido diseados, estamos en condiciones de modelarlos y agruparlos a fin de mantener una estructura equilibrada y un diseo simple de la aplicacin.

Modelado y agrupacin Se puede decir que un modelo es la forma de agrupar clases y categorizarlas. Un modelo constituye un archivo (lo que para Python se denomina mdulo12). Cada modelo estar integrado por clases con relacin directa: Cada clase estar en su propio modelo (el

12 No confundir el trmino con mdulo en la Arquitectura de Software

90 - Eugenia Bahit - Teora sintctico-gramatical de objetos

cual, llevar el nombre de la clase principal en minsculas) Subtipos estarn en el mismo modelo que el objeto madre Relacionales simples, estarn en el mismo modelo que el objeto al que componen

A la vez, todos los modelos, debern agruparse en un directorio al que podremos llamar models. En el caso de Python, este directorio deber poder ser manipulado como un paquete. Por este motivo, un archivo __init__.py deber incluirse al mismo.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 91

Captulo X: Bases de datos, consultas y abstraccin


Para poder comenzar a trabajar con estructuras de datos, necesitaremos tener en cuenta que: Una clase, jams debe conectarse de forma directa a la base de datos, puesto que resta simplicidad al diseo, al tiempo que provoca una gran redundancia de cdigo, haciendo el sistema poco legible y difcil de mantener; Cada clase deber recurrir entonces, a una capa de abstraccin, que le permita conectarse a la base de datos y efectuar consultas;

Notar que por cuestiones de seguridad, en PHP trabajaremos con el conector mysqli y no con mysql. Sin embargo, en Python solo bastar con una funcin. La capa de abstraccin a bases de datos, pasar a formar parte del ncleo de la aplicacin, puesto

92 - Eugenia Bahit - Teora sintctico-gramatical de objetos

que podr ser reutilizada por cualquier componente de nuestro sistema. Para albergar archivos de ncleo, incluiremos un directorio llamado core.

Creando una capa de abstraccin en Python


En Python, no habr demasiada complicacin. Una simple funcin a la cual podamos pasarle nuestra consulta SQL, ser suficiente. Antes de comenzar: debers instalar el mdulo MySQLdb para poder conectarte a bases de datos MySQL:
sudo apt/get install p$t%on/ $sqldb

Cdigo de la capa de abstraccin Archivo: core/dblayer.py


M /N/ coding: ut+/O /N/ i port 3$KP<db +ro settings i port EB,#)K;7 EB,*KE=7 EB,"AKK7 Q EB,9A3E

Eugenia Bahit - Teora sintctico-gramatical de objetos - 93


de+ run,quer$(quer$): datos - &EB,#)K;7 EB,*KE=7 EB,"AKK7 EB,9A3E' conn - 3$KP<db.connect(Ndatos) cursor - conn.cursor() cursor.e2ecute(quer$) i+ quer$.upper().starts(it%('KE<E6;'): data - cursor.+etc%all() else: conn.co it() i+ quer$.upper().starts(it%('D9KE=;'): data - cursor.lastro(id else: data - 9one cursor.close() conn.close() return data

Como puede observarse, la funcin run_query() recibe como parmetro una sentencia SQL. La funcin comprueba qu tipo de clusula se est invocando: Cuando la sentencia sea de tipo SELECT, retornar una tupla con N tuplas dentro, equivalentes a la cantidad de registros obtenidos de la ejecucin de dicha consulta Cuando la sentencia sea de tipo escritura (INSERT, DELETE y UPDATE), har un commit. Y cuando se tratase de una sentencia de tipo INSERT, retornar la ID del ltimo registro

94 - Eugenia Bahit - Teora sintctico-gramatical de objetos

insertado.

Creando una capa de abstraccin en PHP con mysqli


En PHP , crear una capa de abstraccin con el conector mysqli, es un asunto mucho ms complejo que en Python y para nada equiparable. El objetivo de utilizar el conector mysqli y no el tradicional conector mysql de PHP , es prevenir inyecciones SQL de forma simple y poder trabajar con aplicaciones mucho ms robustas. Pero qu es exactamente mysqli y en qu se diferencia de mysql? Bsicamente, como bien se define en el manual oficial de PHP , mysqli es una extensin mejorada del conector mysql. Entre las principales diferencias, se encuentran adems, sus dos grandes ventajas: Permite trabajar en estilo orientado a objetos (tambin contina proveyendo soporte para estilo procedimental); Nos facilita una forma segura de filtrado de datos en sentencias SQL, para prevenir inyecciones SQL;

Eugenia Bahit - Teora sintctico-gramatical de objetos - 95

Sin dudas, mysqli es una gran ventaja frente al antiguo conector. Tiene una gran cantidad de clases, mtodos, constantes y propiedades muy bien documentados13. Sin embargo, entender la documentacin puede ser una tediosa tarea, en la cual, hallar un principio y un fin, se podr convertir en la peor pesadilla de tu vida. Antes de comenzar: debers instalar el paquete php5-mysql para poder trabajar con el conector mysqli:
sudo apt/get install p%p@/ $sql

Ahora s. Manos a la obra! Y a crear una capa de abstraccin con mysqli orientado a objetos.

Recetario
Lo primero que debemos tener en cuenta, es que nuestra capa de abstraccin deber proveer de mtodos pblicos, que puedan ser llamados de forma esttica, para que crear un objeto conector, no sea necesario.
13 http://php.net/manual/es/book.mysqli.php

96 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Para poder lograr una capa de abstraccin genrica, la clave es utilizar ReflectionClass14 para crear una instancia de mysqli_stmt y mediante ReflectionClass->getMethod, invocar al mtodo bind_param. De lo contrario, preparar una consulta SQL y enlazarle los valores a ser filtrados, ser imposible.
Ten en cuenta que para seguir los ejemplos de este libro, es necesario contar con la versin 5.3.6 o superior, de PHP .

Propiedades Nuestra capa de abstraccin, tendr una nica propiedad pblica, destinada a almacenar los datos obtenidos tras una consulta de seleccin. El resto de las propiedades, sern de mbito protegido, accesibles solo desde nuestra clase y clases que hereden de sta.
class EB)ject { protected static .conn1 M )bjeto conector $sqli protected static .st t1 M preparacin de la consulta KP< M )bjeto =e+le2ivo de $sqli,st t protected static .re+lection1 protected static .sql1 M Kentencia KP< a ser preparada M Arra$ conteniendo los tipo de datos M !s los datos a ser enla8ados

14 http://php.net/manual/es/class.reflectionclass.php

Eugenia Bahit - Teora sintctico-gramatical de objetos - 97


M (ser! recibido co o par! etro) protected static .data1 M 6oleccin de datos retornados por una consulta M de seleccin public static .results1 }

La consulta SQL, deber ser seteada en los modelos (clases) donde se requiera, incluyendo marcadores de parmetros (embebidos con el signo ?), en la posicin donde un dato deba ser enlazado. Un ejemplo de ella, podra ser el siguiente:
.sql - RD9KE=; D9;) vidrio (espesor7 te2tura7 pig entacion) VA<*EK (S7 S7 S)R1

Mientras que el array $data, deber contener, como primer elemento, una string con el tipo de datos y los elementos siguientes, sern los datos a ser enlazados (todos pasados como string):
.data - arra$(RissR7 R{.t%is/0espesor}R7 R{.t%is/0te2tura}R7 R{.t%is/0pig entacion}R)1

El primer elemento, siempre representar el tipo de datos correspondiente al marcador de parmetro que se desea enlazar. Siendo los tipos de datos posibles: s (string), i (entero), d (doble) y b (blob).

98 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Mtodos Conectar a la base de datos:


protected static +unction conectar() { sel+::.conn - ne( $sqli(EB,#)K;7 EB,*KE=7 EB,"AKK7 EB,9A3E)1 }

Requerir 4 constantes predefinidas (se recomienda definirlas en un archivo settings): DB_HOST, DB_USER, DB_PASS y DB_NAME. Preparar una sentencia SQL (con marcadores de parmetros):
protected static +unction preparar() { sel+::.st t - sel+::.conn/0prepare( sel+::.sql)1 sel+::.re+lection - ne( =e+lection6lass( ' $sqli,st t')1 }

La clase ReflectionClass de PHP , cumple un papel fundamental: solo a travs de ella podemos crear un objeto mysqli_stmt reflexivo, siendo sta, la nica alternativa que tenemos para preparar sentencias SQL con marcadores de parmetros, de forma dinmica. La propiedad esttica $sql (self::$sql) ser creada

Eugenia Bahit - Teora sintctico-gramatical de objetos - 99

por el nico mtodo pblico que tendr la clase. Enlazar los datos con la sentencia SQL preparada:
protected static +unction set,para s() { . et%od - sel+::.re+lection/0get3et%od( 'bind,para ')1 . et%od/0invoTeArgs(sel+::.st t7 sel+::.data)1 }

La propiedad esttica $data que se pasa como segundo parmetro a invokeArgs, tambin ser seteada por el nico mtodo pblico. En este mtodo (set_params), la variable temporal $method, llama reflexivamente (a travs del mtodo getMethod de reflectionClass), al mtodo bind_param de la clase mysqli. En la siguiente instruccin, a travs del mtodo invokeArgs de ReflectionClass, le pasa por referencia a bind param, los datos a ser enlazados con la sentencia preparada (almacenados en el array $data). Podr a decirse que invokeArgs, se comporta de forma similar a call_user_func_array(). Enlazar resultados de una consulta de seleccin:
protected static +unction get,data(.+ields) { . et%od - sel+::.re+lection/0get3et%od(

100 - Eugenia Bahit - Teora sintctico-gramatical de objetos


'bind,result')1 . et%od/0invoTeArgs(sel+::.st t7 .+ields)1 (%ile(sel+::.st t/0+etc%()) { sel+::.results&' - unseriali8e( seriali8e(.+ields))1 } }

Este mtodo es uno de los ms complejos y rebuscados, que incluso cuenta con algunas pseudo-magias un tanto raras como el uso de las funciones serialize y unserialize en la la misma instruccin. Pero analicmoslo detenidamente. El parmetro $fields ser recibido a travs del nico mtodo pblico que crearemos en nuestra capa de abstraccin (este mtodo, a la vez, recibir este dato, tambin como parmetro, pero opcional). Este parmetro, ser un array asociativo, donde las claves, sern asociadas al nombre de los campos, y el valor de esas claves, al dato contenido en el campo. Si tuviese la siguiente consulta SQL:
KE<E6; vidrio,id7 espesor7 te2tura7 pig entacion F=)3 vidrio U#E=E vidrio,id - S

Mi array asociativo, podra paracerse al siguiente:


.+ields - arra$(Rvidrio,idR -0 RR7

Eugenia Bahit - Teora sintctico-gramatical de objetos - 101


RespesorR -0 RR7 Rte2turaR -0 RR7 Rpig entacionR -0 RR)1

mysqli->bind_result() enlazar el campo vidro.espesor a la clave espesor, vidro.textura a la clave textura y vidrio.pigmentacion a la clave pigmentacion. Las instrucciones:
. et%od - sel+::.re+lection/0get3et%od( 'bind,result')1 . et%od/0invoTeArgs(sel+::.st t7 .+ields)1

se comportan de forma similar, a sus homnimas en el mtodo set_params. Llama reflexivamente al mtodo bind_result de la clase mysqli y le pasa por referencia, al array $fields. En el bucle while, estamos asociando iterativamente los datos obtenidos a nuestra propiedad pblica $results. Pero cmo lo hacemos? para qu serializar y deserializar los datos?:
(%ile(sel+::.st t/0+etc%()) { sel+::.results&' - unseriali8e( seriali8e(.+ields))1

102 - Eugenia Bahit - Teora sintctico-gramatical de objetos


}

En cada iteracin, stmt->fetch nos est retornando nuestro array $fields, asociado al registro de la tabla, sobre el cul se est iterando. Es decir, que en cada iteracin, stmt->fetch nos retornar algo como esto:
.+ields - arra$(Rvidrio,idR -0 57 RespesorR -0 507 Rte2turaR -0 RlisaR7 Rpig entacionR -0 Rblancu8caR)1

Pero nuestro array $fields, ha sido pasado por referencia. Ergo, en cada iteracin, su contenido ser modificado. Si a mi propiedad esttica $results, le agrego como elemento, un array que est siendo modificado por referencia en el momento que lo estoy asignando a mi propiedad esttica, mi propiedad esttica, ser tambin, modificada en cada iteracin. Para prevenir eso, freezo mi array $fields y lo almaceno en $results serializado. Pero como luego necesitar recuperarlo, ahorro un paso y lo deserializo en la misma iteracin. Al serializarlo, estoy mgicamente emulando una inmutabilidad de los datos asociados.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 103

Notar que cuando la consulta efectuada se realice por coincidencia con una clave primaria (id del objeto), no ser necesario acceder a la propiedad esttica $results, ya que los resultados se encontrarn reflejados en el array $fields, quien al ser pasado por referencia, es modificado tras la llamada a esta capa de abstraccin.

Cerrar conexiones abiertas:


protected static +unction +inali8ar() { sel+::.st t/0close()1 sel+::.conn/0close()1 }

Un mtodo pblico que ejecute todas las acciones:


public static +unction ejecutar(.sql7 .data7 .+ields-False) { sel+::.sql - .sql1 M setear la propiedad .sql sel+::.data - .data1 M setear la propiedad .data sel+::conectar()1 M conectar a la base de datos sel+::preparar()1 M preparar la consulta KP< sel+::set,para s()1 M enla8ar los datos sel+::.st t/0e2ecute()1 M ejecutar la consulta i+(.+ields) { sel+::get,data(.+ields)1 return sel+::.results1 } else { i+(strpos(sel+::.sql7 strtoupper('D9KE=;')) --- 0) { return sel+::.st t/0insert,id1 } } sel+::+inali8ar()1 M cerrar cone2iones abiertas

104 - Eugenia Bahit - Teora sintctico-gramatical de objetos


}

La estructura de control de flujo condicional, que utiliza el mtodo ejecutar(), es la encargada de discernir si se trata de una consulta de lectura a la base de datos para as, llamar al mtodo get_data, o si se trata de una consulta de escritura (INSERT, UPDATE o DELETE). En ese caso, verifica si es una escritura de tipo INSERT para retornar la id del nuevo registro creado. Cdigo completo de la capa de abstraccin
class EB)bject { protected static .conn1 protected static .st t1 protected static .re+lection1 protected static .sql1 protected static .data1 public static .results1 protected static +unction conectar() { sel+::.conn - ne( $sqli(EB,#)K;7 EB,*KE=7 EB,"AKK7 EB,9A3E)1 } protected static +unction preparar() { sel+::.st t - sel+::.conn/0prepare(sel+::.sql)1 sel+::.re+lection - ne( =e+lection6lass(' $sqli,st t')1 } protected static +unction set,para s() { . et%od - sel+::.re+lection/0get3et%od('bind,para ')1 . et%od/0invoTeArgs(sel+::.st t7 sel+::.data)1 } protected static +unction get,data(.+ields) { . et%od - sel+::.re+lection/0get3et%od('bind,result')1

Eugenia Bahit - Teora sintctico-gramatical de objetos - 105


. et%od/0invoTeArgs(sel+::.st t7 .+ields)1 (%ile(sel+::.st t/0+etc%()) { sel+::.results&' - unseriali8e(seriali8e(.+ields))1 } } protected static +unction +inali8ar() { sel+::.st t/0close()1 sel+::.conn/0close()1 } public static +unction ejecutar(.sql7 .data7 .+ields-False) { sel+::.sql - .sql1 sel+::.data - .data1 sel+::conectar()1 sel+::preparar()1 sel+::set,para s()1 sel+::.st t/0e2ecute()1 i+(.+ields) { sel+::get,data(.+ields)1 return sel+::.results1 } else { i+(strpos(sel+::.sql7 strtoupper('D9KE=;')) --- 0) { return sel+::.st t/0insert,id1 } } sel+::+inali8ar()1 } }

Cmo utilizar la capa de abstraccin creada? En todos los casos, siempre ser necesario invocar estticamente al mtodo ejecutar(), pasndole al menos dos parmetros: la sentencia SQL a preparar y un array con los datos a enlazar a la sentencia SQL preparada:
.sql - RD9KE=; D9;) vidrio (espesor7 te2tura7 pig entacion) VA<*EK (S7 S7 S)R1 .data - arra$(RissR7 R{.t%is/0espesor}R7

106 - Eugenia Bahit - Teora sintctico-gramatical de objetos


R{.t%is/0te2tura}R7 R{.t%is/0pig entacion}R)1 .t%is/0vidrio,id - EB)bject::ejecutar(.sql7 .data)1

Cuando se tratare de una consulta de seleccin, se deber adicionar un tercer parmetro, el cul ser un array asociativo, cuyas claves, sern asociadas a los campos de la tabla:
.sql - RKE<E6; vidrio,id7 espesor7 te2tura7 pig entacion F=)3 vidrio U#E=E vidrio,id - SR1 .data - arra$(RiR7 R{.t%is/0vidrio,id}R)1 .+ields - arra$(Rvidrio,idR -0 RR7 RespesorR -0 RR7 Rte2turaR -0 RR7 Rpig entacionR -0 RR)1 EB)bject::ejecutar(.sql7 .data7 .+ields)1

Eugenia Bahit - Teora sintctico-gramatical de objetos - 107

Captulo XI: El mtodo save() en objetos simples, compuestos y relacionales


La finalidad del mtodo save() ser guardar los datos de un objeto (nuevo o existente). Esto nos permitir, poder recuperar el objeto ms adelante, con su mtodo get() correspondiente. El mtodo save() es uno de los ms simples de todos los mtodos (aunque sin dudas, el ms simple de todos es el mtodo destroy() que veremos ms adelante). Al ser su responsabilidad guardar un objeto, sea ste un nuevo objeto u objeto existente, tendr que ingenirselas para saber si debe ejecutar una consulta de insercin o de actualizacin. Para ello, recurrir a evaluar el valor de la propiedad objeto_id. Cuando sta sea igual a cero, entonces un nuevo objeto ha sido creado. De lo contrario, un objeto existente, est solicitando guardar sus cambios.

108 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Finalmente, la responsabilidad del mtodo save(), ser establecer el valor de la propiedad objeto_id con el dato retornado por la capa de abstraccin, cuando la consulta, haya sido de tipo INSERT. Se debe tener en cuenta que todos los m todos save() -sin excepcin alguna-, para crear las consultas de insercin y actualizacin, tendrn en cuenta las mismas pautas que han sido mencionadas para el mapeo: todos los mtodos save() guardarn solo y nicamente los datos de aquellas propiedades que han sido establecidas como campo de su propia tabla. Si observamos los siguientes ejemplos, veremos que no existe diferencia alguna, entre los mtodos save() de objetos simples, compuestos y relacionales:
Python:
3 UN :;<E): =6'PLE class Vidrio(object): de+ ,,init,,(sel+): sel+.vidrio,id - 0 sel+.espesor - 0 sel+.te2tura - '' sel+.pig entacion - '' de& #ave(#e.&): i+ sel+.vidrio,id -- 0: sql - RRRD9KE=; D9;) vidrio (espesor7 te2tura7 pig entacion)

Eugenia Bahit - Teora sintctico-gramatical de objetos - 109


VA<*EK (:i7 ':s'7 ':s')RRR : ( sel+.espesor7 sel+.te2tura7 sel+.pig entacion) sel+.vidrio,id - run,quer$(sql) else: sql - RRR*"EA;E vidrio KE; espesor - :i7 te2tura - ':s'7 pig entacion - ':s' U#E=E vidrio,id - :iRRR : ( sel+.espesor7 sel+.te2tura7 sel+.pig entacion7 sel+.vidrio,id) run,quer$(sql) 3 UN :;<E): 9:'PUE=): class Ventana(object): de+ ,,init,,(sel+7 arco): sel+.ventana,id - 0 sel+. arco - co pose( arco7 3arco) de& #ave(#e.&): i+ sel+.ventana,id -- 0: sql - RRRD9KE=; D9;) ventana ( arco) VA<*EK (:i)RRR : ( sel+. arco. arco,id) sel+. arco,id - run,quer$(sql) else: sql - RRR*"EA;E ventana KE; arco - :i U#E=E ventana,id - :iRRR : ( sel+. arco. arco,id7 sel+.ventana,id) run,quer$(sql) 3 UN :;<E): >ELA96:NAL class <aja"ared(object): de+ ,,init,,(sel+7 co puesto7 co positor-9one):

110 - Eugenia Bahit - Teora sintctico-gramatical de objetos


sel+.lajapared,id - 0 sel+.pared - co pose(co puesto7 "ared) sel+.laja - co pose(co positor7 <aja) sel+.relacion - 5 de+ set,relacion(sel+): t pvar - 0 (%ile t pvar 4 sel+.relacion: sel+.pared.add,laja(sel+.laja) t pvar >- 5 de& #ave(#e.&): i+ sel+.lajapared,id -- 0: sql - RRRD9KE=; D9;) lajapared (pared7 laja7 relacion) VA<*EK (:i7 :i7 :i)RRR : ( sel+.pared.pared,id7 sel+.laja.laja,id7 sel+.relacion) sel+.lajapared,id - run,quer$(sql) else: sql - RRR*"EA;E lajapared KE; pared - :i7 laja - :i7 relacion - :i U#=E lajapared,id - :iRRR : ( sel+.pared.pared,id7 sel+.laja.laja,id7 sel+.relacion7 sel+.lajapared,id) run,quer$(sql)

PHP:
3 UN :;<E): =6'PLE class Vidrio{ +unction ,,construct() { .t%is/0vidrio,id - 01 .t%is/0espesor - 01 .t%is/0te2tura - ''1 .t%is/0pig entacion - ''1 } & n%tion #ave() 2

Eugenia Bahit - Teora sintctico-gramatical de objetos - 111


i+(.t%is/0vidrio,id -- 0) { .sql - RD9KE=; D9;) vidrio (espesor7 te2tura7 pig entacion) VA<*EK (S7 S7 S)R1 .data - arra$(RissR7 R{.t%is/0espesor}R7 R{.t%is/0te2tura}R7 R{.t%is/0pig entacion}R)1 .t%is/0vidrio,id - EB)bject::ejecutar( .sql7 .data)1 } else { .sql - R*"EA;E vidrio KE; espesor - S7 te2tura - S7 pig entacion - S U#E=E vidrio,id - SR1 .data - arra$(RissiR7 R{.t%is/0espesor}R7 R{.t%is/0te2tura}R7 R{.t%is/0pig entacion}R7 R{.t%is/0vidrio,id}R)1 EB)bject::ejecutar(.sql7 .data)1 } } }

3 UN :;<E): 9:'PUE=): class Ventana { +unction ,,construct(3arco . arco-9*<<) { .t%is/0ventana,id - 01 .t%is/0 arco - . arco1 } & n%tion #ave() 2 i+(.t%is/0ventana,id -- 0) { .sql - RD9KE=; D9;) ventana ( arco) VA<*EK (S)R1 .data - arra$(RiR7 R{.t%is/0 arco/0 arco,id}R)1 .t%is/0ventana,id - EB)bject::ejecutar( .sql7 .data)1 } else {

112 - Eugenia Bahit - Teora sintctico-gramatical de objetos


.sql - R*"EA;E ventana KE; arco - S U#E=E ventana,id - SR1 .data - arra$(RiiR7 R{.t%is/0 arco/0 arco,id}R7 R{.t%is/0ventana,id}R)1 EB)bject::ejecutar(.sql7 .data)1

} } }

3 UN :;<E): >ELA96:NAL class <aja"ared { +unction ,,construct("ared .co puesto7 <aja .co positor-9*<<) { .t%is/0lajapared,id - 01 .t%is/0pared - .co puesto1 .t%is/0laja - .co positor1 .t%is/0relacion - 51 } +unction set,relacion() { .t pvar - 01 (%ile(.t pvar 4 .t%is/0relacion) { .t%is/0pared/0add,laja(.t%is/0laja)1 .t pvar>>1 } } & n%tion #ave() 2 i+(.t%is/0lajapared,id -- 0) { .sql - RD9KE=; D9;) lajapared (pared7 laja7 relacion) VA<*EK (S7 S7 S)R1 .data - arra$(RiiiR7 R{.t%is/0pared/0pared,id}R7 R{.t%is/0laja/0laja,id}R7 R{.t%is/0relacion}R)1 .t%is/0lajapared,id - EB)bject::ejecutar( .sql7 .data)1 } else { .sql - R*"EA;E lajapared KE; pared - S7

Eugenia Bahit - Teora sintctico-gramatical de objetos - 113


laja - S7 relacion - S U#E=E lajapared,id - SR1 .data - arra$(RiiiiR7 R{.t%is/0pared/0pared,id}R7 R{.t%is/0laja/0laja,id}R7 R{.t%is/0relacion}R7 R{.t%is/0lajapared,id}R)1 EB)bject::ejecutar(.sql7 .data)1 } } }

Como se puede apreciar, no hay diferencias entre los mtodos save() de los distintos tipos de objetos: todos los mtodos save() siguen la misma lgica algortmica. El orden de llamada para los mtodos save() siempre estar basado en el orden de dependencias.
El orden de llamada a los mtodos save() es un factor clave en la creacin de objetos, ya que de estos mtodos depende de forma directa, la identidad de cada uno de nuestros objetos

Llamar al mtodo save() de un objeto sin

114 - Eugenia Bahit - Teora sintctico-gramatical de objetos

dependencias Un objeto simple, basta con crearlo y llamar a su mtodo save() correspondiente:
Python: piso - "iso() piso.tipo - '+lotante' piso. aterial - ' adera' piso.color - 'cedro' piso.save() PHP: .piso - ne( "iso()1 .piso/0tipo - '+lotante'1 .piso/0 aterial - ' adera'1 .piso/0color - 'cedro'1 .piso/0save()1

Llamar al compuesto

mtodo

save()

de

un

objeto

Un objeto compuesto, deber primero crear a su compositor, llamar al save() de ste, y luego crear el compuesto y llamar al save() del compuesto:
Python: vidrio - Vidrio() vidrio.espesor - 50 vidrio.te2tura - 'lisa' vidrio.pig entacion - 'blancu8ca' vidrio.save() arco - 3arco(vidrio) arco. aterial - 'alu inio'

Eugenia Bahit - Teora sintctico-gramatical de objetos - 115


arco.color - 'blanco' arco.save() PHP: .vidrio - ne( Vidrio()1 .vidrio/0espesor - 501 .vidrio/0te2tura - 'lisa'1 .vidrio/0pig entacion - 'blancu8ca'1 .vidrio/0save()1 . . . . arco - ne( 3arco(.vidrio)1 arco/0 aterial - 'alu inio'1 arco/0color - 'blanco'1 arco/0save()1

Orden de llamada a los mtodos save() cuando interviene un compositor de pertenencia Cuando un objeto compuesto, dependa de un compositor de pertenencia, primero se deber crear el compuesto y llamar a su save(). Luego, se crearn uno a uno los compositores de pertenencia llamando al save() del compositor en cada creacin y una vez guardados todos los compositores, ser n agregados al compuesto:
Python: %abitacion - #abitacion(piso7 cielo,raso) %abitacion.save() pared,i8q - "ared() pared,i8q.%abitacion - %abitacion.%abitacion,id pared,i8q.save()

116 - Eugenia Bahit - Teora sintctico-gramatical de objetos


%abitacion.add,pared(pared,i8q) PHP: .%abitacion - ne( #abitacion(.piso7 .cielo,raso)1 .%abitacion/0save()1 .pared,i8q - ne( "ared()1 .pared,i8q/0%abitacion - .%abitacion/0%abitacion,id1 .pared,i8q/0save()1 .%abitacion/0add,pared(.pared,i8q)1

Orden de llamada de los mtodos save() cuando interviene un compositor reutilizable con un objeto relacional Cuando un objeto se componga de N compositores reutilizables, primero se deber crear y guardar el compositor; luego se deber crear y guardar el objeto compuesto(); a continuacin, se crear el objeto relacional, se guardar la relacin y finalmente, se se llamar al mtodo set_relacion() del objeto relacional:
Python: laja - <aja() laja.color - 'beige' laja.save() pared - "ared() pared.%abitacion - %abitacion.%abitacion,id pared.save()

Eugenia Bahit - Teora sintctico-gramatical de objetos - 117


lajapared - <aja"ared(pared7 laja) lajapared.relacion - ?@ lajapared.save() lajapared.set,relacion() PHP: .laja - <aja()1 .laja/0color - 'beige'1 .laja/0save()1 .pared - "ared()1 .pared/0%abitacion - .%abitacion/0%abitacion,id1 .pared/0save()1 .lajapared - <aja"ared(.pared7 .laja)1 .lajapared/0relacion - ?@1 .lajapared/0save()1 .lajapared/0set,relacion()1

118 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 119

Captulo XII: El mtodo destroy()


El mtodo destroy() -destinado a destruir un objeto existente hacindolo irrecuperable-, es el ms simple de todos los mtodos. Se encuentra presente en todos los objetos, excepto en los relacionales multiplicadores , ya que estos mtodos no necesitan destruir -ni deben hacerlo- una relacin, sino que solo deberan poder modificarla. Puesto que la relacin, solo puede destruirse -con efecto en cascada- cuando uno de los integrantes de la relacin sea destruido. Este mtodo entonces, solo crear una sentencia SQL con la clusula DELETE identificando los datos a destruir, por medio de la ID del objeto.
Python: de+ destro$(sel+): sql - RRREE<E;E F=)3 obj U#E=E obj,id - :iRRR : sel+.obj,id run,quer$(sql) sel+.obj,id - 0

120 - Eugenia Bahit - Teora sintctico-gramatical de objetos


PHP: +unction destro$() { .sql - REE<E;E F=)3 obj U#E=E obj,id - SR1 .data - arra$(RiR7 R{.t%is/0obj,id}R)1 EB)bject::ejecutar(.sql7 .data)1 .t%is/0obj,id - 01 }

Eugenia Bahit - Teora sintctico-gramatical de objetos - 121

Captulo XIII: Mtodos get() estndar, para objetos simples y objetos compuestos
El mtodo get() es el mtodo ms complejo de los tres mtodos comunes, save(), get() y destroy().

El mtodo get() en objetos simples En los objetos sin dependencias (es decir, objetos simples), el mtodo get() solo realizar una consulta a la base de datos para obtener los valores que le ayuden a setear sus propiedades:
Python: class Vidrio(object): de+ ,,init,,(sel+): sel+.vidrio,id - 0 sel+.espesor - 0 sel+.te2tura - '' sel+.pig entacion - ''

122 - Eugenia Bahit - Teora sintctico-gramatical de objetos


de& get(#e.&): sql - RRRKE<E6; vidrio,id7 espesor7 te2tura7 pig entacion F=)3 vidrio

U#E=E vidrio,id - :iRRR : Q sel+.vidrio,id


+ields - run,quer$(sql)&0' sel+.vidrio,id - +ields&0' sel+.espesor - +ields&5' sel+.te2tura - +ields&J' sel+.pig entacion - +ields&H' PHP: class Vidrio{ +unction ,,construct() { .t%is/0vidrio,id - 01 .t%is/0espesor - 01 .t%is/0te2tura - ''1 .t%is/0pig entacion - ''1 } & n%tion get() 2 .sql - RKE<E6; vidrio,id7 espesor7 te2tura7 pig entacion F=)3 vidrio U#E=E vidrio,id - SR1 .data - arra$(RiR7 R{.t%is/0vidrio,id}R)1 .+ields - arra$(Rvidrio,idR -0 RR7 RespesorR -0 RR7 Rte2turaR -0 RR7 Rpig entacionR -0 RR)1 EB)bject::ejecutar(.sql7 .data7 .+ields)1 .t%is/0vidrio,id - .+ields&'vidrio,id''1 .t%is/0espesor - .+ields&'espesor''1 .t%is/0te2tura - .+ields&'te2tura''1 .t%is/0pig entacion - .+ields&'pig entacion''1 }

Eugenia Bahit - Teora sintctico-gramatical de objetos - 123

El mtodo get() en objetos compuestos En los objetos con propiedades compuestas por un nico objeto, el mtodo get() estar dividido en dos partes: la primera parte actuar como el get() de un objeto simple, mientras que la segunda, recurrir al get() de su compositor, para setear las propiedades compuestas por un solo objeto:
Python: class 3arco(object): de+ ,,init,,(sel+7 vidrio-9one): sel+. arco,id - 0 sel+. aterial - '' sel+.color - '' sel+.vidrio - co pose(vidrio7 Vidrio) de+ get(sel+): sql - RRRKE<E6; F=)3
U#E=E

arco,id7 aterial7 color7 vidrio arco


arco,id - :iRRR : sel+. arco,id

+ields - run,quer$(sql)&0' sel+. arco,id - +ields&0' sel+. aterial - +ields&5' sel+.color - +ields&J' vidrio = Vidrio() vidrio/vidrio_id = &ie.d#?@A vidrio/get() #e.&/vidrio = vidrio PHP: class 3arco {

124 - Eugenia Bahit - Teora sintctico-gramatical de objetos

+unction ,,construct(Vidrio .vidrio-9*<<) { .t%is/0 arco,id - 01 .t%is/0 aterial - ''1 .t%is/0color - ''1 .t%is/0vidrio - .vidrio1 } +unction get() { .sql - RKE<E6; arco,id7 aterial7 color7 vidrio F=)3 arco U#E=E arco,id - SR1 .data - arra$(RiR7 R{.t%is/0 arco,id}R)1 .+ields - arra$(R arco,idR -0 RR7 R aterialR -0 RR7 RcolorR -0 RR7 RvidrioR -0 RR)1 EB)bject::ejecutar(.sql7 .data7 .+ields)1 .t%is/0 arco,id - .+ields&' arco,id''1 .t%is/0 aterial - .+ields&' aterial''1 .t%is/0color - .+ields&'color''1

$vidrio = new Vidrio(); $vidrio1,vidrio_id = $&ie.d#?+vidrio+A; $vidrio1,get(); $thi#1,vidrio = $vidrio; } }

Ms adelante, veremos como con la ayuda de una fbrica de objetos, todo el cdigo resaltado (es decir, la creacin del compositor), pasar a ser responsabilidad de un nuevo objeto Factory.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 125

Es vlido aclarar que los subtipos y sus clases madres, poseern -cada uno de ellos-, un mtodo get() estndar como cualquier otro objeto.

126 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 127

Captulo XIV: Los mtodos get() en objetos compositores de pertenencia


Cuando un objeto sea considerado compositor de pertenencia (como por ejemplo, Pared), ste, contar con su mtodo get() estndar ms un mtodo get auxiliar, cuya nica responsabilidad, ser la de proveer una coleccin de datos compuestos por la identidad de cada uno de los compositores que pertenecen al mismo compuesto. Por favor, tngase en cuenta que este mtodo get auxiliar, no retornar objetos sino por el contrario, solo retornar datos que sirvan al objeto compuesto para obtener sus compositores exclusivos. Vale aclarar que cuando los objetos de pertenencia sean subtipos de un objeto madre, el mtodo get auxiliar, siempre deber pertenecer a la clase principal.

128 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Los mtodos get auxiliares, seleccionan solo la identidad de los compositores, utilizando como condicin, el valor de la propiedad de pertenencia. Cuando el compositor en cuestin, posea subtipos, adems de la identidad del objeto, deber retornar True o False en correspondencia a cada subtipo. Un ejemplo de consulta SQL para el objeto madre Pared, podra ser el siguiente:
KE<E6; pared,id7 DF(ventana DK 9*<<7 False7 ;rue)7 DF(puerta DK 9*<<7 False7 ;rue) pared %abitacion - 9

F=)3 U#E=E

El nombre de dichos mtodos estar conformado por la palabra get_ seguida del nombre de la propiedad del objeto compuesto, a la cual dicho compositor compone. Por ejemplo, el mtodo auxiliar de la clase Pared se llamar get_paredes(). Un ejemplo de mtodo get auxiliar, podramos encontrarlo en la clase madre Pared:
Python: de+ get,paredes(sel+): sql - RRRKE<E6; pared,id7 DF(ventana DK 9*<<7 False7 ;rue)7 DF(puerta DK 9*<<7 False7 ;rue) F=)3 pared

Eugenia Bahit - Teora sintctico-gramatical de objetos - 129


U#E=E %abitacion - :iRRR : sel+.%abitacion

return run,quer$(sql) PHP: +unction get,paredes() { .sql - RKE<E6; pared,id7 DF(ventana DK 9*<<7 False7 ;rue)7 DF(puerta DK 9*<<7 False7 ;rue) F=)3 pared U#E=E %abitacion - SR1 .data - arra$(RiR7 R{.t%is/0%abitacion}R)1 .+ields - arra$(Rpared,idR -0 RR)1 return EB)bject::ejecutar( .sql7 .data7 .+ields)1 }

Como se puede observar, los mtodos get auxiliares solo retornan datos y no objetos. En el caso de Python, retornar una tupla con N tuplas dentro, conteniendo la identidad de cada compositor pertenenciente al compuesto que luego lo invoque. Y en el caso de PHP , retornar un array, compuesto de N arrays asociativos. Estos mtodos get auxiliares, como se coment en el prrafo anterior, sern invocados desde el mtodo get() del objeto compuesto, a quien le tocar la parte ms compleja en la historia de los mtodos get() no estndar. Veamos el caso de Habitacion:
Python: de+ get(sel+):

130 - Eugenia Bahit - Teora sintctico-gramatical de objetos


sql - RRRKE<E6; %abitacion,id7 piso7 cielo,raso F=)3 %abitacion U#E=E
%abitacion,id - :iRRR : sel+.%abitacion,id

+ields - run,quer$(sql) sel+.%abitacion,id - +ields&0' piso - "iso() piso.piso,id - +ields&5' piso.get() sel+.piso - piso cr - 6ielo=aso() cr.cielo,raso,id - +ields&J' cr.get() sel+.cielo,raso - cr 3 Ha#ta aB C e. !Dtodo get() e#t5ndar 3 6n%orpora!o# na eEten%iFn pared - "ared() pared.%abitacion - sel+.%abitacion,id 3 ..a!ada a. !Dtodo a Ei.iar paredes - pared.get,paredes() 3 6tera!o# para o$tener .o# o$-eto# +or tupla in paredes: i+ tupla&5' is not False: pared - "ared6onVentana() pared.pared,id - tupla&0' pared.get() sel+.add,paredconventana(pared) eli+ tupla&J' is not False: pared - "ared6on"uerta() pared.pared,id - tupla&0' pared.get() sel+.add,paredconpuerta(pared) else: pared - "ared() pared.pared,id - tupla&0'

Eugenia Bahit - Teora sintctico-gramatical de objetos - 131


pared.get() sel+.add,pared(pared) PHP: +unction get() { .sql - RKE<E6; %abitacion,id7 piso7 cielo,raso F=)3 %abitacion U#E=E %abitacion,id - SR .data - arra$(RiR7 R{.t%is/0%abitacion,id}R)1 .+ields - arra$(R%abitacion,idR -0 RR7 RpisoR -0 RR7 Rcielo,rasoR -0 RR7)1 EB)bject::ejecutar(.sql7 .data7 .+ields)1 .t%is/0%abitacion,id - .+ields&'%abitacion,id''1 .piso - ne( "iso()1 .piso/0piso,id - .+ields&'piso''1 .piso/0get()1 .t%is/0piso - .piso1 .cr - ne( 6ielo=aso()1 .cr/0cielo,raso,id - .+ields&'cielo,raso''1 .cr/0get()1 .t%is/0cielo,raso - .cr1 3 Ha#ta aB C e. !Dtodo get() e#t5ndar 3 6n%orpora!o# na eEten#iFn .pared - ne( "ared()1 .pared/0%abitacion - .t%is/0%abitacion,id1 3 ..a!ada a. !Dtodo a Ei.iar .paredes - .pared/0get,paredes()1 3 6tera!o# para o$tener .o# o$-eto# +oreac%(.paredes as .arra$) {

132 - Eugenia Bahit - Teora sintctico-gramatical de objetos


i+(.arra$&'ventana'' V-- False) { .pared - ne( "ared6onVentana()1 .pared/0pared,id - .arra$&'pared,id''1 .pared/0get()1 .t%is/0add,paredconventana(.pared)1 } elsei+(.arra$&'puerta'' V-- False) { .pared - ne( "ared6on"uerta()1 .pared/0pared,id - .arra$&'pared,id''1 .pared/0get()1 .t%is/0add,paredconpuerta(.pared)1 } else { .pared - ne( "ared()1 .pared/0pared,id - .arra$&'pared,id''1 .pared/0get()1 .t%is/0add,pared(.pared)1 } } }

Eugenia Bahit - Teora sintctico-gramatical de objetos - 133

Captulo XV: El mtodo get() de los objetos relacionales multiplicadores


Mientras que los objetos compositores reutilizables contarn con un mtodo get() estndar, los objetos relacionales contarn con mtodo get() apenas modificado. En principio, debemos tener en cuenta que los mtodos get() de los objetos relacionales, solo sern llamados desde el mtodo get() de un objeto compuesto, quien a la vez, se deber pasar a s mismo como parmetro al momento de crear el objeto relacional. El mtodo get() de un relacional multiplicador, obtendr los valores necesarios para configurar todas las propiedades, estableciendo como condicin, la identidad del objeto al que compone. Tras obtener los datos de la base de datos, actuar como cualquier otro mtodo get() estndar:

134 - Eugenia Bahit - Teora sintctico-gramatical de objetos

1. Modificar su propiedad relacin 2. Recuperar al compositor (invocando al mtodo get() de ste) para modificar a su propiedad compositor Finalmente, llamar a su propio mtodo set_relacion() para que se encargue de componer al objeto que lo ha invocado. Un ejemplo de consulta SQL de seleccin en un objeto relacional multiplicador, sera el siguiente:
KE<E6; relacional,id7 co positor7 relacion F=)3 relacional U#E=E co puesto - 9

De modo genrico, el mtodo get() de un relacional multiplicador, deber guardar siempre la siguiente forma y estructura:
Python: de+ get(sel+): sql - RRRKE<E6; relacional,id7 co positor7 relacion F=)3 relacional U#E=E co puesto - :iRRR : Q sel+.co puesto.co puesto,id +ields - run,quer$(sql)&0' sel+.relacion - +ields&5' co positor - 6o positor() co positor.co positor,id - +ields&0' co positor.get()

Eugenia Bahit - Teora sintctico-gramatical de objetos - 135


sel+.objetoco positor - co positor sel+.set,relacion() PHP: +unction get() { .sql - RKE<E6; relacional,id7 co positor7 relacion F=)3 relacional U#E=E co puesto - 9R1 .data - arra$(RiR7 R{.t%is/0co puesto/0co puesto}R)1 .+ields - arra$(Rrelacional,idR -0 RR7 Rco positorR -0 RR7 RrelacionR -0 RR)1 EB)bject::ejecutar(.sql7 .data7 .+ields)1 .t%is/0relacion - .+ields&'relacion''1 .co positor - ne( 6o positor()1 .co positor/0co positor,id - .+ields&'co positor''1 .co positor/0get()1 .t%is/0co positor - .co positor1 .t%is/0set,relacion()1 }

Finalmente, el objeto compuesto se encargar de llamar al get() del relacional, como ltima instancia de su mtodo get() estndar:
Python: de+ get(sel+): ... pasos est!ndar re.a%iona. = >e.a%iona.(#e.&) re.a%iona./get()

136 - Eugenia Bahit - Teora sintctico-gramatical de objetos


PHP: +unction get(): ... pasos est!ndar $re.a%iona. = new >e.a%iona.($thi#); $re.a%iona.1,get();

Notar que al crear el objeto relacional, el objeto compuesto se pasa a s mismo como parmetro:
"$t%on: =elacional(#e.&) "#": ne( =elacional($thi#)

Eugenia Bahit - Teora sintctico-gramatical de objetos - 137

Captulo XVI: Factora de objetos con Factory Pattern. Objetos compuestos con mtodos get() mucho ms simples
Factory es -al igual que composite- un patrn de diseo. Su sencillez y simpleza, consisten en un mtodo encargado de crear otros objetos. Para qu nos puede ser til un objeto Factory? Para que los mtodos get() que deben llamar al mtodo homnimo de los objetos que lo componen, pueda ser ms limpio, menos redundante y por lo tanto, ms eficiente. Imaginemos un objeto compuesto por otros 3 objetos. El mtodo get() de ste, se ver como el siguiente:
Python: class )bjetoE(object): de+ ,,init,,(sel+7 objetoa-9one7 objetob-9one7

138 - Eugenia Bahit - Teora sintctico-gramatical de objetos


objetoc-9one): sel+.objetod,id - 0 sel+.objetoa - co pose(objetoa7 )bjetoA) sel+.objetob - co pose(objetob7 )bjetoB) sel+.objetoc - co pose(objetoc7 )bjeto6) de+ get(sel+): sql - RRRKE<E6; objetod,id7 objetoa7 objetob7 objetoc F=)3 objetod U#E=E objetod,id - :iRRR : sel+.objetod,id +ields - run,quer$(sql)&0' sel+.objetod,id - +ields&0' objetoa - )bjetoA() objetoa.objetoa,id - +ields&5' objetoa.get() sel+.objetoa - objetoa objetob - )bjetoB() objetob.objetob,id - +ields&J' objetob.get() sel+.objetob - objetob objetoc - )bjeto6() objetoc.objetoc,id - +ields&H' objetoc.get() sel+.objetoc - objetoc PHP: class )bjetoE { +unction ,,construct()bjetoA .objetoa-9*<<7 )bjetoB .objetob-9*<<7 )bjeto6 .objetoc-9*<<) { .t%is/0objetod,id - 01 .t%is/0objetoa - .objetoa1 .t%is/0objetob - .objetob1 .t%is/0objetoc - .objetoc1 } +unction get() {

Eugenia Bahit - Teora sintctico-gramatical de objetos - 139


.sql - RKE<E6; objetod,id7 objetoa7 objetob7 objetoc F=)3 objetod U#E=E objetod,id - SR .data - arra$(RiR7 R{.t%is/0objetod,id}R)1 .+ields - arra$(Robjetod,idR RobjetoaR -0 RobjetobR -0 RobjetocR -0 -0 RR7 RR7 RR7 RR)1

EB)bject::ejecutar(.sql7 .data7 .+ields)1 .t%is/0objetod,id - .+ields&'objetod,id''1 .objetoa - ne( )bjetoA()1 .objetoa/0objetoa,id - .+ields&'objetoa''1 .objetoa/0get()1 .t%is/0objetoa - .objetoa1 .objetob - ne( )bjetoB()1 .objetob/0objetob,id - .+ields&'objetob''1 .objetob/0get()1 .t%is/0objetob - .objetob1 .objetoc - ne( )bjeto6()1 .objetoc/0objetoc,id - .+ields&'objetoc''1 .objetoc/0get()1 .t%is/0objetoc - .objetoc1 } }

Hay una realidad y es que el mtodo get() del ObjetoD solo debera tener la responsabilidad de setear sus propiedades con los datos obtenidos. Sin embargo, como puede verse, se encuentra forzado a tener que crear una instancia de cada una de los objetos que lo componen, modificar su id, llamar al

140 - Eugenia Bahit - Teora sintctico-gramatical de objetos

mtodo get() de cada uno y finalmente, poder generar la composicin necesaria.

Un objeto a nivel del core, encargado de crear y retornar otros objetos, ser la solucin a este problema:
Python: class Factor$6lass(object): de+ aTe(cls7 clase7 id,value7 idna e-''): obj - clase() p - idna e i+ idna e else R:s,idR : Q obj.,,class,,.,,na e,,.lo(er() setattr(obj7 p7 id,value) obj.get() return obj

PHP: class Factor$6lass { public static +unction aTe(.cls7 .id,value7 .idna e-'') {

.p - (.idna e) S .idna e : strtolo(er(.cls) . R,idR1

.obj - ne( .cls()1 .obj/0.p - .id,value1 .obj/0get()1 return .obj1 } }

De esta forma, el seteo de las propiedades compuestas de un objeto, requerir slo de una

Eugenia Bahit - Teora sintctico-gramatical de objetos - 141

llamada esttica al mtodo make() de FactoryClass:


Python: class )bjetoE(object): de+ ,,init,,(sel+7 objetoa-9one7 objetob-9one7 objetoc-9one): sel+.objetod,id - 0 sel+.objetoa - objetoa sel+.objetob - objetob sel+.objetoc - objetoc de+ get(sel+): sql - RRRKE<E6; objetod,id7 objetoa7 objetob7 objetoc F=)3 objetod U#E=E objetod,id - :iRRR : sel+.objetod,id +ields - run,quer$(sql)&0' sel+.objetod,id - +ields&0' #e.&/o$-etoa = 4a%tory9.a##()/!aGe( :$-etoA( &ie.d#?"A) #e.&/o$-eto$ = 4a%tory9.a##()/!aGe( :$-eto;( &ie.d#?HA) #e.&/o$-eto% = 4a%tory9.a##()/!aGe( :$-eto9( &ie.d#?@A) PHP: class )bjetoE { +unction ,,construct()bjetoA .objetoa-9*<<7 )bjetoB .objetob-9*<<7 )bjeto6 .objetoc-9*<<) { .t%is/0objetod,id - 01 .t%is/0objetoa - .objetoa1 .t%is/0objetob - .objetob1 .t%is/0objetoc - .objetoc1 } +unction get() { .sql - RKE<E6; objetod,id7 objetoa7 objetob7 objetoc F=)3 objetod

142 - Eugenia Bahit - Teora sintctico-gramatical de objetos


U#E=E objetod,id - SR

.data - arra$(RiR7 R{.t%is/0objetod,id}R)1 .+ields - arra$(Robjetod,idR RobjetoaR -0 RobjetobR -0 RobjetocR -0 -0 RR7 RR7 RR7 RR)1

} }

EB)bject::ejecutar(.sql7 .data7 .+ields)1 .t%is/0objetod,id - .+ields&'objetod,id''1 $thi#1,o$-etoa = 4a%tory9.a##::!aGe( +:$-etoA+( $&ie.d#?+o$-etoa+A); $thi#1,o$-eto$ = 4a%tory9.a##::!aGe( +:$-eto;+( $&ie.d#?+o$-eto$+A); $thi#1,o$-eto% = 4a%tory9.a##::!aGe( +:$-eto9+( $&ie.d#?+o$-eto%+A);

Eugenia Bahit - Teora sintctico-gramatical de objetos - 143

Captulo XVII: Objetos colectores de instancia nica y Singleton Pattern


Uno de los errores ms graves y a la vez ms frecuente que todos los programadores solemos cometer, es disear nuestros objetos pensando en cmo stos debern mostrarse al usuario en una interfaz grfica. De all, que en una gran cantidad de oportunidades, nos encontraremos con un objeto que define un mtodo destinado a retornar una coleccin de objetos de s mismo. Pero ste, es un error garrafal! Un objeto es 1 solo objeto y no, una coleccin de objetos. Por lo tanto una coleccin de objetos es un ObjetoAColeccion compuesto de N objetos A. La coleccin de objetos A tiene varios objetos A

Python: class )bjetoA6ollection(object):

144 - Eugenia Bahit - Teora sintctico-gramatical de objetos


de+ ,,init,,(sel+): sel+.objetosa - &' PHP: class )bjetoA6ollection { +unction ,,construct() { .t%is/0objetosa - arra$()1 } }

Sin embargo, solo puede existir una -y solo unacoleccin de objetos A. Esta coleccin ser la suma de todos los objetos A existentes, y por tanto, no ser necesaria una ID de ObjetoACollection. Pero debemos asegurarnos de que esto se cumpla. Y para ello, disearemos al nuevo ObjetoCollection como un Singleton.
Singleton es un patrn de diseo. Un Singleton es un objeto de instancia nica (no puede ser instanciado ms de una vez) y para lograr esto, l -y solo l-, puede generar una instancia de s mismo.

Eugenia Bahit - Teora sintctico-gramatical de objetos - 145

Caractersticas de un Singleton colector en PHP


Slo l puede crear una instancia de s mismo. Por lo tanto, tendr un mtodo constructor privado que impida que el objeto pueda ser instanciado desde un mbito diferente a la propia clase.
class )bject6ollection { private +unction ,,construct() { .t%is/0objects - arra$()1 } }

Como solo podr tener una nica instancia, la misma se almacenar en una propiedad privada esttica:
class )bject6ollection { private static .objectcollection1 M al acenar! una instancia de sW is o private +unction ,,construct() { .t%is/0objects - arra$()1 } }

Deber contar con un mtodo de agregacin privado:

146 - Eugenia Bahit - Teora sintctico-gramatical de objetos


class )bject6ollection { private static .objectcollection1 private +unction ,,construct() { .t%is/0objects - arra$()1 } private +unction add,object()bject .object) { .t%is/0objects&' - .object1 } }

El nico mtodo pblico, ser su propio get() esttico quien antes de actuar, ser el encargado de crear una nica instancia de s mismo:
class )bject6ollection { private static .objectcollection1 private +unction ,,construct() { .t%is/0objects - arra$()1 } private +unction add,object()bject .object) { .t%is/0objects&' - .object1 } public static +unction get() { i+(e pt$(sel+::.objectcollection)) {
sel+::.objectcollection - ne( )bject6ollection()1

} } }

Finalmente, deber retornar una instancia de s mismo:

Eugenia Bahit - Teora sintctico-gramatical de objetos - 147


class )bject6ollection { private static .objectcollection1 private +unction ,,construct() { .t%is/0objects - arra$()1 } private +unction add,object()bject .object) { .t%is/0objects&' - .object1 } public static +unction get() { i+(e pt$(sel+::.objectcollection)) {
sel+::.objectcollection - ne( )bject6ollection()1

} } return sel+::.objectcollection1 }

Caractersticas de un Singleton colector en Python


Slo l puede crear una instancia de s mismo. Por lo tanto, tendr un mtodo constructor privado que impida que el objeto pueda ser instanciado desde un mbito diferente a la propia clase. En Python, no existe un mtodo constructor privado. Por lo tanto, habr que sobrescribir el mtodo __new__ heradado de object. A la vez, dicha instancia,

148 - Eugenia Bahit - Teora sintctico-gramatical de objetos

deber almacenarse en una propiedad privada:


class )bject6ollection(object): ,,objectcollection - 9one de+ ,,ne(,,(cls): i+ cls.,,objectcollection is 9one: cls.,,objectcollection - super( )bject6ollection7 cls).,,ne(,,(cls) return cls.,,objectcollection

El mtodo __new__ es un mtodo esttico invocado por Python al crear una nueva instancia de clase. Al sobrescribirlo, se debe invocar al mtodo __new__ de la superclase, utilizando super(clase_actual, cls).__new__(cls). Cada vez que el objeto colector sea llamado, el mismo objeto ser retornado (no se crearn mltiples instancias). Es decir que la sobre-escritura del mtodo __new__, ser la encargada de retornar siempre, la misma instancia.

El mtodo __init__ ser suprimido, a fin de forzar la creacin del objeto solo y nicamente dentro de la propia clase. En reemplazo del mtodo __init__ un mtodo set() privado, ser el encargado de definir las propiedades del colector:
class )bject6ollection(object): ,,objectcollection - 9one

Eugenia Bahit - Teora sintctico-gramatical de objetos - 149

de+ ,,ne(,,(cls): i+ cls.,,objectcollection is 9one: cls.,,objectcollection - super( )bject6ollection7 cls).,,ne(,,(cls) return cls.,,objectcollection de+ ,,set(sel+): sel+.,,objectcollection.objetos - &'

Deber contar con un mtodo de agregacin privado:


class )bject6ollection(object): ,,objectcollection - 9one de+ ,,ne(,,(cls): i+ cls.,,objectcollection is 9one: cls.,,objectcollection - super( )bject6ollection7 cls).,,ne(,,(cls) return cls.,,objectcollection de+ ,,set(sel+): sel+.,,objectcollection.objetos - &' de+ ,,add,objeto(sel+7 objeto): sel+.,,objectcollection.objetos.append( objeto)

El nico mtodo pblico, ser su propio get() quien antes de actuar, ser el encargado de llamar a __set():
class )bject6ollection(object):

150 - Eugenia Bahit - Teora sintctico-gramatical de objetos

,,objectcollection - 9one de+ ,,ne(,,(cls): i+ cls.,,objectcollection is 9one: cls.,,objectcollection - super( )bject6ollection7 cls).,,ne(,,(cls) return cls.,,objectcollection de+ ,,set(sel+): sel+.,,objectcollection.objetos - &' de+ ,,add,objeto(sel+7 objeto): sel+.,,objectcollection.objetos.append( objeto) de+ get(sel+): sel+.,,objectcollection.,,set()

Finalmente, deber retornar una instancia de s mismo:


class )bject6ollection(object): ,,objectcollection - 9one de+ ,,ne(,,(cls): i+ cls.,,objectcollection is 9one: cls.,,objectcollection - super( )bject6ollection7 cls).,,ne(,,(cls) return cls.,,objectcollection de+ ,,set(sel+): sel+.,,objectcollection.objetos - &' de+ ,,add,objeto(sel+7 objeto): sel+.,,objectcollection.objetos.append( objeto)

Eugenia Bahit - Teora sintctico-gramatical de objetos - 151


de+ get(sel+): sel+.,,objectcollection.,,set() return sel+.,,objectcollection

El mtodo get() del singleton colector


El mtodo get() de este singleton, realizar una consulta a la base de datos, trayendo todos los objetos de la coleccin que encuentre e iterando sobre esos resultados, almacenar cada objeto de la coleccin creado con FactoryClass:
Python: de+ get(sel+): sel+.,,objectcollection.,,set() sql - RKE<E6; objeto,id F=)3 objetoR +ields - run,quer$(sql) +or +ield in +ields: sel+.,,objectcollection.,,add,objeto( Factor$6lass(). aTe( )bjeto7 +ield&0')) return sel+.,,objectcollection PHP: public static +unction get() { i+(e pt$(sel+::.objectcollection)) {
sel+::. objectcollection - ne( )bject6ollection()1

152 - Eugenia Bahit - Teora sintctico-gramatical de objetos


.sql - RKE<E6; object,id F=)3 object U#E=E object,id 0 SR1 .data - arra$(RiR7 R0R)1 .+ields - arra$(Robject,idR -0 RR)1 EB)bject::ejecutar(.sql7 .data7 .+ields)1 +oreac%(EB)bject::.results as .arra$) { sel+::.objectcollection/0add,object( Factor$6lass:: aTe( ')bject'7 .arra$&'object,id''))1 } return sel+::.objectcollection1 }

Eugenia Bahit - Teora sintctico-gramatical de objetos - 153

Captulo XVIII: Objetos relacionales complejos (conectores lgicos relacionales)


Mis alumnos conocen a estos objetos por un nombre bastante particular, el cul hemos decidido adoptar debido a la complejidad de los mismos. Muy probablemente, cuando llegues al final del captulo, tu solo podrs imaginar qu nombre le hemos otorgado con mis alumnos, a este tipo de objetos. A lo largo del captulo y, a fin de evitar confundirnos con los objetos relacionales simples vistos anteriormente, me referir a este tipo de objetos como conectores lgicos relacionales o simplemente conectores lgicos. Un conector lgico es una especie de mezcla entre compositor de pertenencia y objeto relacional simple. Su finalidad, es la de establecer la conexin lgica existente entre N1 objetos compositores

154 - Eugenia Bahit - Teora sintctico-gramatical de objetos

reutilizables de identidad diferenciada y N2 objetos compuestos. Recientemente, Christian -uno de mis alumnos-, me trajo un caso de compositores reutilizables que requieren de un conector lgico, ampliamente mucho ms esclarecedor que el que vena utilizando como ejemplo en mis clases. Por ese motivo, me tomo la atribucin de citarlo en este libro como ejemplo. Imaginemos un sistema de gestin de eventos festivos, donde tenemos un amplio listado de invitados. Cada invitado puede asistir a diferentes eventos, lo que significa que los distintos eventos, pueden compartir los mismos invitados. Al mismo tiempo, cada evento tiene un gran nmero de invitados. Si los invitados pueden asistir a diferentes eventos, descartamos estar en presencia de compositores de pertenencia. Y al estar Evento compuesto por varios invitados, pero cada uno de ellos, de identidad nica, descartamos estar en presencia de un compositor reutilizable cuya relacin, requiera ser establecida por un objeto relacional multiplicador. Tenemos en consecuencia una relacin de N compositores a N compuestos. Cmo haremos

Eugenia Bahit - Teora sintctico-gramatical de objetos - 155

para establecer la relacin entre ellos? Es aqu que surge la necesidad de contar con un conector lgico relacional. Propiedades del conector lgico El objeto conector lgico, contar entonces, con al menos tres propiedades: 1. Su propiedad objeto_id 2. Objeto compuesto 3. Una coleccin de compositores cuyo valor, se obtendr de la coleccin provista por el objeto compuesto
Python: class DnvitadoEvento(object): de+ ,,init,,(sel+7 evento): sel+.invitadoevento,id - 0 sel+.evento - co pose(evento7 Evento) sel+.invitados - evento.invitados PHP: class DnvitadoEvento { +unction ,,construct(Evento .evento) { .t%is/0invitadoevento,id - 01 .t%is/0evento - .evento1 .t%is/0invitados - .evento/0invitados1 }

156 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Mapeo relacional Cuando un conector lgico debe ser mapeado, se tendr en consideracin todo lo visto en el Captulo VII. Pero cmo se mapean las colecciones? La propiedad colectora de este objeto, a diferencia de las vistas hasta ahora, no posee como valor asociado un array ni una lista vaca. Por el contrario, desde su inicializacin, adoptar como valor una coleccin de objetos. El conector lgico deber iterar sobre la propiedad colectora y por tal motivo, dichas propiedades son mapeadas como si se tratara del objeto compositor en un relacional simple. Obteniendo por tanto (si continuamos con el mismo ejemplo) un campo invitado que ser clave fornea con efecto en cascada. Por consiguiente, la consulta SQL generada, lucir como la siguiente:
6=EA;E ;AB<E invitadoevento ( invitadoevento,id D9;(55) 9); 9*<< A*;),D96=E3E9; "=D3A=F,GEF 7 evento D9;(55) 7 D9EEL(evento)

Eugenia Bahit - Teora sintctico-gramatical de objetos - 157


7 F)=EDC9 GEF (evento) =EFE=E96EK evento (evento,id) )9 EE<E;E 6AK6AEE 7 invitado D9;(55) 7 D9EEL(invitado) 7 F)=EDC9 GEF (invitado) =EFE=E96EK invitado (invitado,id) )9 EE<E;E 6AK6AEE ) E9CD9E- DnnoEB1

Los mtodos save(), get() y destroy() del conector lgico


El conector lgico contar con tres mtodos, similares en concepto a los mtodos estndar ya conocidos, pero diferentes en su algortmica. El mtodo save() El mtodo save() del objeto conector es quien contar con el algoritmo ms complejo de todos los mtodos. A diferencia de los mtodos save() estndar, stos solo debern guardar nuevas relaciones, puesto que a nivel conceptual no existe la posibilidad de modificar una relacin existente (en este tipo de objetos), sino que la misma debe ser destruida y

158 - Eugenia Bahit - Teora sintctico-gramatical de objetos

reemplazada por una nueva. Por tal motivo, siempre antes de ejecutar su propio algoritmo, llamarn al mtodo de destruccin. Ten en cuenta que la relacin final resultante, siempre ser entre 1 compositor y 1 compuesto. Dicho mtodo deber generar de forma dinmica, tanto la consulta SQL de insercin como los valores a ser insertados, ya que deber guardar cada par compuesto-compositor como un nico registro y no queremos conectarnos y desconectarnos a la base de datos, por cada par compuesto-compositor a insertar. Para lograrlo, deber iterar sobre la propiedad colectora:
Python: de+ save(sel+): sel+.destro$() sql - RRRD9KE=; D9;) invitadoevento (evento7 invitado)RRR data - &' t pvar - 0 +or invitado in sel+.invitados: sql >- R7 R i+ t pvar 0 0 else R VA<*EK R sql >- R(:i7 :i)R data.append(sel+.evento.evento,id) data.append(invitado.invitado,id) t pvar >- 5 run,quer$(sql : tuple(data))

Eugenia Bahit - Teora sintctico-gramatical de objetos - 159

PHP: +unction save() { .t%is/0destro$()1 .sql - RD9KE=; D9;) invitadoevento (evento7 invitado)R1 .data - arra$(RR)1 .t pvar - 01 +oreac%(.t%is/0invitados as .invitado) { .sql .- (.t pvar 0 0) S R7 R : R VA<*EK R1 .sql .- R(S7 S)R1 .data&0'.- RiiR1 .data&' - R{.t%is/0evento/0evento,id}R1 .data&' - R{.invitado/0invitado,id}R1 .t pvar>>1 } EB)bject::ejecutar(.sql7 .data)1 }

El mtodo destroy() El mtodo destroy() se encargar de destruir de forma masiva, todas las relaciones existentes con el compuesto:
Python: de+ destro$(): sql - RRREE<E;E F=)3 invitadoevento U#E=E evento - :iR : Q sel+.evento.evento,id run,quer$(sql)

160 - Eugenia Bahit - Teora sintctico-gramatical de objetos


PHP: +unction destro$() { .sql - REE<E;E F=)3 invitadoevento U#E=E evento - SR1 .data - arra$(RiR7 R{.t%is/0evento/0evento,id}R)1 EB)bject::ejecutar(.sql7 .data)1 }

El mtodo get() El mtodo get() del conector lgico, realizar la consulta de forma similar a un mtodo get auxiliar. Sin embargo, su comportamiento, ser distinto. Con los resultados obtenidos de la consulta, deber crear los compositores -al igual que el mtodo get() de un objeto relacional simple- de forma iterativa y agregarlos al compuesto:
Python: de+ get,relacion(sel+): sql - RRRKE<E6; invitado F=)3 invitadoevento U#E=E evento - :iRRR : Q sel+.evento.evento,id results - run,quer$(sql) +or +ield in results: invitado - Dnvitado() invitado.invitado,id - +ield&0' invitado.get() sel+.evento.add,invitado(invitado)

Eugenia Bahit - Teora sintctico-gramatical de objetos - 161


PHP: +unction get() { .sql - RKE<E6; invitado F=)3 invitadoevento U#E=E evento - SR1 .data - arra$(RiR7 R{.t%is/0evento/0evento,id}R)1 .+ields - arra$(RinvitadoR -0 RR)1 .results - EB)bject::ejecutar(.sql7 .data7 .+ields)1 +oreac%(.results as .+ield) { .invitado - ne( Dnvitado()1 .invitado/0invitado,id - .+ield&'invitado''1 .invitado/0get()1 .t%is/0evento/0add,invitado(.invitado)1 } }

162 - Eugenia Bahit - Teora sintctico-gramatical de objetos

Potrebbero piacerti anche