Generaciones de la Programación Informática
Los equipos de ordenador (el hardware) han pasado por cuatro generaciones, de las que las tres primeras (ordenadores con válvulas, transistores y circuitos integrados) están muy claras, la cuarta (circuitos integrados a gran escala) es más discutible.
Algo parecido ha ocurrido con la programación de los ordenadores (el software), que se realiza en lenguajes que suelen clasificarse en cinco generaciones, de las que las tres primeras son evidentes, mientras no todo el mundo está de acuerdo en las otras dos. Estas generaciones no coincidieron exactamente en el tiempo con las de hardware, pero sí de forma aproximada, y son las siguientes:
Primera Generación (para otros Generación Cero): Programación Manual
En un principio las instrucciones de los programas se tenian que codificar manualmente, en la epoca que se utilizaban las tarjetas perforadas
Segunda Generación (para otros Primera Generación): Programación Imperativa y el Código Spaghetti
Se programaba directamente con instrucciones rudimentarias y con metodos primitivos, los cuales se anudaban creando el efecto "codigo spaghetti" o codigo enmarañado
El código spaghetti es un término peyorativo para los programas de computación que tienen una estructura de control de flujo compleja e incomprensible. Su nombre deriva del hecho que este tipo de código parece asemejarse a un plato de espaguetis, es decir, un montón de hilos intrincados y anudados.
Tradicionalmente suele asociarse este estilo de programación con lenguajes básicos y antiguos, donde el flujo se controlaba mediante sentencias de control muy primitivas como goto y utilizando números de línea. Un ejemplo de lenguaje que invitaba al uso de código spaghetti es el QBasic de Microsoft en sus primeras versiones.
Sin embargo, se debe tener en cuenta que hoy, con lenguajes modernos como PHP, SQL, Javascript (su última versión) junto con HTML (incluyendo su última versión), el código spaghetti es cada vez más utilizado ya que muchas veces estos lenguajes deben quedar entrelazados, aunque es perfectamente posible que un programador experimentado evite esto aunque se requiera para ello de un poco más de esfuerzo de programación que al final viene a ser recompensado con una programación más limpia, fácilmente entendible que le beneficia incluso a él mismo a la hora de dar mantenimiento a los sistemas.
Un ejemplo sencillo sería:
<?php
$a=1;
$b=2;
echo '<html>';
echo '<head>';
echo '</head>';
echo '<body>';
echo '<form action='pr2.php';
if($a+$b==1) {
echo'
Nombre<input type="text" name="nombre" value="" />
'; echo'
Apellido <input type="text" name="apellido" value="" />
';
}
else {
echo'
Telefono<input type="text" name="telefono" value="" />
'; echo'
Direccion <input type="text" name="direccion" value="" />
';
}
echo' </FORM> ';
echo ' </body>';
echo '</html>';
?>
Tercera y Cuarta Generación (para otros Segunda y Tercera Generación): Descomposición Funcional
La "descomposición funcional" es el proceso de tomar un proceso complejo y lo descomponen en sus más pequeños, las piezas más simples.
Descomposición funcional es una manera de romper el problema complejo en problemas más simples basados en las tareas que deban llevarse a cabo en lugar de las relaciones los datos. Este término se suele asociar con el diseño anterior orientado al procedimiento.
Por ejemplo, piense en utilizar un cajero automático. Usted puede descomponer el proceso en:
Camine hasta el cajero automático
Inserte su tarjeta bancaria
Ingrese su PIN
Usted puede pensar en la programación de la misma manera. Piensa en el software que se ejecuta que ATM:
Código para la lectura de la tarjeta
PIN de verificación
Transferencia de procesamiento
Cada una de la que se puede dividir aún más. Una vez que hayas llegado a las piezas más descompuesto de un subsistema, se puede pensar acerca de cómo empezar a programar esas piezas. A continuación, componen las partes pequeñas en el conjunto mayor
Descomposición (programación)
El beneficio de la descomposición funcional es que una vez que comience la codificación, usted está trabajando en los más simples componentes que puede funcionar con la aplicación. Por lo tanto en desarrollo y los ensayos de los componentes se hace mucho más fácil (sin mencionar que son más capaces de su código y el arquitecto del proyecto se ajuste a sus necesidades).
La desventaja obvia es la inversión de tiempo. Para realizar la descomposición funcional en un sistema complejo requiere más que un porcentaje insignificante de tiempo antes de codificar comienza.
Es lo mismo que las estructuras WorkBreakDown (PEP), mapas mentales y el desarrollo de arriba hacia abajo - básicamente romper un gran problema en partes más pequeñas, más comprensible sub-partes.
Pros:
permite un acercamiento proactivo a la programación (resiting el impulso de código)
ayuda a identificar las complejas y / o zonas de riesgo de un proyecto (en el ejemplo de cajeros automáticos, la seguridad es probablemente el componente más complejo)
ayuda a identificar a TODOS los componentes de un proyecto - la causa # 1 del proyecto o el fracaso de código (a través de Capers Jones) falta piezas - las cosas no pensó hasta tarde en el proyecto (caray, no me di cuenta que tenía que revisar el balance de la persona antes de la entrega de los US $)
permite la disociación de los componentes para una mejor programación, el intercambio de código y distribución del trabajo
Contras: - NO hay CONS real en hacer una descomposición, sin embargo hay algunos errores comunes
NO está partida lo suficientemente lejos o derribar a la medida - que cada persona necesita para determinar el nivel de detalle feliz necesarios para proporcionarle la información detallada al componente sin exagerar (no se descomponen en líneas de código de programación ...)
NO el uso de patrones pre-existentes o módulos de código en cuenta (re-proceso)
NO revisar con los clientes para garantizar una delimitación es correcta
NO usar el desglose de codificación, cuando en realidad (como el diseño de una casa que olvidar el plan y acaba de empezar a clavar unas tablas juntas)
Quinta Generacion (para otros la Cuarta Generacion): Descomposicion en Objetos
La programación orientada a objetos es otra forma de descomponer problemas. Este nuevo método de descomposición es la descomposición en objetos; vamos a fijarnos no en lo que hay que hacer en el problema, sino en cuál es el escenario real del mismo, y vamos a intentar simular ese escenario en nuestro programa.
Los lenguajes de programación tradicionales no orientados a objetos, como C, Pascal, BASIC, o Modula-2, basan su funcionamiento en el concepto de procedimiento o función. Una función es simplemente un conjunto de instrucciones que operan sobre unos argumentos y producen un resultado. De este modo, un programa no es más que una sucesión de llamadas a funciones, ya sean éstas del sistema operativo, proporcionadas por el propio lenguaje, o desarrolladas por el mismo usuario.
En el caso de los lenguajes orientados a objetos, como es el caso de C++ y Java, el elemento básico no es la función, sino un ente denominado precisamente objeto. Un objeto es la representación en un programa de un concepto, y contiene toda la información necesaria para abstraerlo: datos que describen sus atributos y operaciones que pueden realizarse sobre los mismos.
La programación orientada a objetos es una nueva forma de pensar, una manera distinta de enfocar los problemas. Ahí radica la dificultad de aprender un lenguaje totalmente orientado a objetos, como es Java, sin conocer previamente los pilares de la programación orientada a objetos. Hecha esta importante aclaración, conviene destacar que Java, más que un lenguaje orientado a objetos, es un lenguaje de objetos. Java incorpora el uso de la orientación a objetos como uno de los pilares básicos y fundamentales del lenguaje. Esto constituye una importante diferencia con respecto a C++. C++ está pensado para su utilización como lenguaje orientado a objetos, pero también es cierto que con C++ se puede escribir código sin haber oído nada de la programación orientada a objetos. Esta situación no se da en Java, dotado desde las primeras etapas de su diseño de esta filosofía, y donde no cabe obviar la orientación a objetos para el desarrollo de programas, por sencillos que éstos sean. Al contrario que en C++, en Java nada se puede hacer sin usar al menos un objeto.
Características de los Objetos
Los objetos como tales, presentan muchas cualidades diferentes, respecto a una variable simple. Entre ellas podemos mencionar las siguientes:
1. Los objetos se pueden agrupar en rubros (o tipos) denominados Clases
2. El estado de los objetos está determinado por los datos del mismo
3. Permite lo que se conoce como Ocultación de datos
4. Pueden heredar propiedades de otros objetos
5. Por medio de los Mensajes un objeto se puede comunicar con otro
6. Los métodos definen el comportamiento de los objetos
Generaciones anteriores de la Programación (sin contar la Primera Generación (Generación Cero)
Sexta Generación (para otros la Quinta Generación): Descomposición de Aspectos
A mediados de los 90 surgió la programación orientada a aspectos (POA), un nuevo paradigma de programación que ha logrado un nivel de desarrollo interesante y que ha generado expectativas importantes a nivel mundial. Este paradigma ofrece una nueva herramienta de modularización, la descomposición de aspectos, junto con nuevas formas de relacionar módulos, por medio de los designadores de enlace; y mediante éstas herramientas provee formas novedosas de implementar aplicaciones que resultan ser altamente modulares. Sus conceptos tienen similaridad con conceptos en otros paradigmas de programación, como programación generativa , metaprogramación o programación declarativa , aunque sus seguidores han encontrado una forma de diferenciar y darle carácter propio al desarrollo orientado por aspectos (DOA).
Los aspectos no suelen ser unidades de descomposición funcional del sistema, sino propiedades que afectan al rendimiento o la semántica de los componentes. Algunos ejemplos de aspectos son, los patrones de acceso a memoria, la sincronización de procesos concurrentes, el manejo de errores, etc.
Como se puede observar, en la versión tradicional estos mismos bloques de funcionalidad quedan repartidos por todo el código, mientras en que la versión orientada a aspectos tenemos un programa más compacto y modularizado, teniendo cada aspecto su propia competencia.
Los lenguajes orientados a aspectos definen una nueva unidad de programación de software para encapsular las funcionalidades que cruzan todo el código. Para que ambos (aspectos y componentes) se puedan mezclar, deben tener algunos puntos comunes, que son los que se conocen como puntos de enlace, y debe haber algún modo de mezclarlos.
Los puntos de enlace son una clase especial de interfaz entre los aspectos y los módulos del lenguaje de componentes. Son los lugares del código en los que éste se puede aumentar con comportamientos adicionales. Estos comportamientos se especifican en los aspectos.
El encargado de realizar este proceso de mezcla se conoce como tejedor (del término inglés weaver). El tejedor se encarga de mezclar los diferentes mecanismos de abstracción y composición que aparecen en los lenguajes de aspectos y componentes ayudándose de los puntos de enlace.
En las aplicaciones orientadas a aspectos, sin embargo, además del compilador, hemos de tener el tejedor, que nos combine el código que implementa la funcionalidad básica, con los distintos módulos que implementan los aspectos, pudiendo estar cada aspecto codificado con un lenguaje distinto.
Una ayuda para poder identificar la segmentación de un programa es :
Análisis y diseño orientado a objetos:
Sustantivos: candidatos a clases o atributos.
Verbos: candidatos a métodos.
Análisis y diseño orientado a asepctos:
Adverbios y adjetivos: candidatos a aspectos.
Transacción segura, registro permanente, evento
Definen conceptos que tienen sentido independientemente a los sustantivos y verbnos a los que se aplican.
También pueden ser candidatos a subclases e interfaces.
Síntesis de Funcionalidades Básicas
Aspect (Aspecto): es la funcionalidad que se cruza a lo largo de la aplicación (cross-cutting) que se va a implementar de forma modular y separada del resto del sistema. El ejemplo más común y simple de un aspecto es el logging (registro de sucesos) dentro del sistema, ya que necesariamente afecta a todas las partes del sistema que generan un suceso.
Join point (Punto de Cruce o de Unión): es un punto de ejecución dentro del sistema donde un aspecto puede ser conectado, como una llamada a un método, el lanzamiento de una excepción o la modificación de un campo. El código del aspecto será insertado en el flujo de ejecución de la aplicación para añadir su funcionalidad.
Advice (Consejo): es la implementación del aspecto, es decir, contiene el código que implementa la nueva funcionalidad. Se insertan en la aplicación en los Puntos de Cruce.
Pointcut (Puntos de Corte): define los Consejos que se aplicarán a cada Punto de Cruce. Se especifica mediante Expresiones Regulares o mediante patrones de nombres (de clases, métodos o campos), e incluso dinámicamente en tiempo de ejecución según el valor de ciertos parámetros.
Introduction (Introducción): permite añadir métodos o atributos a clases ya existentes. Un ejemplo en el que resultaría útil es la creación de un Consejo de Auditoría que mantenga la fecha de la última modificación de un objeto, mediante una variable y un método setUltimaModificacion(fecha), que podrían ser introducidos en todas las clases (o sólo en algunas) para proporcionarlas esta nueva funcionalidad.
Target (Destinatario): es la clase aconsejada, la clase que es objeto de un consejo. Sin AOP, esta clase debería contener su lógica, además de la lógica del aspecto.
Proxy (Resultante): es el objeto creado después de aplicar el Consejo al Objeto Destinatario. El resto de la aplicación únicamente tendrá que soportar al Objeto Destinatario (pre-AOP) y no al Objeto Resultante (post-AOP).
Weaving (Tejido): es el proceso de aplicar Aspectos a los Objetos Destinatarios para crear los nuevos Objetos Resultantes en los especificados Puntos de Cruce. Este proceso puede ocurrir a lo largo del ciclo de vida del Objeto Destinatario:
Aspectos en Tiempo de Compilación, que necesita un compilador especial.
Aspectos en Tiempo de Carga, los Aspectos se implementan cuando el Objeto Destinatario es cargado. Requiere un ClassLoader especial.
Aspectos en Tiempo de Ejecución.
Ventajas de programar la implementación de POA
Las ventajas que tiene el capturar los aspectos ya desde la fase de sieño son claras:
Facilita la creación de documentación y el aprendizaje, porque implica el diseño por completo de los mismos.
Facilita la reutilización de los aspectos, ya que conocemos la estructura interna y podemos adaptarlos a la nueva problemática.
Ventajas de la utilización de POA
Disminución del código disperso distribuido por toda la aplicación (scattered code).
Implementación un única vez en una ejecución de multimples comportamientos en forma simultánea.
Desventaja
Con respecto a los lenguajes de dominio específico, puede tener bastante importancia el hecho de escoger un lenguaje base. Se tiene que tener en cuenta que los puntos de enlace solamente pueden ser los que se identifiquen en el lenguaje base. Si necesitamos separar las funcionalidades, debemos recordar que el lenguaje base debe restringirse después de que se hayan separado los aspectos. Lo que implica quitar módulos del lenguajes base, que puede no haber sido diseñado para esto e implica un conocimiento con profundidad del mismo (mas dificil que haber creado uno desde cero).
Los lenguajes de aspectos de propósito general son menos difíciles de implementar por encima de un lenguaje de programación existente, ya que no necesitan restringir el lenguaje base.
Conclusión
La separación de los aspectos a todos los niveles (diseño, codificación y ejecutable) es un paso importante que se ha comenzado a dar, pero que aún hay que refinar, sobre todo en cuestiones de eficiencia.
Los entornos de programación orientada a aspectos que han habido hasta ahora no soportan una separación de funcionalidades suficientemente amplia, el lenguaje de aspecto soporta el dominio de aspecto parcialmente, no se sostiene adecuadamente la restricción del lenguaje base, o bien no se cuenta suficientemente desarrollada la idea de implementación que solucione un problema sin incurrir en otro aumentando la complejidad y disminuyendo el tiempo de desarrollo, mantenimiento u tiempo necesario de proceso.
Para la comunidad de usuarios de www.taringa.net, Ranko Inazuma[/size]
Los equipos de ordenador (el hardware) han pasado por cuatro generaciones, de las que las tres primeras (ordenadores con válvulas, transistores y circuitos integrados) están muy claras, la cuarta (circuitos integrados a gran escala) es más discutible.
Algo parecido ha ocurrido con la programación de los ordenadores (el software), que se realiza en lenguajes que suelen clasificarse en cinco generaciones, de las que las tres primeras son evidentes, mientras no todo el mundo está de acuerdo en las otras dos. Estas generaciones no coincidieron exactamente en el tiempo con las de hardware, pero sí de forma aproximada, y son las siguientes:
Primera Generación (para otros Generación Cero): Programación Manual
En un principio las instrucciones de los programas se tenian que codificar manualmente, en la epoca que se utilizaban las tarjetas perforadas
Segunda Generación (para otros Primera Generación): Programación Imperativa y el Código Spaghetti
Se programaba directamente con instrucciones rudimentarias y con metodos primitivos, los cuales se anudaban creando el efecto "codigo spaghetti" o codigo enmarañado
El código spaghetti es un término peyorativo para los programas de computación que tienen una estructura de control de flujo compleja e incomprensible. Su nombre deriva del hecho que este tipo de código parece asemejarse a un plato de espaguetis, es decir, un montón de hilos intrincados y anudados.
Tradicionalmente suele asociarse este estilo de programación con lenguajes básicos y antiguos, donde el flujo se controlaba mediante sentencias de control muy primitivas como goto y utilizando números de línea. Un ejemplo de lenguaje que invitaba al uso de código spaghetti es el QBasic de Microsoft en sus primeras versiones.
Sin embargo, se debe tener en cuenta que hoy, con lenguajes modernos como PHP, SQL, Javascript (su última versión) junto con HTML (incluyendo su última versión), el código spaghetti es cada vez más utilizado ya que muchas veces estos lenguajes deben quedar entrelazados, aunque es perfectamente posible que un programador experimentado evite esto aunque se requiera para ello de un poco más de esfuerzo de programación que al final viene a ser recompensado con una programación más limpia, fácilmente entendible que le beneficia incluso a él mismo a la hora de dar mantenimiento a los sistemas.
Un ejemplo sencillo sería:
<?php
$a=1;
$b=2;
echo '<html>';
echo '<head>';
echo '</head>';
echo '<body>';
echo '<form action='pr2.php';
if($a+$b==1) {
echo'
Nombre<input type="text" name="nombre" value="" />
'; echo'
Apellido <input type="text" name="apellido" value="" />
';
}
else {
echo'
Telefono<input type="text" name="telefono" value="" />
'; echo'
Direccion <input type="text" name="direccion" value="" />
';
}
echo' </FORM> ';
echo ' </body>';
echo '</html>';
?>
Tercera y Cuarta Generación (para otros Segunda y Tercera Generación): Descomposición Funcional
La "descomposición funcional" es el proceso de tomar un proceso complejo y lo descomponen en sus más pequeños, las piezas más simples.
Descomposición funcional es una manera de romper el problema complejo en problemas más simples basados en las tareas que deban llevarse a cabo en lugar de las relaciones los datos. Este término se suele asociar con el diseño anterior orientado al procedimiento.
Por ejemplo, piense en utilizar un cajero automático. Usted puede descomponer el proceso en:
Camine hasta el cajero automático
Inserte su tarjeta bancaria
Ingrese su PIN
Usted puede pensar en la programación de la misma manera. Piensa en el software que se ejecuta que ATM:
Código para la lectura de la tarjeta
PIN de verificación
Transferencia de procesamiento
Cada una de la que se puede dividir aún más. Una vez que hayas llegado a las piezas más descompuesto de un subsistema, se puede pensar acerca de cómo empezar a programar esas piezas. A continuación, componen las partes pequeñas en el conjunto mayor
Descomposición (programación)
El beneficio de la descomposición funcional es que una vez que comience la codificación, usted está trabajando en los más simples componentes que puede funcionar con la aplicación. Por lo tanto en desarrollo y los ensayos de los componentes se hace mucho más fácil (sin mencionar que son más capaces de su código y el arquitecto del proyecto se ajuste a sus necesidades).
La desventaja obvia es la inversión de tiempo. Para realizar la descomposición funcional en un sistema complejo requiere más que un porcentaje insignificante de tiempo antes de codificar comienza.
Es lo mismo que las estructuras WorkBreakDown (PEP), mapas mentales y el desarrollo de arriba hacia abajo - básicamente romper un gran problema en partes más pequeñas, más comprensible sub-partes.
Pros:
permite un acercamiento proactivo a la programación (resiting el impulso de código)
ayuda a identificar las complejas y / o zonas de riesgo de un proyecto (en el ejemplo de cajeros automáticos, la seguridad es probablemente el componente más complejo)
ayuda a identificar a TODOS los componentes de un proyecto - la causa # 1 del proyecto o el fracaso de código (a través de Capers Jones) falta piezas - las cosas no pensó hasta tarde en el proyecto (caray, no me di cuenta que tenía que revisar el balance de la persona antes de la entrega de los US $)
permite la disociación de los componentes para una mejor programación, el intercambio de código y distribución del trabajo
Contras: - NO hay CONS real en hacer una descomposición, sin embargo hay algunos errores comunes
NO está partida lo suficientemente lejos o derribar a la medida - que cada persona necesita para determinar el nivel de detalle feliz necesarios para proporcionarle la información detallada al componente sin exagerar (no se descomponen en líneas de código de programación ...)
NO el uso de patrones pre-existentes o módulos de código en cuenta (re-proceso)
NO revisar con los clientes para garantizar una delimitación es correcta
NO usar el desglose de codificación, cuando en realidad (como el diseño de una casa que olvidar el plan y acaba de empezar a clavar unas tablas juntas)
Quinta Generacion (para otros la Cuarta Generacion): Descomposicion en Objetos
La programación orientada a objetos es otra forma de descomponer problemas. Este nuevo método de descomposición es la descomposición en objetos; vamos a fijarnos no en lo que hay que hacer en el problema, sino en cuál es el escenario real del mismo, y vamos a intentar simular ese escenario en nuestro programa.
Los lenguajes de programación tradicionales no orientados a objetos, como C, Pascal, BASIC, o Modula-2, basan su funcionamiento en el concepto de procedimiento o función. Una función es simplemente un conjunto de instrucciones que operan sobre unos argumentos y producen un resultado. De este modo, un programa no es más que una sucesión de llamadas a funciones, ya sean éstas del sistema operativo, proporcionadas por el propio lenguaje, o desarrolladas por el mismo usuario.
En el caso de los lenguajes orientados a objetos, como es el caso de C++ y Java, el elemento básico no es la función, sino un ente denominado precisamente objeto. Un objeto es la representación en un programa de un concepto, y contiene toda la información necesaria para abstraerlo: datos que describen sus atributos y operaciones que pueden realizarse sobre los mismos.
La programación orientada a objetos es una nueva forma de pensar, una manera distinta de enfocar los problemas. Ahí radica la dificultad de aprender un lenguaje totalmente orientado a objetos, como es Java, sin conocer previamente los pilares de la programación orientada a objetos. Hecha esta importante aclaración, conviene destacar que Java, más que un lenguaje orientado a objetos, es un lenguaje de objetos. Java incorpora el uso de la orientación a objetos como uno de los pilares básicos y fundamentales del lenguaje. Esto constituye una importante diferencia con respecto a C++. C++ está pensado para su utilización como lenguaje orientado a objetos, pero también es cierto que con C++ se puede escribir código sin haber oído nada de la programación orientada a objetos. Esta situación no se da en Java, dotado desde las primeras etapas de su diseño de esta filosofía, y donde no cabe obviar la orientación a objetos para el desarrollo de programas, por sencillos que éstos sean. Al contrario que en C++, en Java nada se puede hacer sin usar al menos un objeto.
Características de los Objetos
Los objetos como tales, presentan muchas cualidades diferentes, respecto a una variable simple. Entre ellas podemos mencionar las siguientes:
1. Los objetos se pueden agrupar en rubros (o tipos) denominados Clases
2. El estado de los objetos está determinado por los datos del mismo
3. Permite lo que se conoce como Ocultación de datos
4. Pueden heredar propiedades de otros objetos
5. Por medio de los Mensajes un objeto se puede comunicar con otro
6. Los métodos definen el comportamiento de los objetos
Generaciones anteriores de la Programación (sin contar la Primera Generación (Generación Cero)
Sexta Generación (para otros la Quinta Generación): Descomposición de Aspectos
A mediados de los 90 surgió la programación orientada a aspectos (POA), un nuevo paradigma de programación que ha logrado un nivel de desarrollo interesante y que ha generado expectativas importantes a nivel mundial. Este paradigma ofrece una nueva herramienta de modularización, la descomposición de aspectos, junto con nuevas formas de relacionar módulos, por medio de los designadores de enlace; y mediante éstas herramientas provee formas novedosas de implementar aplicaciones que resultan ser altamente modulares. Sus conceptos tienen similaridad con conceptos en otros paradigmas de programación, como programación generativa , metaprogramación o programación declarativa , aunque sus seguidores han encontrado una forma de diferenciar y darle carácter propio al desarrollo orientado por aspectos (DOA).
Los aspectos no suelen ser unidades de descomposición funcional del sistema, sino propiedades que afectan al rendimiento o la semántica de los componentes. Algunos ejemplos de aspectos son, los patrones de acceso a memoria, la sincronización de procesos concurrentes, el manejo de errores, etc.
Como se puede observar, en la versión tradicional estos mismos bloques de funcionalidad quedan repartidos por todo el código, mientras en que la versión orientada a aspectos tenemos un programa más compacto y modularizado, teniendo cada aspecto su propia competencia.
Los lenguajes orientados a aspectos definen una nueva unidad de programación de software para encapsular las funcionalidades que cruzan todo el código. Para que ambos (aspectos y componentes) se puedan mezclar, deben tener algunos puntos comunes, que son los que se conocen como puntos de enlace, y debe haber algún modo de mezclarlos.
Los puntos de enlace son una clase especial de interfaz entre los aspectos y los módulos del lenguaje de componentes. Son los lugares del código en los que éste se puede aumentar con comportamientos adicionales. Estos comportamientos se especifican en los aspectos.
El encargado de realizar este proceso de mezcla se conoce como tejedor (del término inglés weaver). El tejedor se encarga de mezclar los diferentes mecanismos de abstracción y composición que aparecen en los lenguajes de aspectos y componentes ayudándose de los puntos de enlace.
En las aplicaciones orientadas a aspectos, sin embargo, además del compilador, hemos de tener el tejedor, que nos combine el código que implementa la funcionalidad básica, con los distintos módulos que implementan los aspectos, pudiendo estar cada aspecto codificado con un lenguaje distinto.
Una ayuda para poder identificar la segmentación de un programa es :
Análisis y diseño orientado a objetos:
Sustantivos: candidatos a clases o atributos.
Verbos: candidatos a métodos.
Análisis y diseño orientado a asepctos:
Adverbios y adjetivos: candidatos a aspectos.
Transacción segura, registro permanente, evento
Definen conceptos que tienen sentido independientemente a los sustantivos y verbnos a los que se aplican.
También pueden ser candidatos a subclases e interfaces.
Síntesis de Funcionalidades Básicas
Aspect (Aspecto): es la funcionalidad que se cruza a lo largo de la aplicación (cross-cutting) que se va a implementar de forma modular y separada del resto del sistema. El ejemplo más común y simple de un aspecto es el logging (registro de sucesos) dentro del sistema, ya que necesariamente afecta a todas las partes del sistema que generan un suceso.
Join point (Punto de Cruce o de Unión): es un punto de ejecución dentro del sistema donde un aspecto puede ser conectado, como una llamada a un método, el lanzamiento de una excepción o la modificación de un campo. El código del aspecto será insertado en el flujo de ejecución de la aplicación para añadir su funcionalidad.
Advice (Consejo): es la implementación del aspecto, es decir, contiene el código que implementa la nueva funcionalidad. Se insertan en la aplicación en los Puntos de Cruce.
Pointcut (Puntos de Corte): define los Consejos que se aplicarán a cada Punto de Cruce. Se especifica mediante Expresiones Regulares o mediante patrones de nombres (de clases, métodos o campos), e incluso dinámicamente en tiempo de ejecución según el valor de ciertos parámetros.
Introduction (Introducción): permite añadir métodos o atributos a clases ya existentes. Un ejemplo en el que resultaría útil es la creación de un Consejo de Auditoría que mantenga la fecha de la última modificación de un objeto, mediante una variable y un método setUltimaModificacion(fecha), que podrían ser introducidos en todas las clases (o sólo en algunas) para proporcionarlas esta nueva funcionalidad.
Target (Destinatario): es la clase aconsejada, la clase que es objeto de un consejo. Sin AOP, esta clase debería contener su lógica, además de la lógica del aspecto.
Proxy (Resultante): es el objeto creado después de aplicar el Consejo al Objeto Destinatario. El resto de la aplicación únicamente tendrá que soportar al Objeto Destinatario (pre-AOP) y no al Objeto Resultante (post-AOP).
Weaving (Tejido): es el proceso de aplicar Aspectos a los Objetos Destinatarios para crear los nuevos Objetos Resultantes en los especificados Puntos de Cruce. Este proceso puede ocurrir a lo largo del ciclo de vida del Objeto Destinatario:
Aspectos en Tiempo de Compilación, que necesita un compilador especial.
Aspectos en Tiempo de Carga, los Aspectos se implementan cuando el Objeto Destinatario es cargado. Requiere un ClassLoader especial.
Aspectos en Tiempo de Ejecución.
Ventajas de programar la implementación de POA
Las ventajas que tiene el capturar los aspectos ya desde la fase de sieño son claras:
Facilita la creación de documentación y el aprendizaje, porque implica el diseño por completo de los mismos.
Facilita la reutilización de los aspectos, ya que conocemos la estructura interna y podemos adaptarlos a la nueva problemática.
Ventajas de la utilización de POA
Disminución del código disperso distribuido por toda la aplicación (scattered code).
Implementación un única vez en una ejecución de multimples comportamientos en forma simultánea.
Desventaja
Con respecto a los lenguajes de dominio específico, puede tener bastante importancia el hecho de escoger un lenguaje base. Se tiene que tener en cuenta que los puntos de enlace solamente pueden ser los que se identifiquen en el lenguaje base. Si necesitamos separar las funcionalidades, debemos recordar que el lenguaje base debe restringirse después de que se hayan separado los aspectos. Lo que implica quitar módulos del lenguajes base, que puede no haber sido diseñado para esto e implica un conocimiento con profundidad del mismo (mas dificil que haber creado uno desde cero).
Los lenguajes de aspectos de propósito general son menos difíciles de implementar por encima de un lenguaje de programación existente, ya que no necesitan restringir el lenguaje base.
Conclusión
La separación de los aspectos a todos los niveles (diseño, codificación y ejecutable) es un paso importante que se ha comenzado a dar, pero que aún hay que refinar, sobre todo en cuestiones de eficiencia.
Los entornos de programación orientada a aspectos que han habido hasta ahora no soportan una separación de funcionalidades suficientemente amplia, el lenguaje de aspecto soporta el dominio de aspecto parcialmente, no se sostiene adecuadamente la restricción del lenguaje base, o bien no se cuenta suficientemente desarrollada la idea de implementación que solucione un problema sin incurrir en otro aumentando la complejidad y disminuyendo el tiempo de desarrollo, mantenimiento u tiempo necesario de proceso.
Para la comunidad de usuarios de www.taringa.net, Ranko Inazuma[/size]