• No se han encontrado resultados

UNIDAD IZTAPALAPA DIVISIÓN DE CIENCIAS BASICAS E INGENIERIA TíTU LO LENGUAJE DE ESPECIFICACIóN ENACT: Su uso en el diseiio de programas orientados a objetos PRESENTADO POR

N/A
N/A
Protected

Academic year: 2018

Share "UNIDAD IZTAPALAPA DIVISIÓN DE CIENCIAS BASICAS E INGENIERIA TíTU LO LENGUAJE DE ESPECIFICACIóN ENACT: Su uso en el diseiio de programas orientados a objetos PRESENTADO POR"

Copied!
76
0
0

Texto completo

(1)

UNIVERSIDAD AUTóNOMA METROPOLITANA

UNIDAD IZTAPALAPA

DIVISIÓN DE CIENCIAS

BASICAS

E INGENIERIA

TíTU LO

LENGUAJE DE ESPECIFICACIóN ENACT:

Su uso en el diseiio de programas orientados a objetos

PRESENTADO POR

ALTAIR HAZEL MARROQUíN CRUZ

ASESORADO POR

DR. JOHN CHARLES GODDARD CLOSE

PARA OBTENER EL TíTULO DE

-

LICENCIADO EN COMPUTACIóN

(2)

A TODOS AQUELLOS QUE ME AYUDARON YAPOYARON A SER LO QUE AHORA SOY

(3)

iNDlCE

INTRODUCCI~N OBJETIVOS

INGENIERíA DE SOFTWARE

LENGUAJE DE ESPECIFICACIóN ENACT PROGRAMACIóN ORIENTADA A OBJETOS CONSTRUCCIóN DE PROTOTIPOS

ENACT

1.CAPíTULO

I

DESCRIPCIóN DEL MÉTODO

6

1 . I .DIFERENCIAS CON EL DESARROLLO TRADICIONAL 7

1.2.EJEMPLIFICANDO EL MÉTODO 9

1.2.1 .ESPECIFICACIóN EN ENACT 11

I .2.2.lMPLEMENTAClóN EN C++ 14

2.CAPíTULO

II

DESCRIPCIóN DEL PROBLEMA

20

2.1.DESCRIPClÓN DE LAS NECESIDADES DE UN SISTEMA

BIBLIOTECARIO 20

2.2.ORGANIZAClÓN ACTUAL 21

2.3.PROBLEMAS 23

3.CAPiTULO 111

DESARROLLO DEL SISTEMA

26

3.1 .ANÁLISIS Y DISEÑO DEL SISTEMA BIBLIOTECARIO 26 3.2.MODELO EN ENACT 33

3.3.IMPLEMENTAClóN EN C++ 44

3.4.CONCLUSIONES 59

APÉNDICES

SINTÁXIS EN ENACT

DIAGRAMAS Y DESCRIPCIóN DE TÉRMINOS C++

61 61 66 68

(4)

I'.. No debes confundir la escala con el destino.. "

c. c.

P.

OBJETIVOS

En la computación como en otras ramas de la ciencias los avances tecnológicos se suceden vertiginosamente, se debe estar al tanto de las nuevas ideas. El estudio tanto de la filosofía de la programación orientada a objetos convinada con la utilización de un lenguaje de especificación durante el desarrollo de un sistema son

los

principales objetivos de este proyecto.

INGENIERíA DE SOFTWARE

Actualmente se demandan sistemas más confiables por lo que se plantea la necesidad de utilizar una metodología que comprenda todas las etapas del ciclo de vida del software.

de software en la siguiente figura.

Podemos ver las partes principales que integran el desarrollo

-

DISENO ... : + ...

Fig. 1 Ciclo de vida del Software

ANALISIS

En esta etapa es cuando debemos entender

los

requerimientos del cliente, precisando la información que se va a abarcar, como va a ser

actualizada y consultada.

(5)

DISEÑO

El diseño se refiere a la identificación de los componentes de la programación (funciones, flujos de datos y almacenamiento) especificando la relación entre ellos, la estructura de la programación y manteniendo un registro de las decisiones.

Aquí decidimos como la información deseada va a ser organizada y procesada por la computadora, escogiendo la plataforma de implementación, cuyas características se tomarán en consideración en el diseño de estructuras de datos y algoritmos que usará el sistema.

IMPLEMENTACI~N

La fase de implementación viene después cuando el análisis y el diseño ha determinado suficientemente la descripción precisa del código requerido. Construimos componentes de código compuestas de subrutinas que son probadas individualmente y luego en conjunto. Consecuentemente descubrimos errores ó inadecuaciones en el código que corregimos. Por otro lado también se encuentran inadecuaciones en el diseño, corregir esto es más caro, debido a que los cambios requeridos pueden afectar componentes que ya han sido considerados completos.

Metodologías Tradicionales

Herramientas utilizadas durante la fase del Análisis

Diagramas E-R,

Descomposición Funcional,

Diagrama de dependencia entre los procesos,

Diseño

Diagrama de flujo de datos, Tablas de estructura,

Diagramas de Acción (Algoritmos)

Implementación COBOL, PL/I, C

Manejadores de bases de datos como: ORACLE, FOXPRO, INFORMIX, etc.

Cuadro1

(6)

PROGRAMACIóN ORIENTADA A OBJETOS

El software una vez desarrollado tiene que tener la habilidad de estar abierto a futuros cambios. Los métodos orientados a objetos es una alternativa que permiten ésta flexibilidad.

En la programación convencional, los datos asumen cualquier estructura y los procesos hacen de los datos lo que el programador desee.

En el mundo orientado a objetos, las estructuras se relacionan con los objetos y sólo pueden ser utilizadas mediante los métodos diseñados para ese tipo de objeto, es decir, el procesamiento de los datos se centra en los tipos de objetos cuya estructura de datos sólo pueda controlarse mediante los métodos de la clase del objeto.

Cada objeto lleva a cabo una función específica e independiente de los demás objetos. Responde a mensajes, sin saber la razón del envío de éstos ni las consecuencias de su acción.

Las técnicas orientadas a objetos modifican el punto de vista de los analistas de sistemas de información acerca del mundo. En lugar de pensar en los procesos y su descomposición, piensan en objetos y su comportamiento, los Cuadros1 y 2 que muestran las herramientas utilizadas en las fases de desarrollo del software nos permiten ver este contraste.

Técnicas Orientadas a Objetos

Análisis y Diseño se basan en:

La identificación de Objetos y definición de clases Organización jerarquizada de clases

Reutilización de clases

Contrucción de marcos estructurales de aplicación a partir de librerías de clases

Implementación

Smalltalk, C++, ADA, etc

Cuadro2

(7)

Construcción

del prototipos

La contrucción de prototipos es una versión a pequeña escala del sistema, la idea es lograr una versión funcional lo más pronto posible para poder explorar opciones de diseño e implantación. Se utiliza para apoyar la confirmación de requisitos, no se ha utilizado mucho en la evaluación del software. Esto es debido a que mejor se modifica el sistema terminado para que cumpla con necesidades no planteadas ó no percibidas anteriormente antes que dar primero la oportunidad al usuario que comprenda, refine y complete sus necesidades y posteriormente se construya el sistema final. Construir el prototipo es caro si se le considera con los mismos estándares y términos que el sistema final. Sin embargo si se proyecta para demostrar los aspectos funcio- nales más que los no funcionales de un sistema, tendría un costo mucho menor que el sistema final.

Para sistemas pequeños puede ser apropiado presentar al usuario un sistema incompleto y después ampliarlo a medida que se descubran ó completen las necesidades reales, es decir partir del prototipo y evolucionar hasta el final, por otra parte se puede contruir el prototipo para identificar los problemas iniciales y, después de experimentar, se formula una especificación mejorada, se desecha y se construye el sistema final. La razón de este ultimo enfoque es que el desarrollo rápido es el principal objetivo de la contrucción de prototipos

Ventajas de utlizar un prototipo

-

Disminución de malentendidos entre desarrolladores de software y usuarios, al poder identificarlos a medida que se muestran las funciones del sitema

