« [XP] Propiedad colectiva del cÛdigo, tests, y coding standards | Inicio | Un ejemplo del PatrÛn Prototype ( la versiÛn Java ) »

Un ejemplo del PatrÛn Prototype

El Profesor Dispar es un cientÌfico espaÒol que est· planeando dominar el mundo. øQuieres conocer los problemas con los que se ha encontrado, y cÛmo los ha resuelto implementando el patrÛn prototype?

El Profesor Dispar era un respetado cientÌfico espaÒol, que se convirtiÛ en un genio del mal por sus malas condiciones laborales ( y por que su novia se la pegaba con otro, la verdad ). Ahora, su ˙nico deseo es llevar a cabo su malvado plan para °°°dominar el mundo!!!

professorCoupling.jpg
El Profesor Dispar

AsÌ que, en sus delirios paranoides, ha construido una m·quina para clonar. Una m·quina para clonar muy especial, porque puede ser programada en ActionScript

El plan del Profesor Dispar es clonar todas las ovejas que pueda, para asÌ controlar la economÌa mundial y dominar el mundo ( la verdad, no entiendo el porquÈ de ese plan, pero recuerda, aunque estÈ loco, es un genio! ).

sheep.jpg
Una oveja ( vista frontal )

La m·quina para clonar es algo asÌ:

class CloningMachine { function CloningMachine( ) { } public function buildClone( ): Sheep { return new Sheep( ); } public function buildManyClones( cloneNum: Number ) { var returnArray: Array = new Array( ); for( var k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

Y la oveja:

class Sheep { function Sheep( ) { trace( "beeeee. Soy una nueva oveja reciÈn creada" ); } }

Tras inundar el mundo con ovejas clonadas ( es su malvado plan, no el mÌo ), el Profesor Dispar se dio cuenta que clonar unos cuantos miles de vacas le ayudarÌa a dominar el mundo m·s r·pido. Pero su m·quina para clonar no fue construida para clonar vacas, sino para clonar ovejas

cow.jpg
Una vaca ( vista lateral )

AsÌ que el malvado genio del mal decide aÒadir a su m·quina la funcionalidad necesaria para clonar vacas. øCÛmo?. Mira:

class CloningMachine { function CloningMachine( ) { } public function buildClone( ): Sheep { return new Sheep( ); } public function buildCowClone( ): Cow { return new Cow( ); } public function buildManyClones( cloneNum: Number ) { var returnArray: Array = new Array( ); for( var k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

El Profesor Dispar est· loco, pero no es idiota. Por tanto, enseguida se da cuenta de que puede encontrarse con problemas si quiere clonar otros animales, como, por ejemplo, p·jaros, o incluso humanos

Tras pensar cuidadosamente sobre su problema, hace otro intento:

class CloningMachine { function CloningMachine( ) { } public function buildClone( type: String ): Object { if( type == "sheep" ) { return new Sheep( ); } else if ( type == "cow" ) { return new Cow( ); } } public function buildManyClones( cloneNum: Number ) { var returnArray: Array = new Array( ); for( var k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( ); } return returnArray; } }

Tras varios minutos de las tÌpicas risas histÈricas, el Profesor Dispar empieza a pensar en la forma en que ha implementado su m·quina para clonar, y enseguida encuentra varios puntos dÈbiles.

En primer lugar, el mÈtodo buildClone devuelve un Object, no una oveja ( Sheep ) o una vaca ( Cow ). øPor quÈ?. Porque este mÈtodo no sabe lo que va a crear a priori. El Profesor Dispar ( recuerda, est· loco, pero no es idiota ) barrunta que Èsta no es la mejor soluciÛn posible

TambiÈn se da cuenta que si en alg˙n momento quisiera clonar alg˙n otro animal, deberÌa cambiar de nuevo su m·quina para clonar. Y eso no hace su m·quina f·cil de mantener.

Pero entonces, una idea empieza a abrirse paso en su malvado cerebro. A˙n no sabe exactamente cÛmo hacerlo, pero øquÈ pasarÌa si pudiera darle algo a la m·quina( una oveja, una cabra, un humano, o una piedra ) y pedirle a la misma que le devolviera 500 copias del mismo?. °°Brillante!! ( m·s risas histÈricas ). AsÌ, no tendrÌa que preocuparse de cÛmo funciona la m·quina, simplemente la m·quina le devolverÌa tantas copias como necesitara del original que Èl le facilitara.

Entonces, el Profesor Dispar recuerda sus tiempos de estudiante, cuando leyÛ un libro llamado "Patrones de diseÒo: Elementos de software orientado a objetos reutilizable" ( el GoF ), y aquella cosa que se llamaba el "patrÛn prototype"

Por tanto, la m·quina para clonar no puede saber quÈ tiene que clonar ni cÛmo debe clonarlo. …sa ( la creaciÛn de la copia ), ser· una responsabilidad de cada uno de los animales ( o cosas a clonar ). La m·quina de clonar, simplemente recibir· un animal, y le dir· a Èste que produzca tantas copias de sÌ mismo como se necesiten, y luego se las devolver· al Profesor Dispar.

Por tanto ( recuerda, no hay clases abstractas en ActionScript ), todos los animales deber·n implementar un interfaz, que contiene sÛlo un mÈtodo:

interface ICloneable { public function clone( ): ICloneable; }

[ Nota ]. SerÌa posible que todos los animales extendieran de una clase base, y que por tanto el tipo que devuelve el mÈtodo clone( ) fuera esa clase base. Pero yo voy a continuar mi ejemplo con este interfaz, porque de esta forma el diseÒo es mucho m·s flexible.

Ese mÈtodo clone( ) ser· el encargado de crear y devolver una nueva copia de cada animal que lo implemente.

La oveja ahora ser·:

class Sheep implements ICloneable { function Sheep( ) { trace( "Hola, soy Dolly, me van a clonar en un plis" ); } public function clone( ): ICloneable { trace( "Beeee, soy un nuevo clon de Dolly" ); return new Sheep( ); } public function toString( ): String { return "{ Hola, soy una oveja clonada. }"; } }

Y aquÌ est· la vaca:

class Cow implements ICloneable { function Cow( initFlag: Boolean ) { trace( "Muuuu, soy una vaca, a mÌ tambiÈn me van a clonar en un momento" ); if( initFlag == true ) { init( ); } } private function init( ) { trace( "Soy una vaca inicializada, signifique eso lo que signifique" ); } public function clone( ): ICloneable { return new Cow( true ); } public function toString( ): String { return "{ sÌ, soy una vaca clonada, muuuuuu }"; } }

Ahora, el Profesor Dispar tan sÛlo tendr· que hacer algo asÌ:

var cMachine: CloningMachine = new CloningMachine( ); cMachine.buildClone( new Sheep( ) ); cMachine.buildClone( new Cow( ) ); trace( "--" ); var sheepClones: Array = cMachine.buildManyClones( 5, new Sheep( ) ); var cowClones: Array = cMachine.buildManyClones( 5, new Cow( ) ); trace( "--" ); trace( "sheepClones " + sheepClones ); trace( "cowClones " + cowClones );

Por tanto, la m·quina para clonar podr· recibir cualquier animal ( una instancia de una clase ), y mandarla que cree todas las copias de sÌ misma que se necesiten.

class CloningMachine { function CloningMachine( ) { } public function buildClone( template: ICloneable ): ICloneable { return template.clone( ); } public function buildManyClones( clonesNum: Number, template: ICloneable ): Array { var returnArray: Array = new Array( ); for( var k=0; k< clonesNum; k++ ) { returnArray[ k ] = template.clone( ); } return returnArray; } }

Ahora, el Profesor Dispar puede seguir inundando el mundo con los clones creados por su m·quina ( m·s risas histÈricas ), sabiendo que puede crear copias de todo lo que le dÈ la gana, porque le ha dado a su m·quina el "don" de crear objetos sin saber de quÈ tipo deben ser.

Pero el Profesor es un hombre de ciencia, y en su af·n por alcanzar el conocimiento absoluto, sigue leyendo documentaciÛn sobre el patrÛn prototype, y entonces se da cuenta de que tambiÈn ha separado el cÛdigo que crea los objetos del cÛdigo que maneja los detalles de la creaciÛn de nuevos objetos ( eso queire decir que, por ejemplo, si quiere crear 1000 ovejas rojas hoy, y 1000 ovejas azules maÒana, tan sÛlo debe aÒadir una m·quina para pintar animales al lado de la m·quina para clonar, y esa m·quina de pintar se encargar· de darlas color, sin saber cÛmo ni donde se han cread esos animales ).

Gracias a Celia Carracedo, hoy concretamente por los dibujos de la oveja, la vaca, y el malvado Profesor Dispar.

TrackBack

URL del Trackback para esta entrada:
http://ctarda.dreamhosters.com/cgi-bin/mt-tb.cgi/675

Comentarios

xDDDD

una forma de explicar muy amena ;)

Pues sÌ que est· bien explicado. Bueno me he enterado de poco, pero sin el ejemplo del profe me no hubiese podido cogerlo por ning˙n lado.

Excelente!
Muy original la forma de explicarlo :)
Como siempre, nunca faltan los animalitos a la hora de explicar la teorÌa de objetos

exelente =)

Excelente! quedamos a la espera de los dem·s patrones!

Extraordinario, muchas gracias.

Extraordinario. Muchas gracias.

Excelente ilustraciÛn del patrÛn. Muchas gracias porque fue de mucha ayuda.