Está en la página 1de 16

Composición de Requerimientos No

Funcionales
Gerson Samaniego, José Pulido
Universidad de los Andes
gj.samaniego35@uniandes.edu.co, jc.pulido58@uniandes.edu.co,

Resumen.
Incluir requerimientos no funcionales (RNF) en una aplicación de forma
sencilla para el desarrollador es una de las características que debería
ofrecer un modelo de componentes. Lograr que el desarrollador se centre en
el diseño e implementación de la lógica funcional permite obtener mejores
resultados en las aplicaciones. En este artículo planteamos una solución
para incluir RNFs en un modelo de componentes. La estrategia consiste en
definir los RNFs como componentes no funcionales (CNF) y en definir la
composición de éstos con componentes funcionales (CF) u otros CNFs de
manera externa. Para expresar la interacción entre los componentes
proponemos un lenguaje de dominio específico orientado a aspectos.
Ilustramos nuestra propuesta con un caso de estudio de una aplicación de
comercio electrónico en donde incluimos algunos requerimientos no
funcionales.

Palabras claves.
Programación orientada por aspectos (AOP), Software basado en
componentes (CBSD), Requerimientos no funcionales.

1 INTRODUCCIÓN

El objetivo del desarrollo de software basado en componentes (CBSD) es construir


aplicaciones complejas mediante el ensamblado de partes, llamadas componentes. Un
componente es una pieza de código pre-elaborado que expone su funcionalidad a través
de interfaces estándar [28]. Son los "ingredientes de las aplicaciones", que se juntan y
combinan para llevar a cabo una tarea [4]. Su objetivo principal es la separación de
código en unidades auto-contenidas para promover la reutilización [8]. Por ser
independientes, simplifican las pruebas facilitando la evaluación de su funcionalidad
individualmente y mejoran la calidad de las aplicaciones [6].
Los componentes pueden existir y cooperar dentro de contenedores, entidades de
software que permiten contener a otras entidades, proporcionando un entorno compartido
de interacción [14]. En los modelos componente-contenedor, los contenedores
simplifican el desarrollo de aplicaciones ofreciendo algunos aspectos no funcionales
complejos, tales como transacciones, seguridad, persistencia entre otros, a todos los
componentes. Estos servicios pueden ser utilizados por el desarrollador de manera
declarativa facilitando así el desarrollo de las aplicaciones.

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE


2 Gerson Samaniego, José Pulido

En otros modelos de componentes, los requerimientos no funcionales son expresados


como capas de control que se pueden extender como en Fractal [5], o definidos en un
lenguaje de aspectos por ejemplo en AspectJ2EE [25] para los EJBs o FractNet [15] para
Fractal en .net.
La programación orientada a aspectos (AOP) [2], tiene como objetivo permitir el
aislamiento, la composición y eficaz reutilización de código transversal presente en una
aplicación. Basados en las propuestas, CBSD y AOP, se han planteado modelos de
integración como el presentado en [17], cuyo objetivo principal es crear modelos que
unan los componentes y los aspectos.
Nuestra propuesta busca separar los aspectos funcionales de los no funcionales y
proveer una forma de composición que los relacione, basándonos en CBSD y AOP. Se
crean componentes funcionales (CF) y componentes no funcionales (CNF) como
elementos independientes.
Para la composición entre el CF y los CNFs, definimos un mecanismo que expresa la
interacción de forma externa a los componentes, mediante un lenguaje de dominio
específico orientado a aspectos. El lenguaje permite establecer el orden de llamado a los
diferentes componentes (funcionales y no funcionales).
En el grupo de construcción de software de la Universidad de los Andes se ha
desarrollado un modelo de componentes distribuidos que viven en una red de nodos
llamado Gaita [19], [13], [27]. El modelo resuelve la localización de los servicios e
instancias de forma transparente para el desarrollador. Es sobre dicho modelo que hemos
realizado una propuesta para incluir requerimientos no funcionales.
El caso de estudio utilizado en nuestra propuesta es una aplicación de comercio
electrónico que incluye: proveedores, despachadores, intermediarios y sistemas
electrónicos de pagos en línea; estos se representaron en componentes funcionales y se
incluyó el manejo de ciclo de vida, persistencia y seguridad; definidos en componentes
no funcionales (CNF).
Para el desarrollo de esta propuesta en primer lugar analizamos la caracterización del
problema y su respectivo caso de estudio, en segundo lugar realizamos una breve
introducción al modelo de componentes Gaita, para posteriormente presentar nuestra
estrategia con la solución al problema planteado y los detalles de implementación. En la
sección siguiente describimos algunos trabajos relacionados y finalmente, conclusiones y
trabajos futuros.

2 DESCRIPCIÓN DEL PROBLEMA

Para ilustrar los diferentes problemas y la estrategia de solución, presentamos un caso de


estudio para una aplicación de comercio electrónico (E-Commerce) como se muestra en
la figura 1, incluye: proveedores de productos, despachadores de paquetes, un
intermediario y sistemas electrónicos de pagos en línea.
En los proveedores de productos debe ser posible recibir órdenes y manejar el
inventario de los productos. Los despachadores de productos permiten enviar órdenes de
clientes a diferentes destinos.

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE


Composición de Requerimientos No Funcionales 3

El intermediario es una aplicación típica de mediación en línea que sirve para


encontrar productos asociados a catálogos de proveedores por categorías y realizar envíos
de paquetes a un destino a través de los despachadores.

Figura 1: Aplicación de comercio electrónico


Adicionalmente, la aplicación debe tener un sistema de almacenamiento de los datos;
ofrecer un nivel de seguridad aceptable, que permita autenticar a los usuarios frente al
sistema para acceder a los servicios; garantizar la integridad y consistencia de datos
cuando se realice una operación. Los ítems anteriores representan los Requerimientos No
Funcionales de la aplicación.
En la actualidad, el manejo de los RNFs es una tarea que se ha dejado a los modelos
de componentes. Ellos resuelven la lógica no funcional usando diferentes técnicas.
Los modelos orientados al contenedor como EJB [24], CORBA Componente Model
(CCM) [24] y Microsoft .NET [16], separan los requerimientos funcionales de los
requerimientos no funcionales dejando el manejo de los últimos a al contenedor. Este,
simplifica el desarrollo de aplicaciones permitiendo a los desarrolladores usar los RNFs
de forma declarativa. El modelo de componentes Fractal [5] propone el manejo de los
RNFs agregando una membrana o capa de control a cada componente. Se puede ver dicha
membrana como si cada componente tuviese su propio contenedor.
Las soluciones mencionadas son algunas de las más comunes, sin embargo, no llenan
completamente las expectativas en cuanto a lo esperado por el CBSD. En los modelos
orientados al contenedor, los aspectos no funcionales que éste ofrece, pueden no aplicar
en escenarios que impliquen necesidades específicas. Algunos de estos modelos permiten
agregar nuevas características no funcionales mediante técnicas de interceptores, pero no
se pueden extender las existentes. Los componentes son dependientes de contexto al
depender de un contenedor específico. Por otra parte, en Fractal sólo se define una
metodología para el desarrollo uniforme de los elementos, y el desarrollador debe realizar
la implementación de las interfaces que forman la membrana de control. Se han
propuesto diferentes soluciones en Fractal similares a las planteadas en éste trabajo, en
las que se usan técnicas de AOP para separar preocupaciones transversales asociadas a
RNFs de la lógica funcional, por ejemplo FAC [17]. Este trabajo presenta una propuesta,
también basada en los principios de AOP, que se acerca más a los objetivos del CBSD.
La validación de la propuesta se realiza sobre el modelo de componentes Gaita. Este,
ofrece localización transparente de servicios y otras características CBSD, pero no cuenta
con soporte a requerimientos no funcionales.

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2


4 Gerson Samaniego, José Pulido

3 MODELO DE COMPONENTES GAITA

En ésta sección, se describe brevemente el modelo de componentes sobre el que se


prueba nuestra solución. Gaita es un modelo de componentes distribuidos no jerárquicos
que viven en una red de nodos. Gaita resuelve la localización de los servicios y sus
instancias de forma transparente mediante la comunicación entre los nodos de la red y la
consistencia de los elementos definida en el modelo [12].

Componentes
Representan funcionalidades que pueden estar expresadas en términos de contratos
ofrecidos (facetas), contratos requeridos (receptáculos) y un conjunto de fábricas que
permiten instanciar el componente. La figura 2 muestra un ejemplo de componente:

Figura 2: Componente en Gaita-S

Conectores
Los componentes en Gaita se comunican por medio de conectores. Un receptáculo de un
componente espera poder ser resuelto por la faceta de otro. El Conector es el elemento
encargado de unir el receptáculo y el componente. El conector puede encerrar la lógica de
localización de los componentes requeridos, ocultando dicho trabajo al componente. De
ésta forma, el componente tiene sólo la lógica que le corresponde.

Lenguaje de Definición de Componentes


Actualmente Gaita cuenta con un lenguaje de definición de Componentes (CDL) que
permite definir tanto componentes simples, cuya implementación es una clase Java, como
componentes compuestos, en donde la implementación es la composición de
componentes predefinidos.

Figura 3: Ejemplo de componente compuesto (Calculadora)


En la figura 3, se muestra un ejemplo de componente compuesto llamado Calculadora,
cuya implementación es resuelta por los componentes internos Sumador y Multiplicador.

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE


Composición de Requerimientos No Funcionales 5

Aplicaciones Basadas en Componentes

Son aplicaciones cuya implementación es una red de componentes ensamblados:


componentes unidos por sus interfaces (facetas y receptáculos). El Desarrollador de
Aplicaciones Basadas en Componentes se encarga de ensamblar la aplicación utilizando
componentes ya creados, resolviendo sus dependencias y creando nuevos componentes
compuestos si es necesario. La aplicación resultante no debe tener receptáculos sin
resolver.

E-Commerce con componentes Gaita