-

Detectar servicios faltantes

-

Identificar y redefinir los servicios difíciles de utilizar o confusos

-

Disponer con rapidez de un sistema de trabajo, aunque limitado, para demos

-

Se pueden encontrar inconsistencias en los requisitos ó pueden estar éstos

-

El prototipo puede servir como especificación trar la viabilidad y utilidad de la aplicación

incompletos

Especificación

abstracta de alto nivel para el diseñador

La especificación es la parte en la cual el diseño se expresa en una forma

Especificaciones operacionales

La función principal de las especificaciones operacionales es la de definir lo que el programa debe hacer en lugar de efectuar realmente las operaciones.

Si el lenguaje de especificación es ejecutable, la especificación no es más que otro programa, éstos imponen demandas muy fuertes a un sistema a tiempo

(8)

de ejecución y podrían ejecutarse con una lentitud cientos de veces mayor que los programas equivalentes.

El desarrollo de las especificaciones es un proceso iterativo; a medida que se desarrollan las especificaciones de las abstracciones de bajo nivel del sistema, pueden surgir errores en las especificaciones de nivel más alto y deben ser corregidas.

Un área muy importante de desarrollo de software, que parece ignorarse en la mayoría de los análisis sobre especificación del software, es la entrada y la salida. Los programas reales toman y producen información para su ambiente. Si una parte de cierto sistema es responsable de la entrada y la salida, también se debe especificar.

La razón de evitar las operaciones de E/S en la mayoría de los análisis sobre especificación formal es que resulta muy difícil establecer un modelo limpio de propósito general subyacente en los procesos de E/S. Esta dificultad resulta de que estos procesos deben actuar recíprocamente con el hardware subyacente, cuyo diseño a menudo no es elegante ni está especificado de manera formal. Sin embargo, incluso un modelo informal de operaciones de E/S es inútil cuando se construyen las especificaciones de diseño.

ENACT

Para permitirnos evaluar estas nuevas alternativas de arquitectura de software y entender mejor su comportamiento, antes de hacer ó emprender una larga implementación en lenguaje de alto nivel como lo es C++, se utiliza ENACT como lenguaje de modelado.

ENACT fue desarrollado en la Universidad de Southampton, Inglaterra por Peter Henderson del Departamento de Electrónica y Ciencias Computacionales, su libro “Object-Oriented Specification and Design with C++” en el cual se basó este trabajo puede ser consultado para una mejor referencia.

(9)

CAPíTULO I

DESCRIPCIóN DEL MÉTODO

Esta basado en seguir la programación orientada a objetos. Como ya señalamos anteriormente, los métodos orientados a objetos facilita la creación en el programa de un modelo del mundo real donde hay una directa relación entre el modelo abstracto de alto nivel y los componentes del mundo real. Cada entidad en el mundo real será representado por un solo objeto en la máquina.

Antes que nada hay que enteder los requerimientos, después viene la fase de Análisis, que va a estar constituida por la construcción de un modelo conceptual del mundo real para un sistema en la computadora. Así como el mundo real evoluciona, el modelo basado en la computadora evoluciona ó desarrolla para conservar el paso y registrar hechos relevantes. Esta fase empieza desde el momento de escoger objetos para modelar las entidades del mundo real. Dibujando diagramas-objeto para capturar algunas de las propiedades más abstractas de

los

objetos, creando una arquitectura para

nuestro sistema que sea adecuada a nuestros propósitos, válida y hábil a desarrollar tanto como evolucionen o desarrollen nuestros requerimientos. Se utilizan diversos diagramas que actúan como referencia visual para la información.

Finalmente se enumeran los eventos que puedan alterar el estado de nuestro mundo, se puede entrar o no en detalles de las operaciones que correspondan a las acciones de la ocurrencia de dichos eventos dependiendo de la complejidad del sistema.

Como ya se mencionó los cambios en el diseño puede alcanzar a cada componente en el sistema, por lo que se necesitan métodos que pongan especial cuidado en las primeras fases del desarrollo.

En el Diseño se empiezan a considerar los requerimientos que la computadora contrariamente al mundo real, pone sobre nosotros y desarrollar una estrategia que nos permita ir probando las decisiones de diseño.

(10)

Muchas veces, los detalles del problema y los conceptos de la solución

sólo

se comprenden claramente a través del esfuerzo de expresarlos en el programa: aquí es donde adquiere importancia la elección del lenguaje de programación ya que para que un lenguaje sea considerado de aplicación general debe poseer ciertas características:

Ejecutarse en máquinas tradicionales

Coexistir con sistemas operativos y lenguajes tradicionales en términos de

Servir para todas la áreas de aplicación importantes eficiencia durante la ejecución

La elección del lenguaje de programación para la Implementación en este caso es C++.

C++ es una buena plataforma para varios estilos de programación, en particular apoya la abstracción de datos y la programación orientada a objetos. Está diseñado para apoyar la noción de programa como modelo de algunos aspectos de la realidad y la de clase como la representación concreta de un concepto de la aplicación. Además de ser muy difundido comercialmente.

DIFERENCIAS CON EL DESARROLLO TRADICIONAL

Métodos de Especificación

Una especificación formal en

la

Ingeniería de Software es el uso de conceptos matemáticos para dar una definición precisa a los componentes con los que será construido el software. El camino normal por el cual una especificación es organizada; es la vista de esos componentes como un TDA.

Las operaciones aplicadas al TDA dan un significado preciso es decir qué es lo que el componente se supone hace, en lugar de cómo se supone lo hace.

Los métodos matemáticos formales constituyen los fundamentos de los profesionales en Ingeniería de Software, sin embargo los métodos usados están en una especie de state-of-the-art y tienden hacia esas bases teóricas.

-

El método algebraic0

-

El método orientado al modelado

Dos métodos formales de especificación populares son:

que tienen cierta relación con la programació funcional.

La ventaja derivada del empleo de especificaciones formales de los componentes del software es que dada una especificación formal y una

definición de la semántica del lenguaje de programación, puede demostrarse que un programa cumple con su especificación. Así se puede establecer la ausencia de ciertos tipos de errores de los programas, siempre y cuando la prueba sea correcta. Sin embargo no se obtiene nada que se pueda ejecutar en una máquina.

(11)

ESPEClFICAC16N ORIENTADA A OBJETOS

Se ha hecho referencia al código en Enact como especificación, como modelo, modelo en funcionamiento y/o como prototipo.

Su papel es servir como pseudocódigo para capturar detalles de nuestro diseño orientado a objetos y cuando este lo suficientemente completo pueda ser ejecutado, proporcionando un modelo en funcionamiento dandonos una retroalimentación anticipada de las consecuencias de las decisiones del diseño.

¿En qué sentido es una descripción en Enact una especificación y en qué sentido es diferente de los métodos tradicionales de especificación matemática? Enact es diferente de

los

lenguajes de especificación matemática en que permite la directa descripción de efectos secundarios, permite asignaciones. Soporta directamente la descripción de cambio de estado. Usa la noción de objeto como poseedor de estado. El objeto tiene identidad y estado, las operaciones aplicadas a éI pueden cambiar su estado sin cambiar su identidad. Además de poder ejecutarlo y ver su interpretación y cambios que se generen, en contraste con los modelos matemáticos con frecuencia no corren

El método orientado a objetos descrito modela el mundo real asociando objetos con entidades en el mundo real, en el mismo sentido los cambios en el mundo real son modelados por los cambios correspondientes en los objetos.

Después de entender el mundo real, podemos construir un modelo en funcionamiento con una muy directa relación con la realidad, por consiguiente

Enact sirve como una especificación.

Dado que se ha tomado el diseño orientado a objetos como el paradigma central, obviamente hay otras alternativas para la especificación orientada a objetos ó la construcción del modelo, por ejemplo Smalltalk que provee toda la funcionalidad de Enact y más, pero ¿porqué no usar C++ directamente como especificación y lenguaje de modelado?

Una de las causas es el tiempo dedicado a detalles que no son relevantes en las primeras decisiones de diseño

