Académique Documents
Professionnel Documents
Culture Documents
Unidad 1: Introduccin.
1.1 Conceptos relacionados con los paradigmas de diseo de software.
Para resolver cualquier tipo de problema es necesario realizar una planeacin detallada que permita generar acuerdos entre los distintos participantes en el proyecto de resolucin. El proceso de diseo se realiza en algn momento entre la fase en que planteamos los requerimientos de nuestro sistema y la fase en la que se va construyendo un programa que cumpla con dichos requerimientos. A quin no le ha pasado que realiza una planeacin de requerimientos, slo para darse cuenta durante la codificacin que no puede realizar lo que dicha planeacin solicita? A pesar que esta situacin no siempre puede evitarse durante la fase de diseo se intenta determinar cmo se cumplirn los requerimientos planteados, cmo se puede implementar una solucin de forma eficiente y cmo hacer un sistema que resulte fcil de extender en un futuro. El diseo se apoya en mtodos denominados reglas de forma y en notaciones estandarizadas que permiten al diseador comunicar sus ideas a los encargados de la implementacin. La tarea de desarrollar un programa requiere del programador distribuir su atencin en mltiples aspectos del problema y de las formas de solucin disponibles. Pero esta complejidad se eleva con creces cuando se debe disear un sistema interrelacionado, ya que se requiere de un mayor nivel de abstraccin para modelar el comportamiento de todas sus partes. La idea de diseo se fundamenta en dos caractersticas inherentes al ser humano: el uso de herramientas y la capacidad de comunicarse. Sin importar si la herramienta que estamos manejando es un hacha de piedra o un compilador, podemos definir una herramienta como artefactos que nos permiten agilizar el trabajo. Pero para poder operar una herramienta de manera eficiente, podemos optar por uno de dos caminos: el mtodo de prueba y error, o bien aprender a manejar las herramientas siguiendo las instrucciones de un experto. Para aprender de quien ya sabe hacer las cosas, es necesaria la comunicacin. Pero adems, esta comunicacin debe tener una estructura que nos permita comprender exactamente la idea de la persona que nos la est transmitiendo, y ah es donde entra al rescate el diseo. Disear es plasmar el conocimiento de un experto en una representacin estandarizada que permita que los estudiantes de una materia sean capaces de reutilizar dicho conocimiento de una forma inmediata y eficaz. Este proceso se considera parte importante en la transicin entre una habilidad y una disciplina de ingeniera, pues permite utilizar el conocimiento de mltiples expertos sin necesidad de reinventarlos. La creacin de artefactos cuyo funcionamiento libre de errores resulta crucial (tales como aviones, puentes y edificios) justifica plenamente la necesidad de un diseo que respalde su desarrollo. Sin embargo, el diseo juega un papel importante en el desarrollo de artefactos en los que la seguridad no resulta crtica. En estos casos, por lo general el diseo contribuye a que la experiencia de uso de dichos artefactos sea placentera al usuario. Por supuesto, el puro diseo no es el factor ms importante para la creacin de artefactos. Tambin importa el proceso de fabricacin. Un proceso de fabricacin deficiente puede convertir en basura un maravilloso diseo. Sin embargo, la importancia del diseo radica en que no existe proceso de fabricacin, por magnfico que sea, que permita corregir un error de diseo.
Pero la programacin siempre ha sido un proceso de conocimiento y trabajo intensos. Actualmente, el incremento de la demanda de aplicaciones hace necesario mejorar el rendimiento, la seguridad y la robustez del software. Paradigma (palabra griega que significa "modelo" o "ejemplo") se usa comunmente para referirse a una categora de entidades que comparten caractersticas comunes. Thomas Kuhn define la nocin de paradigma en el proceso cientfico como una visin cientfica del mundo y la estructura de sus modelos y teoras, que afectan esa visin. Kuhn considera que los paradigmas emergen como resultado de procesos sociales en los que la gente desarrolla nuevas ideas y crea principios y prcticas que envuelven dichas ideas. El desarrollo de software es un proceso social, puesto que comnmente es el resultado de un esfuerzo de grupo, y porque cada aplicacin nueva es una creacin nica por derecho propio, siendo casi imposible que dos equipos de programadores generen un par de programas completamente iguales en cuanto a codificacin y estructura.
Cuando se disea software, se debe disear un modelo de programacin. El modelo de programacin captura las interfaces entre los elementos del software as como la funcionalidad de los elementos. Sin embargo, dicha funcionalidad se representa a un nivel ms alto para que el cliente pueda concentrarse en sus requerimientos y no en cmo programar cada elemento. Un buen modelo de programacin describe su funcionalidad de tal forma que coincida con la forma en que el desarrollador desea que funcione el programa. Un desarrollador de software no suele iniciar su modelo desde cero. Ms bien suele buscar la implementacin que mejor se acomode al problema que est tratando de resolver. Los patrones de diseo se definen como soluciones para estos problemas recurrentes en la construccin de software. Usualmente se piensa que los patrones de diseo slo son aplicables al desarrollo de grandes programas, siendo que pueden aplicarse para resolver pequeos problemas como la implementacin de estructuras de datos o algoritmos sencillos. Los patrones de diseo pueden combinarse para conformar componentes. Los componentes son elementos de software ms complejos que los patrones de diseo. Pueden estar compuestos de ms de un patrn de diseo, pero comnmente constan de un nico patrn de diseo llevado a la codificacin. Los componentes se integran en estructuras ms grandes llamadas frameworks, las cuales tienen una caracterstica especial: poseen un dominio especfico, es decir, su propsito es implementar una estructura para solucionar un tipo de problemas de una clase especfica. Es decir, desarrollamos un framework con el propsito de implementar una estructura de soluciones a una clase de problemas dentro de un dominio particular. La mayora de los frameworks contienen una o ms arquitecturas de software. Hay una progresin natural en la complejidad entre paradigmas de programacin hasta los frameworks. Las capas superiores se construyen usando los elementos por debajo de ellos en la jerarqua.
El trmino "programacin concurrente" suele referirse al tipo de programacin requerida para llevar a cabo actividades simultneas en una aplicacin de software, es decir, es el conjunto de tcnicas y herramientas utilizadas en las actividades de programacin que comparten informacin dinmicamente con otros programas. Sin embargo, la programacin concurrente puede referirse a una variedad de modelos de programacin. La concurrencia puede ser aparente o real. Los programas concurrentes pueden ejecutarse en un solo procesador, mltiples procesadores, procesadores paralelos o procesadores distribuidos. Una tarea grande puede ser realizada serialmente, un paso tras de otro, o ser descompuesta en tareas ms pequeas que se realicen simultneamente. La concurrencia se caracteriza por: * Descomponer la tarea principal en tareas ms pequeas. * Asignar las pequeas tareas a mltiples hilos para trabajar sobre ellas de manera simultnea. * Coordinar la ejecucin de los hilos. * Limitar la divisin de las tareas para evitar que tome ms tiempo resolver la tarea en paralelo que de manera secuencial. Una forma especial de programacin concurrente es la programacin paralela en la cual un programa es escrito para ejecutarse en mltiples procesadores fsicos. Escribir programas paralelos es mucho ms difcil que escribir programas secuenciales puesto que requiere administrar adecuadamente el flujo de control entre los diferentes hilos de ejecucin, controlar el almacenaje y acceso de los datos globales y sincronizar los eventos para conseguir una ejecucin del programa determinstica sin perder la ventaja de aceleracin del paralelismo. Programas transformacionales y reactivos Otra manera de ver la clasificacin de programas es considerando cmo manejan los datos. La mayora de los problemas pueden ser divididos en transformacionales y reactivos. Un programa transformacional es aqul en el cual la entrada de datos es leda, procesada, y los resultados son entregados. Pueden ser expresados como funciones de M entradas que entregan N salidas. Los programas reactivos interactan con su ambiente mientras se ejecutan. Por lo general un programa reactivo no puede especificarse como funcin. Generalmente no puede recibir nuevas entradas mientras se ejecuta, por lo que su comportamiento depende de su estado actual y del valor de sus entradas. Estos programas se ejemplifican mediante el manejo de eventos. Los programas transformacionales son un tipo especializado de los programas reactivos. Paradigmas de lenguajes de programacin Los lenguajes de programacin pueden clasificarse en dos categoras: imperativos y declarativos. Los primeros permiten a los programadores expresar algoritmos para resolver problemas, pero no le muestran como es realizado el proceso. Los lenguajes declarativos pueden dividirse a su vez en lenguajes funcionales y lgicos. Este tipo de lenguajes ofrecen tres ventajas distintas: son inherentemente de alto nivel ya que especifican la lgica de los sucesos y no la manera en que deben realizarse; los datos pueden representarse como reglas, o bien como hechos explcitos; y adems son muy tiles para realizar prototipos de estructuras de datos y cdigo rpido para expresar ideas complejas.
Las herramientas CASE se utilizan junto con el modelo de procesos que se haya elegido. Si se dispone de un conjunto completo de herramientas, se utilizarn durante la mayora de los pasos del proceso. Es importante estar consciente de que las herramientas CASE no sustituyen las prcticas de ingeniera de software, slo las complementan. En el caso de herramientas CASE integradas, para que las herramientas se comuniquen entre s, es necesario que reciban soporte de un marco de integracin, constituido por un grupo de programas especializados que se encargan de dar coherencia a la informacin aportada por cada herramienta. Por otra parte, necesita servicios de portabilidad para migrar entre diferentes plataformas sin requerir de adaptaciones significativas. Sin embargo, no todas las herramientas CASE se desarrollan con este tipo de soporte. Las herramientas CASE se pueden clasificar por su funcin, por los usuarios objetivos, por el paso de diseo en el que se utiliza, por la arquitectura del entorno que le presta su apoyo a la herramienta, o incluso por su origen o su coste. Una clasificacin por su funcin sera: Herramientas de ingeniera de procesos de negocio, modelado de procesos y herramientas de gestin, herramientas de planificacin de proyectos, herramientas de gestin de proyectos, herramientas de seguimiento de requisitos, herramientas de mtricas y de gestin, herramientas de anlisis de riesgos, herramientas de documentacin, herramientas de gestin de configuracin de software, herramientas de software de sistemas, herramientas de control de calidad, herramientas de gestin de bases de datos, herramientas de anlisis y diseo, herramientas de construccin de prototipos y simulacin, herramientas de desarrollo y diseo de interfaz, herramientas de integracin y pruebas, herramientas de anlisis esttico, herramientas de anlisis dinmico, herramientas de programacin, herramientas de desarrollo web, herramientas de reingeniera, herramientas de gestin de pruebas, herramientas cliente / servidor, etc.
class FabricaBicicletas { public function createRueda() { return new Rueda(); } public function createMarco() { return new Marco(); } public function createBicicleta($rdelantera, $rtrasera, $marco) { return new Bicicleta($rdelantera, $rtrasera, $marco); } //Creacin de una bicicleta completa sin pase de argumentos: public function BicicletaCompleta() { Rueda $delantera = createRueda(); Rueda $trasera = createRueda(); Marco $marco = createMarco(); return createBicicleta($delantera, $trasera, $marco); } } class FabricaBicicletasCarrera { public function createRueda() { return new Rueda1700c(); } public function createMarco() { return new MarcoCarreras(); } public function createBicicleta($rdelantera, $rtrasera, $marco) { return new BicicletaCarreras($rdelantera, $rtrasera, $marco); } } class FabricaBicicletasMont { public function createRueda() { return new Rueda126in(); } public function createMarco() { return new MarcoMont(); } public function createBicicleta($rdelantera, $rtrasera, $marco) { return new BicicletaMont($rdelantera, $rtrasera, $marco); } }
class Carrera { var $bfabrica; public function __construct() { $this->bfabrica = new FabricaBicicletas(); } public function creaCarrera() { $bicicleta1 = $this->bfabrica->BicicletaCompleta(); $bicicleta2 = $this->bfabrica->BicicletaCompleta(); } } class TourDeFrance extends Carrera { public function __construct() { $this->bfabrica = new FabricaBicicletasCarrera(); } } class CycloCross extends Carrera { public function __construct() { $this->bfabrica = new FabricaBicicletasMont(); } } En esta versin, el tipo de bicicleta est definido dentro de la clase de la carrera. Si cambiamos el constructor de las clases, podemos pasar el tipo de bicicleta a utilizarse como un parmetro de constructor: class Carrera { var $bfabrica; public function __construct($bfabrica) { $this->bfabrica = $bfabrica; } public function creaCarrera() { $bicicleta1 = $this->bfabrica->BicicletaCompleta(); $bicicleta2 = $this->bfabrica->BicicletaCompleta(); } } class TourDeFrance extends Carrera { public function __construct($bfabrica) { $this->bfabrica = $bfabrica; } }
class CycloCross extends Carrera { public function __construct($bfabrica) { $this->bfabrica = $bfabrica; } } De esta manera, la creacin de las instancias de clase pueden controlar tanto el tipo de carrera como las bicicletas que se usarn, por ejemplo, haciendo su llamada de la forma: new TourDeFrance(new FabricasBicicletasCarrera()); Muchos de los patrones de diseo buscan evitar la prdida de acoplamiento. Para entender este concepto, suele echarse mano de una situacin a la que los desarrolladores se enfrentan comunmente cuando disean sistemas grandes. Cuando dentro de un sistema de tales caractersticas deciden cambiar un fragmento de cdigo, observan asombrados cmo otras partes del sistema comienzan a fallar. Segn crean, esas partes no tenan relacin alguna con la parte corregida. Sin embargo, generalmente las clases de una parte del sistema se apoyan fuertemente en comportamientos y estructuras de otras clases del sistema, por lo cual suele necesitarse un conjunto de patrones que permitan la intercomunicacin de clases, pero sin relacionarlas a tal grado que dichas clases se bloqueen entre s. En grandes sistemas, la mayor parte del cdigo se apoya en unas cuantas clases bsicas. Las dificultades se presentan cuando se tiene que cambiar una de dichas clases. Es en situaciones como sta donde el patrn de diseo de fbrica encuentra su utilidad, ya que su estructura permite la creacin de objetos de manera automtica. Si en algn momento el desarrollador decide cambiar el tipo de objetos creados, basta con cambiar la fbrica, y puesto que el cdigo usa la fbrica para trabajar, la adaptacin es automtica.
Patrn Singleton.
Algunos recursos de aplicacin son exclusivos en el sentido de que dentro de la aplicacin debe haber uno y slo un objeto de este tipo de recurso. Por ejemplo, la conexin a una base de datos por medio del manejador de base de datos es exclusiva, pero dicha conexin puede querer compartirse para evitar repetir la apertura y cierre de dicha conexin entre mtodos de la clase de pgina. El patrn singleton cubre esta necesidad. Un objeto es un singleton si la aplicacin puede incluir uno y slo uno de dichos objetos en un momento dado. El siguiente cdigo muestra un objeto singleton para conexin a base de datos: <?php private $_observers = array(); public function addCustomer( $name ) { foreach( $this->_observers as $obs ) $obs->onChanged( $this, $name ); } public function addObserver( $observer ) { $this->_observers []= $observer; } } class UserListLogger implements IObserver { public function onChanged( $sender, $args ) { echo( "'$args' agregado a la lista de usuarios.\n" ); } }
$ul = new UserList(); $ul->addObserver( new UserListLogger() ); $ul->addCustomer( "Jack" ); ?> Este cdigo define cuatro elementos: dos interfases y dos clases. La interfaz IObservable define un objeto que puede observarse, y la clase UserList implementa dicha interfaz para registrarse como observable. La interfaz IObserver define cmo ser un observador, implementndose en la clase UserListLogger. El cdigo de prueba crea un UserList y le agrega el observador UserListLogger. Luego se agrega un cliente, y el objeto UserListLogger es avisado del cambio. Es importante darse cuenta que el objeto UserList no sabe lo que el objeto observador est haciendo. Puede haber ms de un objeto observador haciendo otras cosas. Por ejemplo, puede haber otro observador cuyo objetivo sea enviar un mensaje al nuevo usuario, dndole la bienvenida al sistema. As, el objeto observable se mantiene cumpliendo su trabajo de mantener la lista de usuarios y enviar mensajes a los observadores cuando sta cambie.
Patrn estrategia.
En este patrn, los algoritmos son extrados de clases complejas de tal forma que pueden ser fcilmente reemplazados. Por ejemplo, el patrn estrategia es una opcin si se quiere cambiar la forma en que las pginas son calificadas por un motor de bsqueda. Pinsese en un motor de bsqueda en varias partes: una que itera a travs de las pginas, una que califica cada pgina, y otra que ordena los resultados obtenidos de la calificacin. En un ejemplo complejo, todas estas partes entraran en la misma clase. Utilizando el patrn estrategia, puede tomarse la parte de calificacin y crear con ella una nueva clase de tal manera que pueda cambiarse la forma en que las pginas son calificadas sin interferir con el resto del cdigo del motor de bsqueda. <?php interface IStrategy { function filter( $record ); } class FindAfterStrategy implements IStrategy { private $_name; public function __construct( $name ) { $this->_name = $name; }
public function filter( $record ) { return strcmp( $this->_name, $record ) <= 0; } } class RandomStrategy implements IStrategy { public function filter( $record ) { return rand( 0, 1 ) >= 0.5; } } class UserList { private $_list = array(); public function __construct( $names ) { if ( $names != null ) { foreach( $names as $name ) { $this->_list []= $name; } } } public function add( $name ) { $this->_list []= $name; } public function find( $filter ) { $recs = array(); foreach( $this->_list as $user ) { if ( $filter->filter( $user ) ) $recs []= $user; } return $recs; } } $ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) ); $f1 = $ul->find( new FindAfterStrategy( "J" ) ); print_r( $f1 ); $f2 = $ul->find( new RandomStrategy() ); print_r( $f2 ); ?> La clase UserList se encarga de contener un arreglo de nombres, y de implementar un mtodo find que usa una de varias estrategias para seleccionar un subconjunto de dichos nombres. Esas estrategias estn definidas por la interfaz IStrategy que tiene dos implementaciones: una selecciona a los usuarios aleatoriamente y la otra selecciona todos los nombres despus de un nombre especificado. El cdigo de prueba ejecuta las dos estrategias tomando la misma lista de usuarios y muestra los resultados. En el primer caso, la estrategia busca un nombre ordenado despus de la J. La segunda estrategia selecciona los nombres aleatoriamente, por lo que mostrar distintos resultados cada vez. El patrn
estrategia se usa para sistemas de manejo de datos complejos o para sistemas de procesamiento de datos que necesitan mucha flexibilidad en la forma en que los datos son filtrados, buscados o procesados.
Patrn adaptador.
Se utiliza para convertir un objeto de un tipo a otro. Comnmente, los desarrolladores realizan una reasignacin de tipos entre objetos por medio de un mtodo que realiza todas las asignaciones de datos necesarias: class AddressDisplay { private $addressType; private $addressText; public function setAddressType($addressType) { $this->addressType = $addressType; } public function getAddressType() { return $this->addressType; } public function setAddressText($addressText) { $this->addressText = $addressText; } public function getAddressText() { return $this->addressText; } } class EmailAddress { private $emailAddress; public function getEmailAddress() { return $this->emailAddress; } public function setEmailAddress($address) { $this->emailAddress = $address; } } /* Crea el objeto EmailAddress */ $emailAddress = new EmailAddress(); /* Llena el objeto EmailAddress */ $emailAddress->setEmailAddress("correo@servidor.com"); /* Crea el objeto AddressDisplay */ $address = new AddressDisplay(); /* Cdigo de asignacin de valores de un objeto al otro */ $address->setAddressType("email"); $address->setAddressText($emailAddress->getEmailAddress());
El patrn adaptador proporciona una forma de reutilizar este cdigo de asignacin de valores en otros lugares, adems de encapsular el cdigo de asignacin, con lo cual, si la forma en que se realiza la conversin de un objeto en otro cambia, slo hay que alterar el patrn. class EmailAddressDisplayAdapter extends AddressDisplay { public function __construct($emailAddr) { $this->setAddressType("email"); $this->setAddressText($emailAddr->getEmailAddress()); } } $email = new EmailAddress(); $email->setEmailAddress("correo@servidor.com"); $address = new EmailAddressDisplayAdapter($email); echo($address->getAddressType() . "\n") ; echo($address->getAddressText());
Patrn iterador.
Este patrn provee una forma de encapsular ciclos sobre una coleccin de arreglos de objetos. Es particularmente til si se desea iterar a travs de diferentes tipos de objetos. Regresando al ejemplo anterior utilizado para el patrn adaptador, podemos crear una clase que se encargue de guardar un arreglo de direcciones de email y que las vaya entregando conforme se invoca su mtodo next(). El iterador puede controlarse mediante el mtodo hasNext() que indica si quedan elementos por extraerse. Para reinicializar el contador, se usa el mtodo reset(). interface AddressIterator { function reset(); function hasNext(); function next(); } class PersonAddressIterator implements AddressIterator { private $emailAddresses; private $position; public function __construct($emailAddresses) { $this->emailAddresses = $emailAddresses; $this->position = 0; } public function reset() { $this->position = 0; }
public function hasNext() { if ($this->position >= count($this->emailAddresses) || $this->emailAddresses[$this->position] == null) return false; else return true; } public function next() { $item = $this->emailAddresses[$this->position]; $this->position = $this->position + 1; return $item; } }
2.3 Interfaz.
Un dominio amplio para el desarrollo de patrones es el comprendido por las interfaces humano computadora. Aunque la literatura acadmica y tcnica est repleta de buena informacin sobre diseo de interfaces de usuario, y se habla mucho sobre la manipulacin directa, la retroalimentacin inmediata, el uso adecuado del sonido, y la forma ms adecuada de presentar mensajes de error, los diseadores novatos difcilmente recordarn todos estos consejos para aplicarlos de la manera ms adecuada, por lo cual es conveniente usar patrones de diseo especiales para interfaces. Una de las primeras formas de describir los patrones de interfaz es mediante el uso de guas de estilo, que indican cmo disear interfaces de usuario para garantizar resultados similares. El problema de las guas de estilo es que su desarrollo est usualmente enlazado a sistemas operativos o herramientas de diseo muy especficos. Para que dichos patrones de diseo tengan una aplicacin ms amplia, el diseador debe aplicar los principios y tcnicas de otras guas de estilo a sus propios proyectos.
2.4 Diseo.
Despus de trabajar durante cierto tiempo con patrones de diseo, el diseador llega a notar que muchos de ellos tienen una estructura similar, y que algunos patrones pueden implementarse mediante otros patrones. Es por esto que la descripcin de la estructura de un patrn no es suficiente. Se necesita adems describir la semntica del patrn, es decir, lo que hace y cul es la intencin que motiva su diseo. Patrones de diseo con una estructura similar, como el prototipo y la fbrica abstracta tienen intenciones diferentes. Por otra parte, describir el modo de operacin de un patrn no delimita el modo de implementarlo, siempre que la estructura del patrn se cumpla. De esta manera, mediante ciertas variaciones de la estructura de un patrn, se puede conseguir generar patrones distintos al cambiar el tipo y las caractersticas de los participantes en un patrn. De esta manera podemos crear familias de patrones a partir de un solo patrn. El diseador utiliza los patrones de diseo como bloques de construccin para el software, lo cual implica que un patrn que resuelve un problema particular de un modo puede ser reemplazado por un patrn que resuelve el mismo problema de un modo distinto. As, aunque un patrn impone restricciones de diseo, y fuerza al mantenimiento de ciertas relaciones entre los participantes, se puede hacer tan acoplado o desacoplado como se requiera, para que imponga de forma tan rgida o flexible sus restricciones como se desee.
3.2 Revisin.
Existen dos conceptos importantes relacionados con estndares en el desarrollo de componentes: el modelo de componente y el estndar de composicin. Ambos son conceptos importantes al considerar cmo podemos disear con componentes, y tambin cmo deben disearse los componentes para ser reutilizables. El modelo de componente incorpora estndares especficos de interaccin y uso, y el estndar de composicin define cmo pueden combinarse componentes para crear grandes estructuras. Al observar las definiciones dadas de componentes de software, el concepto de reuso aparece de forma explcita en la primera e implcita en la segunda, esto debido a que estrictamente, el reuso no es una caracterstica esencial de un componente, sino slo una caracterstica deseable. Si un sistema contiene slo uno o dos componentes elaborados en lugar de un conjunto de componentes reutilizables, esto puede considerarse una decisin de diseo prctica que reduce el problema de diseo detallado al disear slo unos cuantos componentes, en lugar de un sistema completo. Recordemos que mientras los sistemas hardware suelen requerir de la inclusin de muchas instancias de un pequeo conjunto de componentes, los grandes sistemas software suelen requerir un gran nmero de formularios de componentes individuales. En un contexto amplio, reutilizar componentes requiere: * Una funcionalidad bien definida. * Interfaces bien definidas. * Especificacin de las dependencias. La especificacin de las dependencias quiere decir que todas aquellas entradas externas que necesite el componente para funcionar deben estar perfectamente detalladas en su definicin, y preferentemente deben estar consideradas en su interfaz para que sean asignadas en el momento en que se requieran. Sin embargo, las dependencias en el software suelen ser muy sutiles, lo que lleva a que difcilmente esta condicin sea plenamente satisfecha.
3.3 Interfaz.
El desarrollo de software basado en componentes no siempre funciona igual que los modelos de la vida real en los que est inspirado. Por ejemplo, los diseadores electrnicos compran los componentes que requieren para sus dispositivos a los fabricantes especializados en lugar de fabricarlos, mientras que un desarrollador de software difcilmente recurrir a un especialista en desarrollo de componentes de software para comprar los componentes necesarios para realizar un proyecto. La diversa naturaleza de los componentes, la variedad de estilos de diseo usados para su construccin y la falta de madurez del concepto implican que ninguna prctica estandarizada de desarrollo de componentes se haya establecido. Sin embargo, contamos con ciertas guas que podemos seguir, incluyendo posibles estrategias de diseo, as como actividades de apoyo. Existe poco conocimiento que pueda orientarnos a la hora de desarrollar una aplicacin basada en componentes, incluso para estilos de diseo bien establecidos (por ejemplo, JavaBeans), lo cual se complica por el hecho de que los componentes pueden ser utilizados para interactuar entre ellos de forma horizontal en un sistema, pero tambin verticalmente, creando capas de servicios por medio de mecanismos como CORBA o .NET. En este contexto, cobra especial relevancia saber buscar los componentes adecuados para cubrir las necesidades que aparezcan en nuestro software, ya que una buena seleccin de componentes nos permitir cumplir adecuadamente con el mtodo de diseo seleccionado, y obtener una interaccin de componentes y capas que cumpla con los objetivos de la aplicacin. Existen dos posibles estrategias que podemos seguir para la bsqueda de componentes: Identificar las necesidades generales del problema, y luego buscar un conjunto de componentes que cumplan con la funcionalidad buscada, unindolos para conformar el sistema. (a la que puede denominarse estrategia primero los elementos). Descomponer el problema en subproblemas bien definidos, y luego buscar un conjunto de componentes que resuelvan las necesidades de los subproblemas individuales. (que podra denominarse estrategia primero la estructura). Obviamente, ambas estrategias pueden combinarse para obtener mejores resultados, por lo que se recomienda no tomar partido preferencial por la primera, a pesar que para ciertos desarrolladores puede parecer la mejor opcin de desarrollo. Para armar un sistema a partir de un conjunto de componentes, el diseador debe ser capaz de modelar y predecir su funcionalidad y comportamiento agregado, e identificar los problemas potenciales que puedan aparecer en la interrelacin de componentes, a saber: Funcionalidad traslapada: Ocurre cuando dos o ms componentes pueden proveer una misma funcionalidad de entre todas sus funciones. El diseador debe determinar cul de todos los componentes realiza el trabajo, y debe asegurarse que slo dicho componente lo realice. Desde un punto de vista de diseo, es particularmente indeseable que una misma funcionalidad sea otorgada por ms de un componente, ya que las diferencias de procesamiento a la hora de realizar las operaciones que otorgan dicha funcionalidad pueden causar incompatibilidades en los datos contenidos en el sistema, adems que la actualizacin de uno de los componentes, al no afectar al otro pueden causar fallos en la operacin del sistema. Prdida de funcionalidad: El problema surge cuando la funcionalidad total disponible en el sistema es menor que la funcionalidad requerida. La solucin es encontrar un componente que complete la funcionalidad requerida, o bien, crearlo. Funcionalidad indeseada: Usualmente, los componentes son fabricados para cubrir una amplia gama de necesidades, por lo que aparte de cumplir con la funcionalidad que el desarrollador necesita, es comn encontrarse con que dichos componentes presentan funciones extras que pueden ser innecesarias o incluso nocivas, por provocar redundancias en el sistema que causan funcionalidad traslapada. El desarrollador puede decidir entre incorporar dicha funcionalidad (con los riesgos que esta decisin implica) o encontrar la manera de aislar y desactivar las funciones no deseadas. Aunque esta ltima estrategia parece ser la ms adecuada, puede resultar muy difcil de conseguir, debido a que la parte interna de los componentes no suele ser accesible para el desarrollador, y a que las funciones no deseadas en ocasiones estn muy relacionadas con la funcionalidad para la que se requiere el componente. Incompatibilidad de la arquitectura: Este problema se presenta cuando las condiciones de trabajo del
componente no son las mismas para las que originalmente dicho componente se haba desarrollado. Por ejemplo, a bajo nivel, puede ocurrir que el componente est desarrollado en un lenguaje de programacin diferente al utilizado por el desarrollador, y cuyas funciones reciban los parmetros de formas diferentes. A un nivel ms alto, puede suceder que el manejo de eventos entre componentes entre en conflicto, o que la forma en que dos componentes se interconectan sea errnea. Yakimovitch (1999) especifica varios ejemplos de incompatibilidades, tales como: Empaquetado de componentes: Los componentes pueden estar construidos como componentes enlazables (bibliotecas) o como componentes independientes. Tipo de control: Corresponde a la forma en que se organiza y se transfiere el control entre los componentes, y si es manejado centralmente por la aplicacin o de manera concurrente. Tipo de flujo de informacin: El control de flujo de la informacin puede ser realizado a travs de llamadas a mtodos, flujo de datos a travs de memoria compartida o de forma mezclada. Sincronizacin entre componentes: Concerniente a la capacidad de un componente para bloquear la ejecucin de otro componente, o bien, de ejecutarse sin interactuar. Tiempo de enlace: El momento en que los componentes se enlazan a los conectores, que puede ser en tiempo de compilacin, de enlazado del programa, de ejecucin, etc. La incompatibilidad de la arquitectura es ms difcil de tratar que los problemas de funcionalidad previamente citados, por lo que se recomienda ampliamente utilizar componentes con estilo arquitectural consistente.
3.4 Diseo.
Las guas para disear componentes pueden dividirse en las que tratan las propiedades generales de un componente y las que son especficas a las necesidades de un estilo arquitectural particular. En otras palabras, existen caractersticas comunes a todos los componentes, y otras que slo se necesitan para ciertos tipos de componentes. Sin embargo, incluso las caractersticas comunes pueden necesitar reinterpretarse para ajustarse al diseo arquitectural seleccionado. Como ya se ha visto antes, las caractersticas comunes a todos los componentes pueden resumirse en:
Funcionalidad bien definida Interfaz bien definida Especificacin de las dependencias explcitas
Conseguir la primera es cuestin de diseo general, mientras que las otras dos pueden ser influenciadas por el tipo de arquitectura seleccionada. Como ejemplo de la segunda, la forma de la interfaz requerida por un JavaBean est bien definida, hasta la forma de los identificadores que se usarn para los mtodos visibles externamente, mientras que en un proceso de Unix, el diseador puede utilizar los mecanismos de entrada y salida estndar, pero no existe la certeza de que el componente sea implementado de esa manera. Regresando a la cuestin de la funcionalidad, disear componentes para reutilizarlos implica que el diseador se esfuerce en hacer componentes lo ms generales posibles. Los criterios de acoplamiento y cohesin son probablemente los apoyos ms utilizados para determinar qu constituye una forma y grado de funcionalidad aceptables con relacin a la funcionalidad. En un caso de estudio publicado por Crnkovic y Larsson (2002), se identifican las siguientes cuestiones de diseo de componentes: Es mejor disear componentes grandes que son fciles de reutilizar, pues los componentes particulares pueden ser diseados por los creadores de aplicaciones. Mantener la compatibilidad con versiones previas incrementa el costo de diseo. Es necesario separar aquellas caractersticas de un componente que dependen de las interacciones con la plataforma, para permitir una mayor portabilidad del componente.
Adems se enfatiza la necesidad de una profunda planeacin y control en el desarrollo y mantenimiento de los componentes. El desarrollo de un componente reutilizable implica una gran inversin en tiempo y costos, mucho mayor a la de implementar una solucin que no sea necesario englobar como componente.
Componentes en PRADO Un componente es una instancia de TComponent o de sus clases heredadas. La clase base TComponent implementa los mecanismos de propiedades y eventos de un componente. Una propiedad de componente puede verse como una variable pblica que describe un aspecto del componente, tal como su color de fondo, el tamao de letra, etc. Una propiedad se define por la existencia de un mtodo de lectura (get) o de asignacin (set) en la clase del componente. Por ejemplo, en la clase TControl, definimos la propiedad ID utilizando los siguientes mtodos: class TControl extends Tcomponent { public function getID() { ... } public function setID($value) { ... } } Para leer o asignar la propiedad ID, se trata la propiedad ID como si fuera una variable: $id = $component->ID; $component->ID = $id; Hacerlo as es equivalente a lo siguiente: $id = $component->getID(); $component->setID( $id ); Una propiedad es de slo lectura si tiene mtodo de lectura, pero no de asignacin. Puesto que los mtodos en PHP no son sensibles a maysculas y minsculas, los nombres de propiedades tampoco lo son. Una clase componente hereda todas las propiedades de su clase base. Se conoce como subpropiedad a una propiedad que se encuentra al menos doblemente encapsulada, por ser propiedad de un objeto que a su vez es propiedad de otro objeto. Por ejemplo, el componente TWebControl tiene una propiedad Font de tipo TFont. Puesto que el componente TFont tiene una propiedad denominada Name, la propiedad Name del objeto Font perteneciente al componente TWebControl es una subpropiedad. Para acceder a las subpropiedades de un componente pueden utilizarse los siguientes mtodos: $name = $component->getSubProperty('Font.Name'); $component->setSubProperty('Font.Name', $name); equivalentes a: $name = $component->getFont()->getName(); $component->getFont()->setName( $name ); Los eventos de un componente son propiedades especiales que toman nombres de mtodos como sus valores. Adjuntar un mtodo a un evento conectar el mtodo a los lugares donde es lanzado el evento. Por eso, el comportamiento de un componente puede ser modificado de una forma no prevista durante el desarrollo del componente. Un evento de componente se define por la existencia de un mtodo cuyo nombre inicia con la palabra On. El nombre del evento es el nombre del mtodo, y es, por tanto, insensible a maysculas y minsculas. Por
ejemplo, para el componente TButton tenemos la siguiente declaracin: class TButton extends TwebControl { public function onClick( $param ) { ... } } Lo cual define un evento llamado OnClick. Un manejador de dicho evento puede adjuntarse al evento utilizando una de las siguientes formas: $button->OnClick = $callback; $button->OnClick->add( $callback ); $button->OnClick[] = $callback; $button->attachEventHandler( 'OnClick' , $callback ); donde $callback se refiere a cualquier referencia de PHP a funcin vlida (como un nombre de funcin, una invocacin a mtodo de clase de tipo array($objeto, 'metodo'), etc.) Para utilizar un componente en Prado, se crea una instancia de la clase que contiene la definicin del componente. Existen dos tipos de instanciacin: esttica y dinmica. La instanciacin dinmica de componentes se realiza por medio del cdigo PHP, de la misma manera en que se crea cualquier otro tipo de objeto, mientras que la instanciacin esttica crea los componentes por medio de un archivo de configuracin, y la creacin real del objeto es realizada por PRADO. Dichos archivos pueden ser archivos de configuracin de la aplicacin, o bien, plantillas de pgina. Cada etiqueta de componente en una plantilla de pgina especifica un componente que ser creado automticamente por la estructura de PRADO cuando se inicialice la plantilla. Controles en PRADO Un control es una instancia de la clase TControl o de sus subclases. Un control es un componente para el cual se crea una interfaz de usuario. La clase base TControl define la relacin padre-hijo entre controles que reflejan la relacin de contencin entre los elementos de la interfaz de usuario. En la interfaz de usuario, cada control puede ser padre de otros controles, quedando a cargo dicho control padre de la transicin de estado de sus controles hijos.La representacin resultante de los controles hijos se usa comnmente para crear la representacin del control padre. La relacin padre-hijo enlaza a los controles en un rbol de controles. Un control de pgina es la raz del rbol, cuya presentacin es regresada a los usuarios finales. Cada control tiene una propiedad ID que puede identificarlo de sus controles vecinos. Adems, cada control tiene una propiedad UniqueID y una propiedad ClientID que pueden ser usadas para identificar globalmente el control en el rbol de controles en el que reside. UniqueID y ClientID son muy similares, el primero es utilizado por la estructura de PRADO para determinar la localizacin del control correspondiente en el rbol de controles, mientras que el ltimo es usado del lado del cliente como ID para las etiquetas. No se recomienda fiarse demasiado de la estructura de dichas propiedades. HTTP es un protocolo que no provee funcionalidad de apoyo para una interaccin continua entre los clientes y el servidor. Cada solicitud es considerada independiente de las dems. Sin embargo, una aplicacin Web comnmente necesitar saber qu ha hecho el usuario en recargas de pgina anteriores a la ltima. Comnmente el programador se apoya en las variables de sesin para recordar alguna informacin de estado. PRADO toma prestado los conceptos de viewstate (estado de la vista o de la pgina) y controlstate (estado del control) de la arquitectura ASP.NET para proveer un mecanismo de conservacin de estado adicional. Un valor almacenado en el estado de la pgina o en el estado del control quedar disponible para las siguientes recargas de pginas, siempre que sean la recarga de la misma pgina hecha en la misma sesin. La diferencia entre el estado de la pgina y el estado del control, es que la primera puede desactivarse y la segunda no.
Las propiedades viewstate y controlstate estn implementadas en la clase base TControl, y se usan comnmente para definir varias propiedades de los controles. Para guardar y recuperar valores usando dichas propiedades, existen los siguientes mtodos: $this->getViewState('Name',$defaultValue); $this->setViewState('Name',$value,$defaultValue); $this->getControlState('Name',$defaultValue); $this->setControlState('Name',$value,$defaultValue); Donde $this se refiere a la instancia del control, Name se refiere a un identificador asignado por el programador para etiquetar el valor almacenado, y $defaultValue es un valor que se entregar de forma predefinida cuando el programa solicite un identificador no almacenado en el estado de la pgina o del control, y cuya definicin es opcional.
Cada componente est al mismo nivel de detalle Cada componente pueda ser creado de forma independiente, y La implementacin de estos componentes pueda ser integrada para satisfacer los requerimientos originales del sistema.
La descomposicin se usa para dividir el software en componentes que puedan ser combinados para resolver el problema original. La abstraccin ayuda a seleccionar adecuadamente los componentes. Principio 2: La reutilizacin puede ser alcanzada en varios niveles. El software existe en diferentes formas a travs del proceso de ingeniera de software. En las fases de modelado y anlisis, las especificaciones de requerimientos se ven como una forma de software. En la fase de diseo, el diseo arquitectural y los documentos de diseo detallados son parte del software. El cdigo fuente en la fase de implementacin y el cdigo ejecutable entregado al cliente son software. Por tanto, la reutilizacin de software incluye reutilizar todos estos formatos de software en sus diferentes etapas. Principio 3: El desarrollo de software basado en componentes incrementa la confiabilidad del software. Con los rpidos avances en hardware, actualmente disponemos de computadoras altamente confiables, poderosas y baratas, por lo que la confiabilidad de un sistema de cmputo recae fuertemente sobre la parte del software. El uso de software basado en componentes, y por tanto, de programacin orientada a componentes, provee una manera sistemtica de alcanzar sistemas confiables. Partiendo de la abstraccin de componentes y de la integracin sistemtica de componentes, es mucho ms fcil validar requerimientos crticos y verificar la seguridad para sistemas basados en componentes. Adems, los componentes reutilizables usualmente han sido revisados mediante un proceso de validacin y por uso real durante un periodo largo de tiempo, con lo que su calidad queda asegurada. Principio 4: El desarrollo de software basado en componentes puede incrementar la productividad del software. El software basado en componentes est construdo mediante el ensamblaje de componentes reutilizables en lugar de desarrollarse de ceros, siguiendo el principio de reutilizar en lugar de reinventar la rueda. Este proceso es mucho ms rpido que desarrollar una aplicacin desde cero, en la mayora de los casos. Principio 5: El desarrollo de software basado en componentes promueve la estandarizacin de software. El desarrollo de componentes no tendra sentido sin un mnimo grado de estandarizacin que permita la reutilizacin por parte de terceros programadores. La estandarizacin puede utilizarse para crear un acuerdo sobre especificaciones de interfaces concretas, permitiendo una composicin efectiva y asegurando que la programacin orientada a componentes se convierta en un nuevo paradigma de programacin para el que el plug and play se vuelva una realidad equivalente a la de su contraparte hardware.
programacin compatible, restriccin propietaria y soluciones amigables con firewalls de internet para la computacin distribuda interoperativa. Los servicios web trabajan sobre una pila de protocolos consistentes en SOAP/XML/HTTP/TCP/IP que hacen a los web services ampliamente aceptables dado que los clientes de los servicios web tienen soporte para estos protocolos. Un servicio web es un componente distribudo en lnea autodescriptivo, que expone sus servicios y su funcionalidad mediante su interfaz en lnea y que puede ser publicado, localizado e invocado programticamente a travs de internet. Un punto importante de los servicios web es su capacidad de proveer servicios de programacin remotos de los que cualquier aplicacin puede obtener servicios proporcionados por cualquier web service. La filosofa detrs de los servicios web es mover el desarrollo de software distribuido de programacin a composicin, de iniciar de ceros a construir nuevas aplicaciones a partir de componentes existentes ya sea comprando o reutilizando los componentes. As, el objetivo principal de los servicios web no es slo proveer servicios en web, sino tambin proveer un mecanismo para compartir sus servicios como un bloque de construccin que puede ser parte de otros servicios web o programas de aplicacin mediante sus terminales de servicio web programables. Los servicios web han mostrado su potencial para cambiar los mtodos del modelado empresarial de negocios en las interacciones de sistemas distribuidos. Un sistema empresarial grande puede ser dividido en varios componentes de servicios web relativamente independientes, los cuales a su vez pueden recibir servicios de otros componentes de servicios web existentes en Internet. Resumiendo, las caractersticas y propiedades de la tecnologa de servicios web consiste en: Incrementa la portabilidad e interoperabilidad de la computacin distribuida. Incrementa la reusabilidad y escalabilidad de los componentes distribuidos. Reduce la complejidad de la composicin y el despliegue de los componentes. Reduce el costo y el tiempo en el mercado para el desarrollo de software de componentes distribuidos. Mejora significativamente las transacciones comerciales B2B y el intercambio electrnico de datos. Simplifica la administracin de sistemas distribuidos. Es muy fcil ajustar una aplicacin propietaria existente para ser compatible con los servicios web. Opera con una pila de protocolos estandarizados. Es una solucin de internet de tercera generacin para computacin distribuida.