La primera tarea del diseñador de componentes consiste en distribuir la funcionalidad del
mismo en uno o varios componentes. Nosotros identificamos ciertos componentes
funcionales en la aplicación E-commerce, como se muestra en el diagrama de
componentes de la figura 4.

Figura 4: Diagrama de componentes.


La figura muestra los componentes y sus relaciones en la aplicación de comercio
electrónico donde un cliente realiza sus operaciones a través del componente
intermediario. En el diagrama de diseño mostrado, sólo están los componentes
funcionales. Para que la aplicación pueda ser ejecutada en un entorno real, hacen falta
adicionar RNFs tal y como se mencionó en el problema.

4 ESTRATEGIA DE SOLUCIÓN

Nuestra propuesta para incluir RNF, busca principalmente cumplir con algunas de las
premisas del CBSD relacionadas con los componentes: independencia del contexto,
comunicación por medio de las interfaces, separación de responsabilidades y
reutilización. En cuanto a la separación de responsabilidades, se intenta separar las
preocupaciones transversales asociadas a RNFs mediante técnicas de AOP.
La separación de la lógica funcional de la no funcional tiene varias ventajas [2]:
código menos enredado, fácil de depurar y mantener, reutilización de la lógica no
funcional, el desarrollador sólo se centra en la lógica funcional, etc.

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2


6 Gerson Samaniego, José Pulido

Composición de Componentes
La propuesta se basa en composición de componentes no funcionales con
componentes funcionales1 y en la expresión de la interacción entre ellos de manera
externa (usando sus interfaces). Se trata de agregar lógica no funcional a un componente,
componiendo éste con otros predefinidos que ya implementan lógica no funcional. Por
ejemplo, si se quiere agregar manejo de seguridad al componente intermediario de E-
Commerce - CF (Componente Funcional), se asocia éste con un componente de seguridad
- CNF (Componente No Funcional) como se muestra en la figura 5.

Figura 5: Composición con Componentes No funcionales

El resultado es un nuevo componente con las facetas funcionales iniciales. En algunos


casos pueden aparecer nuevas facetas producto de la adición de la lógica no funcional.

Componentes No Funcionales
Cuando un desarrollador de RNFs identifica la necesidad No funcional, lo primero que
debe hacer es encapsularla en un componente con interfaces bien definidas (el CNF). Por
ejemplo, un CNF de seguridad puede ofrecer servicios como autenticación y autorización,
un CNF de persistencia servicios como guardar, actualizar y consultar. Los servicios
ofrecidos por los CNFs deben ser genéricos, es decir, no dependen de los CF finales, para
así permitir la reutilización.

Componentes Funcionales
Un punto clave de la propuesta es que tanto el CF como el CNF se desarrollan sin
conocerse. Una vez creado el CF, solo se puede aplicar lógica no funcional usando sus
interfaces, evitando la intrusión sobre su implementación. Con ésta limitación, es posible
que no todos los RNF puedan ser aplicados, pero es una forma de garantizar
desacoplamiento y reutilización.

Interacción Entre Componentes


Partiendo de la composición de ejemplo en la figura 5, surgen ciertas preguntas: ¿Cómo
se relacionan el CF y el CNF? ¿Qué pasa cuando se invoca un servicio sobre el nuevo
componente CF’? ¿En qué punto interviene la lógica no funcional? ¿Cuál es el orden de
llamados? La interacción entre los componentes encierra la solución a los interrogantes

1
Katalina Marcos [14], presenta en su tesis la composición de requerimientos no funcionales mediante
patrones de composición

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE


Composición de Requerimientos No Funcionales 7

anteriores. Para resolver dicha interacción es necesario un nuevo componente mediador


capaz de interceptar los llamados al CF para aplicar la lógica no funcional del CNF.

Figura 6: Mediador de la interacción


El mediador mostrado en la figura 6 es un componente generado mediante técnicas de
AOP con la ayuda de un lenguaje de dominio específico llamado ISL (Interaction
Specification Lenguage) 2 que hace parte de nuestra propuesta de solución. La interface
del mediador (ICF’) es la misma exportada por el nuevo componente, y por lo tanto, debe
contener los métodos de ICF. La implementación de los métodos del mediador debe
resolver el orden de llamados entre los diferentes componentes.

Lenguaje de Interacción: ISL


El ISL es un Lenguaje Orientado a Aspectos (DSAL – Domain Specific Aspect
Language). Los lenguajes orientados a aspectos buscan resolver el problema de los RNFs
modificando la secuencia normal de ejecución de un programa para agregar la lógica no
funcional [2]. La secuencia de ejecución se modifica con base en condiciones específicas
del entorno de ejecución: si una condición se cumple, se ejecutan las acciones necesarias
[7].
En AOP se usan diferentes formas de cuantificación (formas de especificar las
condiciones [21]), la principal de ellas está asociada a la invocación de métodos: poder
ejecutar acciones cuando un método de una clase es invocado. De ésta forma se puede
interceptar la secuencia del programa y ejecutar instrucciones antes o después del
método, o reemplazar por completo su ejecución. Éste es el concepto en el que se basa
nuestra solución. En nuestro caso, podemos interceptar los llamados a los servicios de los
componentes y también los eventos de su creación y destrucción. Un ejemplo en el
lenguaje AspectJ [26]:
before() : call(public * Prueba.set* (..)){
System.out.println("Setter invocado");
}