La inversión en detalles de diseño es difícil de abandonar cuando se requieren cambios en una decisión de alto nivel en el diseño.

El papel de Enact es simplemente proveer una base de conceptos para el desarrollo rápido de aplicaciones directamente en C++.

(12)

EJEMPLIFICANDO EL MÉTODO

El problema tomado para introducir tanto las ideas de la programación orientada a objetos y ejemplificar el método a seguir para el desarrollo de un sistema, consiste una situación que se presenta en cualquier oficina, archivar documentos

ANALISIS

Tenemos que los documentos deben estar almacenados en cierto orden. Para hacerlo habrá que clasificarlos de alguna manera, todos los que pertenecen a una sola persona los guardaremos en un folder ó carpeta, como tendremos muchos folders de las distintas personas de las que tenemos documentos los pondremos en gavetas ó cajones.

Una primera visión se encuentra en el siguiente diagrama E-R

FOLDER

nido en

Fig. 2 DIAGRAMA ENTIDAD-RELACIóN

Pero la idea es tratar de escoger objetos para modelar entidades del mundo real y tenemos ciertas propiedades y restricciones que queremos que nuestro sistema cumpla.

Propiedades

-

Existen documentos pertenecientes a una persona

-

Documentos deben guardarse en folders

-

Folders deben guardarse en gavetas

(13)

Consideramos que el sistema archivará por orden alfabético

Escogiendo objetos para modelar las entidades del mundo real

I

FOLDER

Arredondo Arzate

Fig. 3 DIAGRAMA-OBJETO

El paso final es enumerar los eventos que afectan el estado del mundo:

-

Se necesita archivar documentos(en folders)

-

Se necesita archivar folders (en gavetas)

-

Buscar gaveta, folders y documentos

-

Eliminar documetos

DISEÑO

Procedemos a construir nuestro modelo del problema en Enact. Antes debemos conocer y definir ciertos conceptos utilizados. (Ver Apéndice II para más definiciones de conceptos)

SISTEMA ABSTRACTO

Es producto de la fase del análisis y el inicio de la fase de diseño. Es un camino para organizar

los

elementos que constituyen los métodos orientados a

(14)

sistema abstracto es una colección de clases(vistas como tipos de datos abstractos junto con el protocolo para su uso), cada clase tiene su propio protocolo, pero sólo algunas de las operaciones en ellas deben ser hechas visibles al usuario del sistema abstracto.

PROTOCOLO

El conjunto de operaciones que sobre una clase particular pueden realizarse, sirve también como la interface que el usuario tiene con un sistema abstracto.

Podemos definirlo en dos formas: La forma textual y la forma de diagrama. La forma textual es más apropiada para capturar las definiciones que envuelven al diseño.

La forma de diagrama da una vista mejor del sistema abstracto en general y las relaciones entre las distintas operaciones que se encuentran en él.(Ver apéndice II para ver detalles de los elementos que lo integran)

Ambas formas se complementan, aunque es conveniente acompañar la sintaxis del protocolo con una descripción al usuario de cómo entender las relaciones entre las operaciones.

Las operaciones que sobre los objetos identificados (Gaveta, Folder,

Documento)se realizan son prácticamente las mismas por lo que es conveniente utilizar aquí el concepto de herencia de la metodología 00, definir una clase base que llamaremos Almacen, en la que se definan dichas acciones y heredar éstas propiedades en común a las subclases como se muestra a continuación.

Fig. 4 DIAGRAMA HERENCIA

class Almacen Object. class Gaveta Almacen. class Folder Almacen.

11

". . . "

(15)

Tanto la colección de documentos como la colección de folders deben almacenarse en una colección de objetos de clase Set. La clase Set predefinida en Enact que tiene el constructor set() y un protocolo que tiene la habilidad de insertar y remover elementos del conjunto y determinar si un objeto es elemento o no del conjunto (Ver Apéndice I).

La especificación en Enact para Almacen se muestra a continuación.

class Almacen -e Object.

Almacen.guarda(objeto) :=self.miembros.insert(objeto). Almacen.remueve(objeto):=self.miembros.remove(objeto). Almacen.busca(identifi) :=self.miembros.locate(x::x=identifi).

...

La primera declaración introduce la clase Almacen, como subclase de la clase (predefinida en Enact) Object, la cual es raiz de todas las clases. No declaramos ningun constructor para esta clase pues no queremos crear instancias de ella, decimos entonces que es una clase abstracta.

La posteriores líneas son las tres operaciones que tienen en común los objetos, es decir los métodos que son como definiciones de funciones excepto que la clase de objeto a la cual se aplican es hecha aparente.

El Único objeto que no requiere heredar dichas operaciones es Documento, pues solo necesitamos crear instancias de esa clase.

class Documento c Object.

documento(nombre) := new Documento with dueño = nombre. Documento.archivar(afolder) := afolder.guarda(self).

Especificación en Enact de la clase Documento

La utilización del constructor nos crea instancias de la clase Documento con un Único atributo: dueño, que es el nombre de la persona a la que pertenece dicho documento. Es necesario tener folders para guardar los documentos en ellos lo cual se realiza con la operación

aDocumento.archivar(afolder)

que guarda un documento aDocumento en un folder determinado afolder. La aperación invoca a la operación guarda que folder heredada de Almacen para almacenar objetos en una colección.

Almacen.guarda(objeto):=self.miembros.insert(objeto).

(16)

Almacen.guarda(objeto):=self.miembros.insert(objeto).

sólo que debemos especificar a que tipo de almacen debemos guardar el objeto, en este caso el Documento por lo que se declara

afolder.guarda(self)

de Enact self se liga a él.

del hecho de que aceptamos como parámetro un folder, la palabra reservada

Igualmente para la clase Folder, nada más creamos instancias de la clase folders como una colección de documentos

class Folder Almacen.

folder() := new Folder with documentos = set(). Folder.archivar(agaveta) := agaveta.guarda(self).

Especificación en Enact de la clase Folder

...

...

La clase Gaveta es una colección de folders y no es necesario definir ninguna otra operación.

class Gaveta c Almacen.

gaveta() := new Gaveta with folders

=

set().

Cuando sea necesario buscar cierto objeto ya sea un documento en un folder o un folder en una gaveta, se llama a la operación busca definida en Almacen, de las formas siguientes

aFolder.busca(aDocumento) aGaveta.busca(aFolder)

objetos que nos permite definir métodos genéricos.

Esto es una muestra de la gran fuerza de la programación orientada a

Finalmente llegamos a nuestro sistema abstracto de archivos

aDocumento := documento(). aFolder := folder(). aGaveta := gaveta(). aDocumento.archivar(aFolder). aFolder.archivar(aGaveta). afolder. busca(aDocumento). aGaveta.busca(aFolder)

Protocolo para el sistema abstracto de archivos

(17)

Podemos darnos cuenta que el código implementado en Enact para probar nuestro diseño es sumamente corto, posteriormente haremos una comparación con el código en C++ para comprobar ésta ventaja.

Ejemplo de uso del sistema

Acta := documento(). Titulo:= documento(). Certificado:=documento().

Portillo := folder(). LetraP := gaveta().

Acta.archivar(Portillo). Titulo.archivar(Portillo). Certificado.archivar(Portillo).

Portillo.documentos.members. %->(Certificado, Titulo, Acta)

Portillo.archivar(LetraP).

LetraP.folders.members. %->(Portillo)

(18)

Cuando el producto pasa del estado de diseño al de implementación, su codificación podría realizarse en casi cualquier lenguaje, no es escencial pero es deseable que el lenguaje de programación no dependa de mecanismos que no se puedan realizar de manera eficiente en una arquitectura tradicional. Todos los lenguajes de programación orientados a objetos tienene tres cosas en común:

objetos, polimorfsmo y herencia.

Se ha escogido C++, ya que por su versatilidad en cuanto al apoyo en una gran variedad de estilos de programación, entre ellas la programación orientada a objetos, y su proyección en los futuros sistemas de programación.

