Coordinación de Objetos Separate en Java
Facultad de Matemática y
Computación.
M. Katrib
Universidad de la Habana
[email protected]
J.L. Pastrana
E.T.S.I.Informática.
Universidad de Málaga
[email protected]
E. Pimentel
E.T.S.I.Informática.
Universidad de Málaga
[email protected]
Resumen
El siguiente trabajo está basado en trabajos previos [1, 3, 4] orientados a la introducción de aserciones
en lenguajes orientados a objetos, como Java y Smalltalk, que no disponen de este tipo de mecanismos, y en
la repercusión que éstos pueden tener en el modelado de la concurrencia. En esta línea, se presenta una
propuesta para la implementación y sincronización de objetos distribuidos en Java usando la metáfora de
“Diseño por Contrato”, adecuando las consideraciones que se establecen en el lenguaje Eiffel para los
objetos “separate”, y reuniendo características como transparencia, corrección, robustez y tolerancia a
fallos. A lo largo del trabajo se expondrán las particularidades de la propuesta, así como determinados
detalles de implementación, y su posible aplicación a lenguajes de definición de interfaces (IDL) para
permitir el desarrollo de componentes que reúnan las características comentadas anteriormente para los
objetos.
1. Introducción
Muchos de los sistemas software que se desarrollan hoy en día, están basados en el paradigma de
programación orientada a objetos y son intrínsecamente distribuidos, por lo tanto, un sistema de software se
puede ver como un conjunto de objetos que cooperan e interactúan entre sí para lograr un objetivo común.
Una de las tendencias actuales en la Ingeniería del Software se basa en la construcción de software utilizando
la noción de componentes como pieza fundamental en el proceso de desarrollo. En [7], Meyer presenta la
metáfora de Diseño por Contrato como una metodología para el desarrollo de software orientado a objetos.
Dicha metáfora se basa en considerar un sistema como una colección de componentes que colaboran del
mismo modo en que lo hacen los negocios que tienen éxito: respetando unos contratos que definen
explícitamente las obligaciones y beneficios que incumben a cada una de las partes. En trabajos previos [1, 3,
4], se aplica dicha metáfora para la coordinación y sincronización de hebras en el contexto de la programación
concurrente en Java o Smalltalk. Partiendo de la experiencia previa en ese campo, la idea central de este
trabajo consiste en el uso de la metáfora del contrato para la integración, coordinación y sincronización de
objetos y/o componentes distribuidos (que se encuentran en diferentes procesadores lógicos) y a los que
llamaremos objetos separate [7].
Los términos en que se establecerán los contratos serán expresados mediante asertos de tres tipos:
precondiciones, postcondiciones e invariantes. Cada método ofrecido por una clase y ejecutado a través de sus
objetos exige el cumplimiento de una condición (precondición) por parte del cliente y a cambio garantiza una
condición (postcondición) que se cumplirá al terminar la ejecución del servicio. Además de estos “contratos
particulares” entre cada servicio de la clase proveedora y la clase cliente, la clase proveedora asegura un
invariante o condición que será satisfecha por los objetos de la clase proveedora cada vez que se relacionen
con la clase cliente.
Junto con la mejora, respecto a los trabajos anteriores, consistente en que los objetos separate sean
realmente distribuidos y no se ejecuten en diferentes procesadores lógicos dentro de la misma máquina física,
en este trabajo se extiende la semántica del contrato de manera que pueda ser usada para garantizar la
sincronización de objetos separate. Esta sincronización se realizará a través objetos especiales llamados
objetos de sincronización e implementados usando la tecnología JavaSpace [2], que es una herramienta para
el desarrollo y coordinación de sistemas distribuidos en Java, basada en las tuplas de Linda, y que nos ofrece
espacios compartidos que son accesibles a través de una red para ser usados como repositorios de objetos.
Dichos objetos, que serán detallados con posterioridad, permitirán garantizar un conjunto de
características esenciales como la exclusión mutua, justicia (cualquier objeto que desee acceder a un objeto de
sincronización debe ser capaz de hacerlo en un intervalo finito de tiempo) y ausencia de bloqueos. En este
campo, se resuelven los problemas de eficiencia existentes en los trabajos anteriores respecto a la evaluación
de las precondiciones y apropiación de los recursos.
Aunque nuestro trabajo está basado en lenguajes orientados a objetos, es fácilmente extensible al campo
de las plataformas de componentes, ya que (según algunos autores) una componente puede verse como un
paquete o un objeto que engloba o encapsula a un conjunto de objetos y servicios.
A lo largo de siguiente trabajo se expondrá la visión del Diseño por Contrato para objetos distribuidos
junto con su implementación en el lenguaje Java y diversos ejemplos que ilustran el funcionamiento de la
propuesta. Se finalizará con un conjunto de conclusiones y trabajos futuros.
2. Diseño por Contrato de Objetos Distribuidos: Una visión en Java
En esta sección, se introducirán los conceptos que van a ser utilizados a lo largo de la propuesta, relativos
a la manipulación de objetos distribuidos (que, a partir de ahora, serán denominados objetos separate,
utilizando la terminología Eiffel). Al mismo tiempo, se irán introduciendo el paralelismo con los mecanismos
utilizados en Java para incorporar la funcionalidad deseada.
2.1 Objetos Separate
Según Meyer, un objeto separate (que puede ser definido en Java como un objeto de una clase que
implementa un determinado interfaz llamado Separate) es un objeto que será gestionado por otro procesador
(físico o lógico). Nuestro trabajo asumirá que dicho objeto existe y está activo. Esto es debido a que los objeto
separate van a ser implementados mediante servidores RMI que serán objetos activables [9].
Como restricción a los objetos separate se impondrá que dichos objetos tengan sus atributos o variables de
instancia como privados y sólo podrán ser consultados/modificados por sus métodos. Esta restricción, a parte
de ser una recomendación metodológica general en la ingeniería de objetos, nos permitirá poder asegurar la
consistencia del estado de los objetos, ya que sus atributos no podrán ser modificados directamente sin el
cumplimiento de los contratos que se impongan. Más adelante veremos detalles de su implementación.
2.2 Objetos de Sincronización
Un objeto de sincronización es un tipo especial de objeto (que implementa un interfaz Synchronizer u
otra interfaz que herede de ésta) que será el encargado de sincronizar los diferentes objetos separate que
actúan en una aplicación. El comportamiento de estos objetos es comparable al de los tokens que dan acceso
a un recurso compartido en sistemas distribuidos pero con la característica añadida de que el propio recurso
está encapsulado en el token. Más adelante veremos también detalles de su implementación.
2.3 Semántica del Contrato: Asertos
En la semántica definida para el contrato se establecen una serie de asertos (precondiciones,
postcondiciones e invariantes), que definen los términos del mismo. A continuación pasaremos a definir
dichos asertos, expresando la semántica que queremos asociar a cada uno de ellos:
Precondiciones: Se definen para los métodos. Establecen las obligaciones que debe cumplir el cliente para
que el servicio sea garantizado. El incumplimiento de las mismas tendrá una doble semántica según afecte o
no a un objeto de sincronización: el incumplimiento de una precondición (o una parte la misma) en la que no
involucra a objetos de sincronización provocará un fallo en la llamada (excepción), que podrá ser recuperado.
Por otra parte, el incumplimiento de una precondición que involucra a un objeto de sincronización
implicará la suspensión del objeto que intenta validarla hasta que dicha precondición sea cierta. Esta doble
semántica en las precondiciones nos sirve para poder expresar las necesidades de sincronización de una
manera cómoda, elegante y formal. Pensemos por ejemplo en un típico problema en el que un productor y un
consumidor utilizan para sincronizarse un buffer acotado. Tanto el productor como el consumidor serán
objetos separate que usan como objeto de sincronización un buffer acotado. Veamos el aspecto de sus
interfaces:
public interface ProducerInterface extends Separate
InvariantException,
{ public void Produce() throws
PreconditionException,
PostconditionException;
}
public interface ConsumerInterface extends Separate
InvariantException,
{ public void Consume() throws
PreconditionException,
PostconditionException;
}
public interface BufferInterface extends Synchronizer
{ Invariant: (NumberOfElements() >=0) && (NumberOfElements() <=MaxElements())
public int Get() throws InvariantException,
PreconditionException,
PostconditionException;
Require: (!isEmpty())
Ensure: (!isFull())
public void Store(int x) throws
Require: (!isFull())
Ensure: (!isEmpty())
public boolean isEmpty() throws
InvariantException,
PreconditionException,
PostconditionException;
InvariantException,
PreconditionException,
PostconditionException;
public boolean isFull() throws InvariantException,
PreconditionException,
PostconditionException;
public int NumberOfElements() throws InvariantException,
PreconditionException,
PostconditionException;
public int MaxElements() throws
}
InvariantExce
Comentarios de: Coordinación de Objetos Separate en Java (0)
No hay comentarios