En el ejemplo anterior, cada vez que se invoque un método de la clase “Prueba” cuya
firma cumpla con las siguientes condiciones: el nombre empieza por “set”, puede tener
cualquier parámetro, esté definido como público y devuelva cualquier tipo, se ejecutará
primero la instrucción:
System.out.println("Setter invocado");
La expresión que permite cuantificar recibe el nombre de Pointcut y las acciones que se
ejecutan cuando se cumple la condición se conocen como Advice. Estos términos se
profundizan más adelante.

2
La idea original de expresar la interacción mediante un lenguaje la mostraron Anis Charfi, Michel Riveill
y Mireille Blay-Fornarino en Transparent and Dynamic Aspect Composition. [1]

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2


8 Gerson Samaniego, José Pulido

No existe ninguna diferencia de estructura entre el ISL y los lenguajes tradicionales


de AOP, por lo tanto, la sintaxis de éste es una adaptación de AspectJ [26]. La semántica
varia: en AspectJ la unidad base del lenguaje (Aspect) representa el aspecto transversal en
la aplicación mientras que en el ISL la unidad base es la interacción y los aspectos están
encapsulados en los CNFs.
En nuestra solución, el rol encargado de describir la interacción mediante el ISL es el
desarrollador de RNFs, por lo tanto, él provee tanto el CNF como la expresión de la
interacción con cualquier CF.
En el ejemplo de AspectJ mostrado anteriormente, se puede definir el Aspecto
conociendo los métodos de la clase “Prueba”. En nuestra solución, por tratarse de algo
más general, el desarrollador de RNFs no conoce el CF objetivo lo que implica que no
conoce sus servicios. Para ello, se propone expresar la interacción con base en
propiedades asociadas a los servicios del CF.
Las propiedades son meta-data adicional asignada al CF y especificada por el
desarrollador de RNFs. Por ejemplo, un CNF de seguridad puede necesitar de
información que indique los roles de usuario que pueden acceder a un servicio. Las
propiedades describen dicha información mediante sus atributos. Para el ejemplo
mencionado, puede existir la propiedad RolesAllowed y uno de sus atributos sería roles,
el cual tiene la lista de los roles permitidos. Las propiedades pueden estar asociadas tanto
al componente como a sus servicios.
La figura 7 resume la interacción con un ejemplo de Seguridad:

Figura 7: Interacción y propiedades


En el caso de estudio, el servicio crearOrden del componente Intermediario, puede
tener asociada la propiedad RolesAllowed y el atributo roles puede ser igual a: admin,
client, etc. De igual forma, la propiedad asociada al componente puede ser Stateful, que
indicaría que el componente tiene un ciclo de vida con estado. Un componente puede ser
persistente, en el caso de los productos de los proveedores, y para ello el componente
Producto podría tener asociada la propiedad Persistent o Entity.
Tipos de interacción
Cuando un desarrollador de RNFs crea un CNF, expresa la interacción de éste con un
sólo CF. Dicha interacción (uno a uno) es conocida como Interacción Básica. Con la
interacción básica y las propiedades, un cliente de la solución provista, puede aplicar
lógica no funcional a un CF. Si quiere aplicar más de un RNF a su CF lo puede hacer,

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE


Composición de Requerimientos No Funcionales 9

aplicando uno después de otro, por ejemplo: aplica Logger y obtiene su CF’ con
funcionalidad de logging; aplica seguridad a su CF’ y obtiene su CF’’ con funcionalidad
de logging y seguridad, y así sucesivamente.
Es posible que la interacción básica e incluso la secuencia de ellas, no sea suficiente
en escenarios más complejos. Por ejemplo, en E-Commerce pueden interferir más de un
RNF a la vez, en el momento de ejecutar una orden de pedido: el Intermediario tiene ciclo
de vida con estado, seguridad y logger, el Proveedor tiene estado persistente y seguridad,
el componente de Pagos tiene seguridad y logger, y todos deben tener en cuenta el
manejo transaccional distribuido. Para resolver casos más complejos de interacciones
nuestro modelo se puede extender creando interacciones complejas que permitan
expresar la relación del CF con más de un CNF a la vez.
No hace parte del presente trabajo indicar la forma correcta de la aplicación de los
RNFs ni el control de las posibles interferencias al aplicar más de uno a la vez. Un
desarrollador de aplicaciones basadas en componentes debe ser conciente de las
complejidades que surgen mientras ensambla su aplicación con lógica no funcional.
Programación Orientada a Aspectos en el ISL
Antes de mostrar un ejemplo de interacción en el ISL definiremos algunos conceptos
adoptados de AOP:
Join-Points: Son puntos bien definidos que se pueden interceptar en el flujo del
programa. Inicialmente, nuestro lenguaje sólo soporta los Join-Points que son alcanzados
cuando:
- Se crean nuevas instancias del un componente
- Se liberan instancias de un componente
- Se invocan servicios (métodos) del componente
Pointcuts: Permiten seleccionar o filtrar JoinPoints. Los pointcuts están orientados a
las propiedades asignadas a los servicios de los componentes. Trabajos parecidos en AOP
donde se intercepta con base en propiedades o meta-data, los podemos encontrar en
Aspectivity [22] y AspectJ 5. El siguiente es un ejemplo de pointcut:
pointcut logging() : call(@LogMessage);
En el ejemplo, se define el pointcut logging que selecciona los joinpoints alcanzados
cuando se invoca la ejecución de cualquier método al que se haya asignado la propiedad
LogMessage.
Pointcuts soportados por el ISL:
- call(@Propiedad): pointcut asociado a la invocación de un servicio en el que
esté presente la propiedad dada.
- if(condicion): permite evaluar los valores de las propiedades
- creation(@Propiedad): asociado a la creación de instancias del componente
- destruction(@Propiedad): asociado a la destrucción de instancias del
componente
- @Property(propiedad): pointcut primitivo que permite asignar la propiedad
del contexto a la variable propiedad definida como parámetro del pointcut.

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2