En C++ una clase introduce un nuevo tipo, define el espacio utilizado para representar valores de éste y determina las operaciones que son aplicables a las instancias de ese tipo.

Empezaremos por mostrar la definición de la clase Documento de nuestro sistema.

class Documento{ public:

char* nombre; Documento(char*); char *name();

1;

Ahora podemos declarar instancias de este tipo asumiendo que se van accesar vía apuntadores, de la siguiente forma:

Documento *Acta

que en realidad es un apuntador a una instancia de tipo Documento.

La clase Documento tiene 3 miembros, por default todos los miembros de una clase son privados a menos que se especifique

lo

contrario como en este caso que ponemos la palabra reservada public que indica que pueden ser

utilizadas por cualquier función.

La primera declaración es un miembro dato que registra el nombre ó identificador del documento.

Las siguientes son funciones miembro que corresponden al constructor y a un método.

C++ utiliza el mismo nombre para la clase y para su constructor.

Documento *Acta =new Documento("Acta");

En la declaración anterior se crea un apuntador a la instancia de tipo Documento y el constructor que le reserva espacio en memoria. En este caso el constructor necesita un parámetro de inicialización.

(19)

Cada miembro de la clase constituyen

los

atributos de una instancia de esa clase y son accesibles simplemente invocandolas, por ejemplo para Documento tenemos la siguiente manera de acceder a

los

atributos de Acta que es una

instacia de tipo de la clase Documento.

Acta->nombre Acta->name()

Las definiciones de las funciones miembros de la clase Documento se

Todas las funciones miembros estan construidas por el nombre de la clase muestran a continuación

a la cual pertenecen en este caso el prefijo es Documento::

Documento::Documento(char* n){ nombre = n;

1

La declaración anterior es la manera de referir a la función constructora al tiempo de definición e inicializa la variable, se puede utilizar este estilo que es

equivalente a declarar

Documento::Documento(char* n):nombre(n)O

Como el constructor no realiza nada más que inicializar datos miembros el cuerpo de la función está vacío

char *Documento::name(){ return nombre;

1

Hay varios mecanismos que provee C++ para apoyar la programación

orientada a objetos. La Herencia es uno de ellos. Vamos a ilustrarlo con nuestro ejemplo. Tenemos ya una clase llamada Documento, de la cual podemos crear instancias. Como ya lo habiamos tratado en la fase de Diseño, tenemos otras

clases más, acordando definir una clase abstracta, Almacen que hereda propiedades comunes tanto a la clase Folder, como a la clase Gaveta

Tenemos entonces una jerarquía de clases Fig. 4

(20)

Almacen es la clase base y Folder y Gaveta las clases derivadas

class Almacen{ char *nombre; Set *elementos;

Almacen(char *);

char *Almacen::name(); void guarda(void *objeto); void remueve(void *objeto); Set *miembros();

virtual void busca(); protected:

public:

1;

No nos interesa construir instancias directamente de tipo Almacen, sólo de tipo Gaveta y Folder por lo que no lo declaramos public, pero no puede ser privado puesto que las clases derivadas no pueden acceder a éI así que necesitamos un nivel intermedio: protected. Protected significa ser inaccesible a los usuarios de la clase excepto por las clases derivadas

class Gaveta : public Almacen{ public:

Gaveta(char *);

1;

class Fo1der:public Almacen{ public:

Folder(char *);

1;

Analizando éstas definiciones

class Fo1der:public Almacen

indica que Folder es una clase derivada de la clase base Almacen y que hereda los miembros públicos de Almacen, aparte se define un nuevo miembro, un constructor para crear instancias. Similarmente para la clase Gaveta.

Almacen::Almacen(char *n):nombre(n),elementos(new Set()){}

Folder::Folder(char *n) :Almacen(n)O

Gaveta::Gaveta(char *n) : Almacen(n)O

Funciones constructoras para las 3 clases

17

(21)

Los constructores de las clases derivadas únicamente pasan sus

argumentos al constructor de Almacen. Tanto Folder como Gaveta heredan las funciones miembros de Almacen definidas a continuación

void Almacen::guarda(void *objeto){ elementos->insert(objeto);

1

Set* Almacen::miembros(){return elementos;}

void Almacen::remueve(void *objeto){ elementos->remove(objeto);

1

Es conveniente adoptar la convención de que los datos miembros sean privados y sólo puedan ser accesados por funciones miembros, por lo tanto se implementa para C++

lo

que en Enact era un simple atributo

char *Almacen::name(){

1

return nombre;

La implementación de Almacén ha requerido el uso de una clase

En general una práctica normal cuando se desarrollan programas grandes

Para reusar una clase existente necesitamos conocer su protocolo, es

La recolección de cierto protocolo para una clase se hará en la medida que

Se puede crear una instancia de la clase Set usando el constructor

una vez creada podemos insertar y remover items del conjunto usando las

x-> insert(p)

predefinida en C++, Set. En el diseño también se utilizó.

en C++ es hacer uso de clases predefinidas en él.

decir, cómo construir instancias de esa clase y cómo acceder a ellas.

se usen las instancias de esa clase.

Set *x

=

new Set();

siguientes llamadas

x-> remove(p)

con p un apuntador. Existen varias operaciones que se pueden utilizar con la clase Set, una de ellas es

x-> member(p) que necesitamos para saber si el apuntador p es un miembro del conjunto x. La función regresa un valor falso si el elemento no pertenece al conjunto y verdadero si lo contrario(si el elemento ha sido insertado y no ha sido removido), ver el Apéndice Ill para definiciones de éstas funciones.

(22)

virtual void Almacen:: busca(){

cout << '7nIntroduzca el nombre del documento a buscar\n";

cin >> nombre-obj;

Documento *objeto=(Documento *)this->miembros()

cout << objeto->nombre;

->locate(compara-nombre-doc);

1

Aparte de

los

beneficios de compartir partes en común de sus definiciones, dividir las clases en una jerarquía de tipos, trae consigo la ventaja de que tenemos un tipo que podemos usar para referirnos tanto a folders como a gavetas

Si declaramos un apuntado de tipo

le podemos asignar tanto folders como gavetas, es decir ambas Almacen *a;

asignaciones son válidas a=&aFolder; a=&aGaveta; Si llamamos a la función

a->busca();

Dependiendo de cual de las asignaciones tome lugar, será buscada la

instancia correspondiente,debido al uso del mecanismo virtual. Es decir el camino en C++ para indicar que la implementación de una función o procedimiento en una clase es o puede ser responsabilidad de una subclase.

Hemos especificado que esa función miembro es virtual que significa que puede ser redefinida en una o más de las clases derivadas. Si la clase derivada tiene a la función redefinida, entonces cuando sea invacada a través del

apuntador se da preferencia a la redefinida, si no está redefinidad entonces tomará lugar la definición de la clase base.

Por último tenemos funciones globales utilizadas para inspeccionar

los

valores de atributos de instancias

int compara-nombre-doc(void *objeto){

return strcmp(((Documento *)objeto)->name(), ::nombre-obj)==O;

1

int compara-nombre-fol(void *objeto){

return strcmp(((Fo1der *)objeto)->name(), ::nombre-obj)==O;

1

19

(23)

y las funciones para imprimir en pantalla

void printDoc(void *aDoc){

cout << ((Documento *)aDoc)->name() << I'

1

void printFol(void *aFol){

cout << ((Folder *)aFol)->name() << ' I ;

1

Ejemplo de uso del sistema

Folder *Portillo=new Folder("Portillo"); //se crean apuntadores Gaveta *LetraP =new Gaveta("LetraP"); // a instancias

Portillo->guarda((void *)Acta); Portillo->guarda((void *)Titulo); Portillo->guarda((void *)Certificado);

//imprime los nombres de documentos guardados en el folder Portillo Portillo->miembros()->forEachDo(printDoc);

LetraP->guarda((void *)Portillo); cout << I' \n";

LetraP->miembros()->forEachDo(printFol); Portillo->busca();

(24)

CAPiTU LO

I I

DESCRIPCIóN DEL PROBLEMA

Objetivos

-

Realización del análisis y diseño de un sistema bibliotecario con las ideas de la programación orientada a objetos, desarrollando una especificación en el lenguaje ENACT.

-

La automatización de algunos procesos en el funcionamiento de la biblioteca

La fase de

ANALISIS

pretende obtener a partir de la especificación del problema del usuario una definición del sistema que va a desarrollarse. Identificar objetos así como los datos y procesos que son naturales para esos objetos(Construcción de un modelo), especificación de requisitos del sistema.

Debido a la naturaleza repetitiva de algunas actividades bibliotecarias, ya sea adquisición, catalogación, preparación, encuadernación, fotocopiado, reparación de libros, etc. es conveniente la automatización de algunas tareas.

El sistema pretende dar servicio a dos tipos de usuarios:

a) El que realiza el control del sistema e introduce nueva información. b) El usuario ordinario de la biblioteca

Generalmente las funciones de una biblioteca son las siguientes: 1. Selección y adquisición de material, incluyendo libros, periódicos, revistas, etc.

2. Preparación y cuidado de material a través de procesos como catalogación, clasificación, encuadernación

(25)

Las características deseables en un sistema son:

O Reducción de trabajo esclavizante

Se espera que la computadora reduzca, no incremente la carga de trabajo. Sea rápida, e idealmente se adapte al tipo de operaciones repetitivas involucradas como son la compilación de listas ó producción de tarjetas para catálogos.

O Reducción de errores al introducir datos al sistema

O Consistencia con el sistema

0 Rapidez

información actualizada a través de reportes

ORGANIZACION ACTUAL

Detección de errores

Consultar archivos más rápido que una persona y proveer

Se ha tomado como base y fuente de información la Coordinación de Servicios Documentales de la Universidad Autónoma Metropolitana

-

lztapalapa que es la encargada de poner a disposición de

los

usuarios el material bibliográfico, hemerográfico y documental que sirve de apoyo al desarrollo académico. Dicha coordinación realiza las actividades de organización, búsqueda de materiales, adquisiciones, catalogación, clasificación y diseminación de la información a través de diferentes secciones.

SECCIóN DE BIBLIOTECA

Cuenta con 100, O00 volúmenes y es la encargada de fijar

los

procedimientos necesarios para que

los

lectores tengan fácil acceso a 10s materiales del acervo general y colecciones especiales.

SECCldN DE HEMEROTECA

Responsable de la adquisición, organización y control del material hemerográfico

La adquisición de material (Revistas y periódicos) se realiza por 3 formas: Canje, compra ó donación.

La organización y control del revistas se realiza a través de un catálogo CARDEX, ordenados por título y alfabéticamente. Los datos contenidos en éI son:

-

Título

-

ISSN

-

Periodicidad

-

Editorial de la revista

-

Volumen

-

Número

-

Año

En

los

estantes están en el mismo orden que aparecen en Cardex

(26)

Los periódicos(La Jornada, Uno más uno, Excélsior, El Financiero, El Universal y el Diario Oficial) estan disponibles desde una fecha dos meses anteriores al mes que va corriendo hasta la fecha actual.

SECCIóN DE SISTEMAS BIBLIOTECARIOS

Se encarga de la búsqueda, localización y obtención de documentos a nivel nacional como internacional, además de proporcionar información bibliográfica especializada, en forma manual ó automatizada.

SECCIóN DE ADQUISICIONES

donación de los materiales bibliográficos.

Su actividad básica es la adquisición ya sea por compra, canje ó

SECCIóN DE

ANALISIS

BIBLIOGFlÁFICO

adquieren para organizar los diferentes catálogos técnicos y de usuarios. Investiga, analiza, cataloga y clasifica los materiales que se

Préstamos

El proceso de registro es muy importante ya que muestra en donde se encuentra un libro cuando no está en los anaqueles y cuando se tiene que regresar. La manera en que se registra en la CSD es :

-

Tipo de usuario (Estudiante, profesor ó administrativo)

-

Nombre

-

Matrícula ó No. económico

-

Autor

-

Colocación

-

No. de adquisición

-

Firma

El usuario llena una papeleta con los siguientes datos:

-

Título

(27)

PROBLEMAS

La producción de ordenes para el comerciante(editoria1) con copias para uso interno en operaciones de los departamentos que conforman la biblioteca, puede ser un proceso tardado y monótono cuando no se utiliza la computadora

La preparación de una lista general de títulos en pedido ó proceso de ser catalogado, comunmente referida como la lista de información en proceso

Las cartas de reclamación de pedidos con un periodo específico de tiempo

El mantenimiento de todas las operaciones de contabilidad de relacionadas con

los

fondos de libros, incluyendo la producción para cada departamento académico declaraciones mensuales indicando el presupuesto de fondos para libros, gastos

Una lista de los títulos nuevos en catálogo de distribución periódica a los usuarios de la biblioteca para el conocimiento del acervo del que pueden disponer.

No es escencial pero es deseable que el sistema contara con un chequeo automático de todo el material prestado por un usuario para verificar la fecha de salida de material y adeudos pendientes.

(28)

o

-! d

g

m

n

w-

z

-0

u

w

3

m

m z

4

u

8

z

.O

3

z:

m

w

n

4 k

i

2

"w

(29)

m

6' O

W u

(30)

CAPiTU LO

I I I

DESARROLLO DEL SISTEMA

“. . Todo el tiempo es presente eternamente por lo

todo el tiempo es nuestro..” The Passion

ANALISIS

DIAGRAMA ENTIDAD-RELACION

EDITORIAL

a

ESTUDIANTE

SISTEMAS ESCOLARES

contrata~l,+

es contratado

I

+

RECURSOS HUMANOS

(31)

DIAGRAMA DE CONTEXTO

papeleta sellada

BIBLIOTECAS

HUMANOS

inform.

B.D.

ESCOLARES

-

(32)

Papeleta Solicitud

material bibliográfico Notificación

domicilio

Fecha entrega material

>

,

o adeudo

or autor

-

or tema

(33)

ANTE EDITORIAL

DE

BIBLIOTECA

rocesados

-

A

ARCHIVO

A

(34)

Datos

libros-copia

libro

.

Dato5

ALJETA LIBRO

YA ADQUiRiDO F COPIA Ll6RO

E ACUERDO A

\ -

y

ONGRESO

CATÁLOGO L E A L

...

... . ... ... ... ... ... . ... .

'NAllONAL UNION CATALOG

(35)

PEDIDOS

m

EDITORIAL

nuevo material

: : ~ ~ ~ ~ ~ : ~ ~ . ~ ~ ~ ? ~ ~ ~ ~ ~ ?

>:.:.:.x.:<.:.:.:.:.:.:.:.:.:.:.:.: ...

edido

EDITORIAL

n

(36)

BASES DE DATOS UTILIZADAS POR EL SISTEMA -ESTUDIANTES -PROFESORES -ADMINISTRATIVOS -LIBROS -REVISTAS -EDITORIALES -PEDIDOS

-USUARIOS EXTERNOS -CONVENIOS

-SUSCRIPCIONES -PRESTAMOS -DISTRIBUIDOR

LIBROS REVISTAS EDITORIALES

.Número de Adquisición .Título

.Autor .ISBN .Edición

.Número de copia .Colocación

.Clave-editorial

4SSN Clave-editorial

.Título .Nombre-editorial

.Año .Dirección

.Volumen .Teléfono

.Número

.Clave-suscripcion .Colocación

.Periodicidad

PEDIDOS SUSCRIPCIONES

.Número de pedido .Tipo-material .Fecha-pedido .Fecha-inicio

.Fecha-llegada .Fecha-fin

Cantidad .Clave-distribuidor .Descripción .Precio

.Precio .Clave-suscripcion

(37)

DISEÑO

En relación a los préstamos introducimos tres clases

PRÉSTAMO

L

tj

USUARIO

t

I L

J U

Fig.5 Diagrama-Objeto

El acervo bibliográfico comprende distintos tipos de materiales no

sólo

libros, también hay revistas, periódico, etc. Tenemos entonces un ejemplo en donde podemos aplicar el concepto de herencia.

Definimos una clase base

class Material < Object.

y puesto que las principales transacciones en una biblioteca se presentan cuando una persona realiza las operaciones de préstamo y devolución de un

libro

Material.presta(aUsuario, fecha-actual, fecha-entrega):=

(aUsuario.num-libros() < aUsuario.max-libros then (self.prestador:=aUsuario; fecha-actual.suma-dias( 15,fecha-entrega);

(38)

Material.regresa(fecha-act):=(self.prestador.devolucion(self,fecha-act);

self.prestador:=nil;

self.fecha-entrega:=nil).

La primera operación implica registrar la asociación del libro a la persona y a su vez la necesidad de validar (Verifica que el usuario no exceda el limite en la cantidad de libros permitidos para prestamo)

Similarmente para la segunda operación registrar la devolución tanto en el conjunto de libros que tenga el usuario como en el libro

También necesitamos operaciones complementarias como saber

si

el libro se encuentra en la biblioteca ó está prestado, ó identificar al usuario que tiene prestado el libro, calcular el monto de la multa a pagar

si

se retrasa en devolver el libro.

Material.enbiblioteca():= self.prestador=nil.

Material.calcula-multa(tot):=tot*l

Material.usuarioprestador():=self.prestador.clave_usuario.

A continuación se presentan las definiciones de las clases Libro y Revista que son las que en realidad se instancian y heredan las funciones y

procedimientos de la clase Material

class Libro < Material,

libro(clave-material,nombre,num-copia):= new Libro with prestador=nil with

numero-adquisicion=clave-material

with titulo=nombre with copia=num-copia with fecha-entrega=nil.

class Revista < Material.

revista(c1ave-material, nombre,periodo):= new Revista with suscrip=nil with issn=clave-material

with titulo=nombre

with periodicidad=periodo.

(39)

I

LIBRO

prestador

1

USUARIO

I

BOOLEAN0

I

Fig. 6 Representación del Protocolo para la clase Libro

El sistema de préstamo debe establecer una fecha límite de entrega, por

lo

que se crea otra clase que maneje todo

lo

relacionado a fechas

reverse(x):=x=nil then nil else

append(reverse(t1 x), (hd x):()).

La función reverse no es propiamente de la clase Fecha, es simplemente una función auxiliar que se utiliza dentro de ella

class Fecha c Object.

fecha():= new Fecha with meses=bag() with valor=set().

Todas las operaciones realizadas se hacen sobre un conjunto, el atributo valor que contendrá 6 digitos, 2 referentes al día, 2 al mes y 2 al año

Fecha.inserta(anum):=self.valor.insert(anum).

inicializa una lista con el número máximo de días de cada mes

Fecha.guarda-valores():=(j:=l; i:=2; (¡<=I O loop

(40)

Fecha.saca-valor(n, lista):=(n=O then hd(lista) else self.saca-valor(n-1 ,tl(lista))).

Fecha.bisiesto(anio):=((anio mod 4) = O and ((anio mod 100) <> O)

or

(anio mod 400) = O).

Fecha.calcula~dias():=(mes:=l;dias:=O;temp:=self.meses.members; (mes< (self.saca-valor(1 ,self.valor.members))

loop (dias:=dias+ hd(temp);mes:=mes+l;temp:=tl(temp)));

dias + self.saca~valor(2,self.valor.members)).

Fecha.restan-dias():=(self.saca-valor(1 ,self.valor.members)=2 and self.bisiesto(hd(self.valor.members))

then ((29-self.saca-valor(2,self.valor.members))+l)

self.saca-valor(1 ,self.valor.members) loop

self.saca-valor(2,self.valor.members) +I )).

else (mes:=l ;temp:=self.meses.members;mes<

(temp:=tl(temp);mes:=mes+l); hd(temp)

-

Fecha.limpia():=(self.valor.members<>nil loop self.valor.remove(hd(self.valor.members))).

Fecha.copia(lista,n):=(n>O then (self.valor.insert(hd(lista));

lista:=tl(lista);self.copia(lista,n-I))

else (self.valor.members:=reverse(self.valor.members))).

Fecha.suma-dias(avalor, aFecha):=((avalor >O loop (avalor >=aFecha.restan-dias() then

(avalor:=avalor-aFecha.restan-dias();

anio:=hd(aFecha.valor.members)+(aFecha.saca-valor(l ,aFecha.valor.members

)/A 2);

mes:=aFecha.saca-valor(1 ,aFecha.valor.members) mod 12 + 1 ; dia:= 1 ; aFecha.limpia();

aFecha. inserta(dia);aFecha. inserta(mes);aFecha.inserta(anio)) else

(dia:=aFecha.saca~valor(2,aFecha.valor.members)+ avalor; avalor:=O;anio:=aFecha.saca_valor(O,aFecha.valor.members);

mes:=aFecha.saca-valor(1 ,aFecha.valor.members);aFecha.limpia();aFecha.ins erta(dia);

aFecha. inserta(mes);aFecha. inserta(ani0)))

1).

(41)

Fecha.dias-entre-fechas(aFecha):=

((totl

:=self.calcula~dias());(tot2:=aFecha.calcula~dias());

(aniol :=hd(self.valor.members))=(anio2:=hd(aFecha.valor.members)) then (totl

-

else

((aniol-1900)/4>0 then

((totl:=totl+l46*((aniol-1900)/4)); aFecha.inserta(tot1));

(aniol-1900) mod 4 >O then

((totl :=tot1 +365*((aniol-I 900) mod 4)+1); aFecha.inserta(tot1));

(anio2-I 900)/4 >O then

((tot2:=tot2+146 * ((anio2-I 900)/4)); aFecha.inserta(tot2));

(anio2-1900) mod 4 > O then

((tot2:=tot2+365*((anio2-1900) mod 4)+1); aFecha.inserta(tot2)); totl -tot2)).

la clase Material se introduce y hace uso de la clase Usuario. Los usuarios de la biblioteca tanto0 estudiantes como empleados ya sean profesores ó

administrativos y externos(personas que no pertenecen propiamente a la institución) tiene diferentes consideraciones en cuanto a las condiciones de préstamo, así que sus características son similares pero no iguales que nos hacer volver a la utilización de herencia.

tot2)

En la Fig. 6 y en las definiciones de los procedimientos y/o funciones de

ESTUDIANTE EMPLEADO EXTERNO

FIG. 7 DIAGRAMA-HERENCIA

(42)

class Usuario Object.

Usuario.registro(aMaterial):=(self.libros.insert(aMaterial)).

Usuario.devolucion(aMaterial,fecha_actual):=(self.libros.remove(aMaterial); ((tot:=fecha-actual.dias-entre_fechas(aMaterial.fecha_entrega)) >O)then (self.multa:=self.multa+aMaterial.calcula~multa(tot))).

Usuario.num-libros():=self.libros.size(). Usuario.paga():=(self.multa:=O).

Cada una de las clases derivadas tienen su constructor por que son las que se necesitan instanciar, ya que la clase base unicamente contiene las funciones ó procedimientos generales

class Estudiante Usuario.

estudiante(aMatricula):= new Estudiante with libros=set() with clave-usuario=aMatricula

with max-libros = 5 with multa=O.

El empleado puede se Académico ó Administrativo por lo que se agrega el atributo tipo.

class Empleado Usuario.

empleado(aNumero-economicolatipo):= new Empleado with libros=set() with clave-usuario = aNumero-economico

with max-libros = 8 with tipo=atipo.

class Externo Usuario.

externo(aCve-personallatelefono, adirec):= new Externo with libros=set() with clave-usuario

=

aCve-personal

with direccion = adirec

(43)

class lnstitucion c Object.

institucion(nombre-biblioteca):= new lnstitucion

with nombre-inst = nombre-biblioteca with telefono

with personas = set().

La clase Institución tambien nos da cuenta de la información de aquellas intituciones con las que se tiene convenio de préstamo interbibliotecario.

La operación de préstamo es la actividad principal de la bibliotena, desde luego no es la única, también está la de Adquisiciones, la Hemeroteca, etc.

La Hemeroteca lleva el control de revistas, publicaciones, periódicos, etc., una parte sencilla de modelar es la de suscripciones.

class Suscripcion Event.

suscripcion(ini, termina,aPrompter,aDisplay ):= new Suscripcion with distribuidor=nil

with prompter=aPrompter with fecha-ini=ini

with fecha-fin=termina with display = aDisplay.

Esta vez la clase no se deriva directamente de la clase predefinida en Enact Object. Se deriva de la Clase Event, que esta en el archivo Userface.act que tiene que cargarse antes de correr el programa, ya que Enact no reconoce clases, funciones ó procedimientos que no han sido declarados antes de su uso, esta utileria tiene funciones que permiten capturar información por parte del usuario y desplegarla en pantalla, digamos que es una capa intermedia entre el sistema y el usuario Io que se llama interfaz.

la parte de interfaz, y aquí se utiliza como auxiliar (para más detalles de sus operaciones ver Apéndice 111).

No ahondaremos en detalles de eso ya que no se considera en el diseño

La clase Suscripción se apoya fuertemente en la clase Fecha, sus operaciones están estrechamente ligadas a cuándo empieza y termina una suscripción y el otro atributo aparte de los utilizado para lograr la conección sistema-usuario es el de distribuidor que es como un apuntador a una instancia de la Clase Distribuidor que declaramos más adelante y contiene información que se puede requerir.

Suscripcion.revisa_fecha(fecha_actual):=fecha_actual.dias_entre_fechas(self.fe cha-fin).

(44)

Suscripcion.renueva(inicio, termino):=(ini:=fecha(); ini.inserta(self.prompter.get("'Fecha de inicio dial')); ini.inserta(self.prompter.get("'Fecha de inicio mes")); ini.inserta(self.prompter.get("'Fecha de inicio año'')); fin:=fecha();fin.guarda-valores();

fin.inserta(self.prompter.get("'Fecha de terminacion dial')); fin.inserta(self.prompter.get("'Fecha de terminacion mes")); fin.inserta(self.prompter.get("'fecha de terminacion año")); self.fecha_ini:=ini;self.fecha_fin:=fin;

resp:=self.display.put("'El

distribudor seguirá siendo el mismo");resp=n then (clave_d:=self.prompter.get("'Clave del distribuidor");

self.distribuidor.clave-dist:=clave-d)).

Suscripcion.realiza(aMaterial,

fecha-actual):=(aMaterial.suscrip=nil

then (ini:=fecha();ini.inserta(self.prompter.get("'Fecha de inicio dial'));

ini.inserta(self.prornpter.get("'Fecha de inicio mes")); ini.inserta(self.prompter.get("'Fecha de inicio

año"));fin:=fecha();fin.guarda-valores();

fin.inserta(self.prompter.get("'Fecha de terminacion

dia"));fin.inserta(self.prompter.get("'Fecha de terminacion mes")); fin.inserta(self.prompter.get("'Fecha de terminacion año''));

self.fecha-ini:=ini; self.fecha-fin:=fin; aMaterial.suscrip:=self;

clave-dist:=self.prompter.get("'Clave del distribuidor"); aMaterial.suscrip.distribuidor:=distribuidor(clave-dist)) else (dias:=aMaterial.suscrip.revisa_fecha(fecha_actual); self.display.put("'Faltan(días)",dias);dias~=30 then

ren:=self.prompter.get("'¿Desea renovarla?"); ren=s then aMaterial.suscripcion.renueva() )).

Talvez el código sea un poco difícil de entender a primera vista pero si se ha tenido relación con LISP, será hará un poco familiar y fácil de manejar.

La sección de Adquisiciones maneja

lo

que se refiere a la compra de nuevo material. Se requiere entonces llevar un control de las solicitudes de los usuarios para la adquisición de nuevo material. Introducimos la siguiente clase que se complementa con la clase Archivo que se explica posteriormente

(45)

class Pedido Object.

pedido(aClve_editorial,aCant,aDescrip,aPrecio,aClve-progr):= new Pedido with clave-editorial = aClve-editorial

with cantidad

=

aCant with descripcion = aDescrip with precio = aprecio

with clave-programa =aClve-progr with numero-pedido.

Pedido.adquisiciones-total():=self.cantidad*self.precio.

Pero si para las suscripciones necesitamos un distribuidor y para los pedidos aparte también se necesitan tratar con Editoriales para conseguir precios menores o mayor rapidez de entrega, ambos son Proveedores por lo que aunque por el momento parezca inútil tener una clase base que los derive ya que no declaramos ninguna operación para ambos como podremos ver a continuación, la filosofía de la programación orientada a objetos persigue que los sistemas faciliten los cambios en el futuro, así que no importa que ahora se deje así.

class Proveedor<Object.

class Editorial Proveedor.

editorial(clave):= new Editorial with clave-edit=clave with nombre.

class Distribuidor Proveedor.

distribuidor(clave):= new Distribuidor with clave-dist=clave with nombre.

La siguiente clase se utiliza para realizar una simulación de la EntradaEalida con la que no cuenta el lenguaje de Especificación ENACT

class Archivo < Object.

archivo():=new Archivo with members=nil.

Archivo.put(aTextObject):=(self.members:=append(self.members,aTextObject:())

1.

Archivo.lee():=(result:=hd(self.members);self.members:=tl(self.members);result).

(46)

Lo Único que realiza es por medio de listas simular la escritura y lectura secuencia1 en disco para poder modelar el proceso de Solicitud de nuevo

material de los distintos departamentos de la Universidad. El hecho es que para reducir el manejo de papeleo los solicitantes por medio de un diskete

conteniendo la información pertinente facilitan el manejo de pedidos que unicamente se revisan y se confirman

cargaPedido(aArchivo, aBiblio):=

caracter:=aArchivo.lee();cantidad:=caracter; caracter:=aArchivo.lee();descripcion:=caracter; caracter:=aArchivo.lee(); precio:=caracter;

caracter: =aArchivo. lee();clave-programa:=caracter;

aBiblio.adquiere(pedido(clave_editorial,cantidad,descripcion,precio,clave_progr

caracter:=aArchivo.lee())).

(caracter:=aArchivo.lee();(caractero"':")loop(clave-editorial:=caracter;

ama));

El procedimiento anterior y la clase que se describe a continuación sirven para probar el modelado de las solicitudes de pedido de nuevo material

class Adquiere Object. adquiere(aBiblioteca):=

new Adquiere with biblioteca=aBiblioteca.

Adquiere.do(aArch):=cargaPedido(aArch, self.biblioteca). Adquiere.suscrip(aMaterial,aFecha,aSuscripcion):= aSuscripcion.realiza(aMaterial,aFecha).

Finalmente la clase principal que lleva la batuta y dispara los eventos de las otras clases es la clase Biblioteca

class Biblioteca Object.

biblioteca():=new Biblioteca with solicitudes=set().

Biblioteca.adquiere(aPedido):=self.solicitudes.insert(aPedido).

Biblioteca.presta(aUsuario,aMaterial, fecha-actual):=(fecha-entrega:=fecha(); fecha_entrega.copia(fecha-actual.valor.members,

fecha_actual.valor.size());fecha-entrega.guarda_valores(); aMaterial.presta(aUsuario, fecha-actual, fecha-entrega)).

Biblioteca.regresa(aUsuario,aMaterial,fech):= aMaterial.regresa(fech).

(47)

Cabe señalar que en el prototipo no se consideraron las cuestiones de persistencia de datos e interfaz ya que el fin perseguido es tratar una rápida especificación y modelado del funcionamiento interno, sin embargo es

(48)

IMPLEMENTACIÓN

En esta fase el código crece debido a que se tiene que ser más detallado en cuestiones que para el rápido desarrollo del prototipo no se consideran

Header del programa aparte de la utilerías de C, debe tener

# include "c:collect.h"

para la utilización de operaciones de conjuntos,

Cuyo código se puede ver con más detalle en el Apéndice Ill que sirve

y las constantes que se manejan a lo largo del programa #define MAX-LIB-EST 5

#define MAX-LIB-EMP 8 #define MAX-LIB-EXT 5

#define DIAS-PRESTAMO-NORMAL 8

#define DIA-MULTA 1.5

# define MAX-NOM-USUARIO 30

# define MAX-CLAVE-USUARIO 8 # define MAX-DIR-USUARIO 50 # define MAX-TEL-USUARIO 1 O # define MAX-INS-USUARIO 1

Lo que procede ahora es como hacer una traducción de lo que tenemos en el prototipo a la plataforma de implementación C++.

La clase Fecha particularmente es muy distinta a la codificada en Enact, debido a que se utilizan estructuras distintas. En este caso las características de la plataforma no sirvieron en el diseño de estructuras, pues Enact no cuenta con mucha variedad de estructuras de datos.

class Fecha{ date valor; int* max-dias;

Fecha();

date regresa-fecha(); void guarda-fecha(date); void inicializa-meses(); int bisiesto(int);

int calcula-dias(); int restan-dias(); void suma-dias(int); dias-entre-fechas();

Fecha* genera-fecha-entrega(int); public:

(49)

Los miembros de una clase pueden ser

Quiere decir privado, su nombre

sólo

puede ser utilizado por funciones

-

private

miembro y amigas de la clase en la que se declara

-

protected

y amigas de la clase en que se declara y por funciones miembro y amigas de clases derivadas de esta clase

Protegido, su nombre no sólo puede ser utilizado por funciones miembro

-

public

Su nombre puede ser utilizado por cualquier función, es una variable pública

Todas estas formas de declarar los miembros de una clase es porque es conveniente precisar el modo en que se deben declarar las variables, se

recomienda que sea de tipo private el acceso a

los

datos debe estar restringido lo más posible para que no cualquiera pueda modificar o accesar y funcione como un TDA, por omisión en C++ los miembros de una clase son private a menos que se especifique lo contrario

simple interfaz(comunicaci6n entre ella y los demás). Es mejor hacer el acceso a ella exclusivamente a través de funciones miembros.

Si queremos que la clase se comporte como un TDA con una buena y

// Constructor Fecha::Fecha(){

max-dias=new int (1 3);

int Aux[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; memcpy(max-dias,Aux ,26);

1

como ya mencionamos si sus miembros 6 atributos son privadas, el código crece al tener que crear funciones para poder acceder a sus atributos como las funciones siguientes

date Fecha::regresa-fecha(){ return valor;

1

void Fecha::guarda-fecha(date dma){

1

valor=dma;

(50)

int Fecha::bisiesto(int anio){

return(ani0 % 4 == O && anio % 100 != O

11

anio % 400 ==

O);

I

int Fecha::calcula-dias(){ int mes,total, dias;

mes=total=dias=O;

for (;mes toascii(valor.da-mon); mes++) dias+=max-dias[mes];

total=dias

+

toascii(valor.da-day);

if(mes>2 && bisiesto(toascii(valor.da_year)))

return(tota1); total++;

1

int Fecha::restan-dias(){ int mes, dia;

if(valor.da-mon==2 && bisiesto(valor.da-year))

else{

return (29-(valor.da-day)+l);

mes=toascii(valor.da-mon); dia=toascii(valor.da-day); return (max-dias[mes]-dia+l );

1

I

void Fecha::suma-dias(int n){ int numero;

while(n

>O){

numero=restan-dias(); if (n >=numero){

n=n-restan-dias();

valor.da-year+=(valor.da-mon/l2);

valor.da-mon = valor.da-mon % 12 + 1 ; valor.da-day = 1 ;

I

else{

valor.da-day+=n; n=O;

I

1

(51)

int Fecha::dias-entre-fechas(){

int totl , tot2, year-fin, year-actual;

year-fin = valor.da-year; tot2 = calcula-dias();

Fecha* actual=new (Fecha); getdate(&(actual->valor));

year-actual= actual->valor.da-year; totl = actual->calcula-dias();

if (year-fin != year-actual){ if(year-actual-I 900/4 > O)

totl =tot1 + 146 * ((year-actual-l900)/4); if(year-actual-I 900%4 > O)

totl =tot1 + 365 * ((year-actual-I 900)%4)+1; if(year-fin-I 900/4 > O)

tot2=(tot2 + 146 * (year-fin-I 900)/4); if(year-fin-I 900%4 > O)

tot2=tot2 + 365 * ((year-fin-I 900)%4)+1;

I

return abs(tot1 -tot2);

1

Dentro de los procedimientos y/o funciones se pueden declarar variables locales como la variable hoy y aux del procedimiento que se muestra a

continuación

Fecha*

Fecha::genera-fecha-entrega(int

dias){ Fecha* hoy=new (Fecha);

date aux;

getdate(&(aux));

hoy->guarda-fecha(aux); hoy->suma-dias(dias); return(hoy);

I

//"""""""""""""""""""""""""""""""""""""""""""""-

(52)

En

C++,

al igual que en Enact no se puede hacer referencia a una clase ó procedimiento si no se ha declarado previamente. En la clase Material, se utiliza a la clase Usuario por los que se debe declarar

class Usuario;

antes de definir la clase Material de lo contrario no se reconocerá

class Material{

Fecha* fecha-entrega; char* titulo;

public:

Usuario* prestador;

Material(char* nombre-mat); Fecha* regresa-fecha-entrega();

void presta(Usuario* persona, int dias); void regresa();

int enbiblioteca();

float calcula-multa(int tiempo, float multa); virtual char* nombre-titulo();

1;

Ahora hay que definirla, debido a que las operaciones que realiza la clase Material hacer referencia a atributos de Usuario que no se conocen

11

""""""""""""""""""""""""""-

"- """"""""""- """""""""""

class Usuario {

char nombre-usuario [MAX-NOM-USUARIO]; Set * material-prestado;

char clave-usuario [MAX-CLAVE-USUARIO]; char direccion-usuario [MAX-DIR-USUARIO]; char telefono-usuario [MAX-TEL-USUARIO]; char inscrito-usuario [MAX-INS-USUARIO]; int multa;

public:

int max-num-libros; int max-libros(); Set* libros(); int num-libros();

void registro(Material* );

void devolucion(Material* ); Usuario(char* , char*, int); char* Quien();

Figure

Fig. 1 Ciclo de vida del Software
Fig. 2 DIAGRAMA ENTIDAD-RELACIóN
Fig. 3 DIAGRAMA-OBJETO
Fig.  4  DIAGRAMA  HERENCIA  class Almacen  Object.
+3

Referencias

Documento similar

En el capítulo de desventajas o posibles inconvenientes que ofrece la forma del Organismo autónomo figura la rigidez de su régimen jurídico, absorbentemente de Derecho público por

b) El Tribunal Constitucional se encuadra dentro de una organiza- ción jurídico constitucional que asume la supremacía de los dere- chos fundamentales y que reconoce la separación

Cedulario se inicia a mediados del siglo XVIL, por sus propias cédulas puede advertirse que no estaba totalmente conquistada la Nueva Gali- cia, ya que a fines del siglo xvn y en

The part I assessment is coordinated involving all MSCs and led by the RMS who prepares a draft assessment report, sends the request for information (RFI) with considerations,

Ciaurriz quien, durante su primer arlo de estancia en Loyola 40 , catalogó sus fondos siguiendo la división previa a la que nos hemos referido; y si esta labor fue de

Este acercamiento entre Roma y la Gran Bretaña lo atribuía Azara al Padre Ricci, general de los jesuítas (1758-73), quien, siempre ateniéndonos al juicio del agente, había

Para denegación hegeliana del mal: «Así como no existe lo fal- so, no existe el mal, es objetada primero por Sade y luego por la subjetividad romántica: en la mé- dula de la

En medio de la búsqueda de una modelación adecuada, el Lenguaje de Modelado Orientado a objetos de Aplicaciones Multimedia (OMMMA - L) se lanza como una propuesta de extensión de