10 Gerson Samaniego, José Pulido

Advices: Junto con los pointcuts, definen el punto exacto a interferir (Antes, después
o reemplazo) más las instrucciones a ejecutar cuando el Join-Point sea alcanzado. El
código (Java) del cuerpo del advice resuelve la interacción entre los componentes.
Ejemplo de interacción del CNF de seguridad:
package uniandes.gaita.rnf.Security;

import uniandes.gaita.rnf.security.property.RolesAllowed;
import uniandes.gaita.rnf.security.cnf.ISecurity;
import uniandes.gaita.rnf.security.interaction.ISecurityAux;

public interaction Security implements ISecurityAux{

@InternalReceptacle("SecurityService")
private ISecurity security;

@Receptacle
private ISecurityAux security;

pointcut secure(RolesAllowed ra): call(@RolesAllowed) && @property(ra);

around(RolesAllowed ra) : secure(ra) {


if (security.validate(ra.roles()){
proceed();
}else{
System.out.println("Permiso Denegado");
}
}

public boolean login(String user, String pwd){


security.login(user, pwd);
}
}

En el ejemplo, se validan los permisos de un usuario para ejecutar los servicios de


un CF que tengan la propiedad @RolesAllowed. Los CNFs son referenciados mediante
su Interface (ISecurity) y dicha referencia se agrega como atributo de la interacción. La
anotación @InternalReceptacle permite definir la implementación del CNF Security y
la posterior inyección de la dependencia. La anotación @Receptacle permite definir
nuevos receptáculos del componente resultado. La interacción, al igual que en AspectJ,
también puede tener atributos y métodos propios. En el ejemplo se agrega el método
login que es parte de la Interface ISecurityAux para ofrecer dicho servicio a los clientes
del componente compuesto.
La palabra clave del lenguaje es interaction y describe el inicio de un conjunto de
pointcuts y advices que permiten expresar la forma en que interactúan los CF y los CNFs.
Es el equivalente al Aspecto (aspect) en AspectJ. Algunos elementos del ejemplo se
entenderán mejor después de la siguiente sección.

Mediadores
El mediador, al igual que en otros modelos de componentes (EJB por ejemplo), es un
componente que se antepone a los llamados del cliente sobre el CF para ejecutar la lógica
adicional necesaria. El cliente final recibe una instancia del mediador y no del CF como
tal (aunque él no lo sabe). El componente es generado cuando se interpreta la interacción.
El código Java de los advices forma parte de los métodos del mediador. Cuando un
método del CF necesita de lógica no funcional (porque una propiedad asociada a él así lo
describe) dicha lógica queda en el método equivalente en el mediador.

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE


Composición de Requerimientos No Funcionales 11

El mediador puede implementar otras interfaces si la interacción así lo describe. Los


métodos de las interfaces implementadas formarán parte de los servicios que ofrecerá el
componente compuesto. Ver el método login de la Interface ISecurityAux del ejemplo
mostrado en la sección anterior.
Existen dos tipos de mediadores: los que intervienen los eventos del ciclo de vida del
componente y los que intervienen los llamados a los servicios del componente.
Un mediador a nivel de Ciclo de Vida permite resolver la instancia adecuada que se
va a entregar a un cliente ayudándose de un CNF de Ciclo de Vida. Este tipo de mediador
es conocido como Home.
Un mediador a nivel de servicio permite interceptar cualquier invocación a un
método o servicio del componente. Esto implica que dicho mediador debe implementar la
misma Interface del componente objetivo, o por lo menos, una que herede de ella. La
decisión de si un método se intercepta o no, y las acciones a tomar a en caso de
interceptarlo dependen de la interpretación del ISL. Este tipo de mediador es conocido
como Interceptor.

Figura 8: Mediadores en Pagos Seguro

En la figura 8 se muestran los mediadores generados para el ejemplo de seguridad


mostrado en la sección anterior y aplicado al componente Pagos de E-Commerce.
Aparecen dos nuevas interfaces no funcionales: IPagosHome e ISecurityAux. La primera
tiene los métodos que permiten controlar el ciclo de vida del nuevo componente y la
segunda, que aparece como faceta y como receptáculo, es generada a partir de la
interacción para permitir funcionalidades como: login de usuarios, paso de contextos de
seguridad, etc.

Resumen de la solución
Para la ejecución de la propuesta se define un marco de trabajo basado en los diferentes
roles que intervienen. Básicamente, se busca abstraer de la complejidad del manejo de los
RNF a los desarrolladores finales, quienes pueden crear su CF sin pensar en la lógica No
Funcional.

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2


12 Gerson Samaniego, José Pulido

Figura 9: Roles en la solución


En la figura 9, un desarrollador final de componentes crea su componente funcional sin
pensar en el manejo de RNFs. Por otra parte, un desarrollador de RNFs crea los CNFs y
los deja en un repositorio junto con la especificación de las propiedades y la interacción
básica. Un tercer desarrollador (desarrollador de aplicaciones basadas en componentes) se
encarga de integrar las soluciones de los dos primeros, aplicando interacciones básicas a
componentes funcionales o creando sus propias interacciones (interacciones complejas)
según las necesidades de la aplicación.

Solución en E-Commerce
Con base en la solución provista, se implementaron algunos RNF para el caso de estudio
del presente artículo. Intermediario, Proveedor y Despachador son componentes
funcionales orientados a servicios, y sobre ellos se aplicaron seguridad, logger y manejo
de estados. Destino, Producto y Cuenta son componentes funcionales que representan
entidades del negocio, y sobre ellos se aplicó persistencia. El requerimiento no funcional
de transacciones no se tuvo en cuenta en ésta primera aproximación.

5 IMPLEMENTACIÓN

Las propiedades se establecen en archivos XML y se especifican mediante esquemas


XSD. Por facilidad y compatibilidad, las propiedades también pueden ser especificadas
con anotaciones de Java 5 [23]. Las propiedades podrían ser definidas en el lenguaje de
definición de componentes (CDL).
Los mediadores son generados a partir de la interpretación de la interacción mediante
plantillas de Velocity. El trabajo lo realiza un motor de interacción de forma estática, en

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE


Composición de Requerimientos No Funcionales 13

el sentido de que las propiedades no pueden cambiar en tiempo de ejecución, lo que


implica que tampoco los enlaces de los componentes cambien. Cuando el motor de
interacción interpreta el ISL se obtiene la red de componentes. Luego, usando el CDL, se
expresa la composición del nuevo componente con lógica no funcional y se pasa dicha
definición al motor de composición.

6 TRABAJOS RELACIONADOS

En esta sección presentamos los principales modelos de componentes: EJB [24], CORBA
CCM [18], Microsoft .NET [16] y Fractal[5]. Mostramos una breve introducción a la
programación orientada a aspectos AOP[2] y comparamos estos trabajos con nuestra
solución.
Los modelos de componentes comerciales como EJB[24], .NET[16], CCM[18],
COM+[11] usan el concepto de contenedores de software para soportar el manejo de
algunos los requerimientos no funcionales (seguridad, transacciones, persistencia y ciclo
de vida).
Para que el contenedor pueda manejar los componentes, estos deben cumplir con
características especiales de cada implementación perdiendo interoperabilidad de los
mismos con otros modelos de componentes. Generalmente los modelos orientados a
contenedor “no hacen explícito el modelo del mundo no funcional que implementan” [13]
(sólo permiten interactuar con ellos de forma declarativa).
Otros modelos de componentes como fractal (modelo de componentes jerárquico)
[5] definen una membrana que interactúa con las propiedades internas y el conjunto de
subcomponentes que posee. El manejo de los requerimientos no funcionales está
representado en la membrana que provee la capa controladora del componente. Tiene la
facilidad de incluir nuevas interfaces de control para requerimientos adicionales. Pero la
implementación de la membrana de control está asociada a cada componente y no puede
ser definida independientemente para su reutilización en otros componentes.
En nuestra solución, los servicios no funcionales son expresados como componentes
independientes del contenedor y pueden ser compuestos con CFs y CNFs.
Por otro lado, la programación orientada por aspectos (AOP)[2] busca la separación
de propiedades funcionales y no funcionales que forman una aplicación. AOP disminuye
la dependencia entre los componentes funcionales y no funcionales, promueve el
reuso[20], facilita el desarrollo y la evolución del componente. AOP provee mecanismos
de composición transparentes y flexibles (principalmente a nivel de programación). En
este sentido, utilizamos el concepto de la AOP para aplicarlo a los componentes tipo caja
negra, con el fin de definir en el lenguaje ISL la interacción entre los componentes
funcionales y no funcionales.
Por su estrategia y madurez la AOP ha sido utilizada en aplicaciones JEE como se
muestra en el artículo AspectJ2EE [25] aplicado a componentes EJB. También los
encontramos en el modelo de componentes Fractal (implementaciones AOKell y
FractNet [15] ) y FAC[17]. Otro ejemplo interesante presentado en [9][10] del lenguaje
de dominio específico KALA para separar las preocupaciones relacionadas con los
sistemas de manejo de transacciones avanzadas ATMS.

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2


14 Gerson Samaniego, José Pulido

En nuestro trabajo tomamos como base el lenguaje de aspectos AspectJ, para definir
el lenguaje de dominio específico ISL que expresa la interacción entre componentes
funcionales y no funcionales.

7 CONCLUSIONES

En este artículo, hemos propuesto la integración de algunos requerimientos no


funcionales estableciendo propiedades a los componentes no funcionales (CNFs) de
forma no intrusiva; mediante metadata y la utilización del lenguaje ISL para expresar la
interacción entre ellos. Este enfoque, nos permite tener repositorios de componentes no
funcionales reutilizables, configurables e independientes de los componentes funcionales.
Con base en la investigación, concluimos que al realizar la especificación de
propiedades de los componentes independientemente a su desarrollo promovemos la
reutilización, se puede agregar o quitar un CNF del modelo y se identifica claramente
cada los roles en el desarrollo de los componentes.
Adicionalmente, el desarrollador de componentes funcionales por lo general, no se
debe preocupar por los requerimientos no funcionales que se apliquen posteriormente a
sus componentes. Hay flexibilidad de definir los servicios a los cuales se les aplica un
determinado RNF mediante la especificación de propiedades y el modelo de interacción.
Por la complejidad y características especiales de los RNFs no es posible generalizar
una solución que los incluya a todos. En nuestra propuesta tratamos únicamente los
requerimientos no funcionales que puedan ser expresados como componentes de forma
independiente al servicio funcional y que sus relaciones con el componente funcional
objetivo sean claramente identificadas. Aunque la idea es que el desarrollador de los
componentes funcionales no piense a la lógica no funcional, en algunos casos es
necesario que sus implementaciones cumplan ciertas condiciones. Por ejemplo, para
poder persistir un componente, éste debe tener métodos para recuperar y establecer los
datos.
Así mismo, no todos los requerimientos no funcionales los podemos expresar de
forma independiente (ejemplo persistencia y transacciones) y en otros casos se identifican
conflictos o dificultades para ser modelados como componentes.

8 TRABAJO FUTURO

Con base en el trabajo expuesto en el artículo, se hace necesario identificar las


interferencias que se puedan presentar en las interacciones entre los componentes que
conforman una aplicación. De igual forma, es útil para el modelo incluir patrones de
composición que puedan ser reutilizados con diferentes componentes.
En nuestra propuesta la configuración de propiedades asociadas a los requerimientos
funcionales se hace de forma estática. Otra alternativa sería incluir las propiedades en
tiempo de ejecución creando mediadores que realicen el cargue de las mismas.
Adicionalmente, las propiedades podrían estar definidas en el lenguaje de definición de
componentes (CDL).

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE


Composición de Requerimientos No Funcionales 15

En el modelo Gaita-NF se incluyeron los requerimientos no funcionales básicos para


el manejo de ciclo de vida, seguridad y persistencia. Sería importante seguir con el
trabajo para incluir nuevos requerimientos no funcionales al modelo.

REFERENCIAS

[1] A. Charfi, M. Riveill, M. Blay-Fornarino, and A. Pinna-Dery, "Transparent and


Dynamic Aspect Composition," Presentado en SPLAT Worshop, Bonn, Germany,
March 2006.
[2] A. M. R. Quintero, “Visión General de la Programación Orientada a Aspectos,”
Departamento de Lenguajes y Sistemas Informáticos, Facultad de Informática y
Estadística, Universidad de Sevilla, Reporte técnico. Diciembre 2000.
[3] C. Szyperski, D. Gruntz, and S. Murer. Component Software - Beyond Object-
Oriented Programming, Addison-Wesley / ACM Press, 2002. pp. 3-15.
[4] ComponentSource. What are components?. (2008, febrero). Disponible:
http://www.componentsource.com/Services/WhatAreComponents.asp?bhcp=1.
[5] E. Bruneton, T. Coupaye, J. B. Stefani. (2004). Specification The Fractal Component
Model. [AEn línea]. Disponible: http://fractal.objectweb.org.
[6] F. Bachmann, L. Bass, C. Buhman, D. Comella, and F. Long. (2000). Volume. II:
Technical Concepts of Component-Based Software Engineering. Software
Engineering Institute, Carnegie Mellon University, Pittsburgh, PA. [AEn línea]. pp.
15-20. Disponible: http://www.sei.cmu.edu/staff/kcw/00tr008.pdf
[7] F. Duclos, J. Estublier, and P. Morat. "Describing and using non functional aspects in
component based applications," Presentado en International Conference on Aspect-
Oriented Software Development, Enschede The Netherlands, April 2002.
[8] J. A. Montilva C., N. Arapé, and J. A. Colmenares, "Desarrollo de Software Basado
en Componentes," Actas del IV Congreso de Automatización y Control
(CAC’2003), Mérida, Venezuela, Noviembre, 2003.
[9] J. Fabry and N. Pessemier, "KALA: A Domain-Specific Solution to Tangled Aspect
Code," Domain-Specific Aspect Languages 06 Workshop at GPCE06, Portland,
Oregon, October 2006.
[10] J. Fabry and T. D’Hondt, “A Family of Domain-Specific Aspect Languages on Top
of KALA,” Open and Dynamic Aspect Languages Workshop At AOSD 2006,
Bonn, Germany, March 20, 2006.
[11] J. Lowy, and J. Lö WY. "COM and .NET Component Services: Migrating from
COM+ to .NET," Sebastopol, CA, USA: O’Reilly & Associates, Inc., 2001.
[12] J. Villalobos, R. Casallas, K. Marcos, P. Barvo, and C. Rocha, "Gaita-s: Model
specification," Universidad de los Andes, Bogotá. Documento técnico, 2005.
[13] K. Marcos B. Gaita-nf: Un Modelo de Composición de Componentes Funcionales
con Servicios No Funcionales. Bogotá, 2005. Tesis (Magíster en ingeniería de

PARADIGMA - REVISTA ELECTRONICA EN CONSTRUCCIÓN DE SOFTWARE VOL. 2 / NUM.2


16 Gerson Samaniego, José Pulido

sistemas). Universidad de los Andes. Facultad de Ingeniería. Departamento de


Ingeniería de Sistemas.
[14] L. Fuentes, J. M. Troya y A. Vallecillo, Desarrollo de Software Basado en
Componentes. Depto. Lenguajes y Ciencias de la Computación. Universidad de
Málaga. Disponible: http://www.lcc.uma.es/~av/Docencia/Doctorado/tema1.pdf
[15] L. Seinturier, N. Pessemier, C. Escoffier, D. Donsez, "Towards a Reference Model
for Implementing the Fractal Specifications for Java and the .NET Platform,"
Presentado en Fractal Workshop ECOOP, Nantes (France), 2006.
[16] Microsoft.(2008, feb.). .NET Framework. http://msdn.microsoft.com/netframework/
[17] N. Pessemier, L. Seinturier, L. Duchien, T. Coupaye. A Component-Based and
Aspect-Oriented Model for Software Evolution. International Journal of Computer
Applications in Technology 31, 1-2 (2008) 94-105.
[18] OMG. (2006, May.). CORBA Component Model Specification, v4.0. [AEn línea].
Disponible: http://www.omg.org/docs/formal/06-04-01.pdf
[19] P. J. Barvo. Izaza. Diseño e implementación del motor del modelo de servicios
Gaita-S V0. Bogotá, 2005. Tesis (Pegrado). Universidad de los Andes. Facultad de
Ingeniería. Departamento de Ingeniería de Sistemas.
[20] P. J. Clemente, J. Herández and F. Sánchez. “Extending Component Composition
Using Model Driven and Aspect-Oriented Techniques,” Journal of software, vol. 3,
No. 1, January. 2008.
[21] R.E. Filman and D.P. Friedman, "Aspect-Oriented Programming is Quantification
and Obliviousness," Presentado en Workshop on Advanced Separation of
Concerns, OOPSLA 2000, Minneapolis, Octuber 2000.
[22] Ramnivas Laddad. (2008, feb.). AspectJ language support for metadata. Disponible
en http://ramnivas.com/blog/index.php?p=10.
[23] Sun Microsystems, Inc.(2004, Sep.). JSR 175: A Metadata Facility for the JavaTM
Programming Language. [AEn línea]. Disponible:
http://jcp.org/en/jsr/detail?id=175
[24] Sun Microsystems, Inc. (2008, March). The Enterprise JavaBeans™ (EJB).
Disponible: http://java.sun.com/products/ejb/
[25] T. Cohen and J. Gil, “AspectJ2EE = AOP J2EE: Towards An Aspect Based,
Programmable and Extensible Middleware Framework,” Presentado en ECOOP
Object-Oriented Programming, Ed., vol. 3086, pp. 219– 243, Springer, 2004.
[26] The AspectJTM 5 Development Kit Developer's Notebook. (2008, feb.). Disponible:
http://www.eclipse.org/aspectj/doc/released/adk15notebook/index.html
[27] Universidad de los Andes. (2008, Feb.). Grupo de Investigación en Construcción de
software – Gaita. Web site, http://chie.uniandes.edu.co/~gaita/doku.php
[28] WebCab Components. (2008, March). About Component Based Development.
Disponible: http://webcabcomponents.com/componentization.shtml.

VOL. 2 / NUM.2 PARADIGMA - REVISTA ELECTRÓNICA EN CONSTRUCCIÓN DE SOFTWARE

También podría gustarte