Você está na página 1de 22

9.

Estudo de Caso: Controle de Biblioteca


Neste captulo desenvolvida uma pequena aplicao onde so empregados os
quatro conceitos fundamentais de orientao a objetos: tipos abstratos de dados,
encapsulamento, herana e polimorfismo. So apresentadas tambm algumas
tcnicas de modelagem especialmente teis para programao orientada a
objetos.
Ao final deste captulo o estudante dever ser capaz de interpretar, projetar e
desenvolver programas que utilizam hierarquias de classes.
9.1. Descrio do Problema
A aplicao que vamos desenvolver se destina a uma escola que possui uma biblioteca
aberta aos seus alunos, professores e ao pblico em geral. O objetivo do sistema manter
um registro dos emprstimos efetuados, visando controlar a situao de cada volume
individualmente e garantir que os emprstimos sejam efetuados de acordo com as normas
da biblioteca, descritas a seguir.
Os livros s podem ser retirados da biblioteca por usurios cadastrados numa das seguintes
categorias: aluno da escola, professor ou usurio externo. Os alunos devem renovar seu
cadastro a cada perodo letivo.
O nmero mximo de volumes que um usurio pode retirar, num mesmo perodo, e o prazo
de emprstimo dependem da categoria do usurio, de acordo com a seguinte tabela:
Categoria

Quantidade

Dias de Prazo

Usurios comuns

Alunos

Professores

14

Os limites acima so reduzidos nos seguintes casos:


(i) o aluno com cadastro vencido fica sujeito aos mesmos limites de um usurio comum, at
que providencie sua renovao;
(ii) o usurio com algum prazo de devoluo vencido fica impedido de retirar outros volumes,
retornando sua condio normal aps a devoluo do(s) livro(s) em atraso;
(iii) peridicos, como revistas e jornais, s podem ser retirados por professores, por um prazo
mximo de 7 dias;
(iv) um professor pode bloquear um nmero qualquer de livros ou peridicos, impedindo que
os mesmos sejam retirados da biblioteca durante um perodo de at 20 dias.
9.2. Projeto das Classes
Uma primeira anlise das informaes acima nos permite perceber a existncia de dois
principais tipos de objetos envolvidos no problema: de um lado os usurios cadastrados e de
outro os livros do acervo da biblioteca. As principais operaes envolvidas so emprstimos
e devolues de livros pelos usurios.
Os usurios so divididos em trs categorias: usurios externos, alunos e professores. Os
usurios externos so os mais limitados quanto s operaes que podem efetuar. Iremos
considerar alunos e professores como subtipos desses usurios, j que tanto um aluno como
um professor pode "substituir" um usurio em qualquer das operaes previstas para o
mesmo: retirada e devoluo de livros. Note que o inverso no verdadeiro: as operaes

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

78

Cap. 9 / Estudo de Caso: Controle de Biblioteca

de bloqueio de livros e renovao de cadastro so exclusivas de professores e alunos,


respectivamente.
As normas para emprstimo diferenciam peridicos dos livros em geral, embora sejam
aceitas as mesmas operaes para ambos. Existem apenas restries extras para o
emprstimo de peridicos. Temos, portanto, ao menos trs alternativas para modelar esses
objetos:
a) englobar livros e peridicos num mesmo tipo que tem a forma de publicao (livro comum
ou peridico) como um de seus atributos, a ser utilizado nas operaes de emprstimo;
b) considerar peridicos como subtipo de livros, que tem uma operao de emprstimo
especializada;
c) o inverso da opo (b), considerando livros como subtipo de peridicos.
A maior vantagem da opo (a) reduzir o nmero de tipos utilizados no projeto, embora
implique numa maior complexidade na definio e implementao das operaes. As opes
(b) e (c) so equivalentes, do ponto de vista da complexidade do projeto e implementao.
Iremos optar pela opo (b), por nos parecer mais natural.
9.3. Diagrama de Classes
Para implementar as hierarquias de tipos acima especificadas iremos definir as seguintes
classes para a aplicao:
Usuario
Abrange todos os usurios externos e a superclasse de alunos e professores.
Atributos: nome do usurio e a lista dos livros retirados.
Operaes: registro de novo usurio, emprstimo e devoluo.
UsuarioAluno
Abrange os alunos que esto cadastrados como usurios da biblioteca. uma
subclasse de Usuario.
Atributos especializados: data de expirao do cadastro.
Operaes especializadas: renovao do cadastro.
UsuarioProfessor
Abrange os professores que esto cadastrados como usurios da biblioteca. uma
subclasse de Usuario.
Atributos especializados: no tem.
Operaes especializadas: bloqueio e desbloqueio de livros.
Livro
Abrange os livros pertencentes ao acervo da biblioteca.
Atributos: ttulo, dados do emprstimo (usurio, data do emprstimo e data de
devoluo prevista), caso esteja emprestado, e dados do bloqueio (professor, data do
bloqueio e data para desbloqueio), caso esteja bloqueado.
Operaes: emprstimo, retorno, bloqueio e desbloqueio.
Periodico
Abrange os peridicos que pertencem ao acervo da biblioteca. uma subclasse de
Livro.
Atributos especializados: no tem.
Operaes especializadas: emprstimo.
A figura 9.3 apresenta o diagrama de classes correspondente.

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

79

Controle da
Biblioteca

Retira

Usuario

Bloqueia

0..*
Livro

0..*

1
UsuarioAluno

UsuarioProfessor

Periodico

Fig. 9.3 - Diagrama de Classes do Sistema de Controle da Biblioteca


Note que, alm dos relacionamentos de herana, esto representados no diagrama dois
outros relacionamentos: Retira (um usurio pode retirar livros) e Bloqueia (um professor
pode bloquear livros). Na notao UML, esse tipo de relacionamento onde h uma conexo
fsica, lgica ou conceitual entre duas classes de objetos, denominado associao.
9.4. Diagramas de Estados
Segundo as normas da biblioteca, a ocorrncia de alguns eventos implica em mudanas no
comportamento de um determinado usurio. So eles: a expirao do prazo de validade do
cadastro de um aluno, que passa a ser tratado como um usurio normal, e o vencimento de
um prazo de emprstimo, que impede novos emprstimos pelo usurio. Dizemos que um
usurio qualquer tem dois estados possveis: apto a retirar livros ou impedido de efetuar
novos emprstimos. Um aluno poder ainda estar em dois "super estados": com cadastro
regular ou com cadastro vencido, que se combinam com os dois estados possveis para um
usurio qualquer, resultando em quatro estados possveis para uma aluno: com cadastro
regular e apto a retirar livros, com cadastro regular e impedido de efetuar novos
emprstimos, com cadastro vencido e apto a retirar livros e, finalmente, com cadastro
vencido e impedido de efetuar novos emprstimos.
Na figura 9.4(a) esto representadas as mudanas de estado possveis para um usurio
externo e na figura 9.4(b) as mudanas de estado para um aluno.
retira / devolve
atingiu cota mxima OU
prazo de emprstimo vencido
apto a
retirar

devolve

a devolver

Fig. 9.4(a) - Diagrama de Estados para a Classe Usuario

Cap. 9 / Estudo de Caso: Controle de Biblioteca

80

Note que, na Figura 9.4(a), o nico tipo de operao permitida no estado a devolver a
devoluo de um livro. Os eventos "atingiu cota mxima" e "prazo de emprstimo vencido"
so disparados automaticamente pelo sistema. A retirada de um livro, por exemplo, pode
implicar em ser atingida a cota mxima para aquele usurio.
retira / devolve
com + de 2 livros OU
prazo de emprstimo vencido
apto a retirar
E regular

devolve

cadastro
vencido

a devolver
E regular

cadastro
vencido
renova
cadastro

renova
cadastro

com + de 1 livro OU
apto a retirar prazo de emprstimo vencido
a devolver
E a renovar
E a renovar
devolve
retira / devolve

Fig. 9.4(b) - Diagrama de Estados para a Classe UsuarioAluno


O comportamento de um professor semelhante ao de um usurio externo, admitindo-se
porm as operaes de bloqueio e desbloqueio, conforme representado na figura 9.4(c) .
retira / devolve
atingiu cota mxima OU
prazo de emprstimo vencido
apto a
retirar

bloqueia / desbloqueia

devolve

a devolver

bloqueia / desbloqueia

Fig. 9.4(c) - Diagrama de Estados para a Classe UsuarioProfessor


De acordo com o diagrama da figura 9.4(c) as operaes de bloqueio e desbloqueio so
permitidas mesmo que o professor esteja com algum prazo de emprstimo vencido, embora
na anlise do problema no tenha sido feita qualquer meno explcita a esse respeito. A
elaborao desses diagramas de grande auxlio na deteco de eventuais omisses e
inconsistncias nas especificaes iniciais do sistema.
Um livro est, tambm, sujeito a mudanas de comportamento em funo de eventos como
emprstimos, devolues, bloqueios e desbloqueios. A figura 9.4(d) apresenta o diagrama
de estados correspondente.
Observe que, de acordo com o diagrama 9.4(d), um livro emprestado no pode ser
bloqueado e o desbloqueio de um livro bloqueado ocorre automaticamente ao final do prazo
ou por uma ordem de desbloqueio. Estes so outros exemplos de decises de projeto que
os diagramas permitem destacar.

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

81

empresta
disponvel

retorna

emprestado

bloqueia
desbloqueia OU
prazo de bloqueio
vencido

retorna

prazo de
emprstimo
vencido

emprestado
E em atraso

bloqueado

Fig. 9.4(d) - Diagrama de Estados para a Classe Livro


9.5. Diagramas de Atividades
Nos diagramas anteriores esto representados os relacionamentos entre as diferentes
classes (diagrama de classes) e a dinmica dos objetos de cada classe isoladamente
(diagramas de estados).
Um terceiro aspecto importante a ser modelado a interao entre os objetos para a
realizao de cada ao do sistema, de forma a definir as responsabilidades de cada um.
Para isso utilizaremos diagramas de atividades, conforme a seguir.
Usuario

no

apto a retirar ?

Livro

sim

no

disponvel ?

sim
calcula data
de retorno
guarda dados
do emprstimo
adiciona livro na
carga do usurio

erro

OK

Fig. 9.5(a) - Diagrama de Atividades para Emprstimo de Livro


Observe que um diagrama de atividades assemelha-se a um diagrama de seqncia, como
apresentado na seo 4.2. Ambos retratam a colaborao entre os objetos a fim de realizar
uma operao. O diagrama de atividades, porm, o faz de forma mais detalhada.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

82

Usuario

no

apto a retirar ?

Peridico

Livro

sim

no

usurio
professor ?

sim

no

disponvel ?

sim
calcula data
de retorno
guarda dados
do emprstimo

adiciona livro na
carga do usurio

erro

OK

Fig. 9.5(b) - Diagrama de Atividades para Emprstimo de Peridico

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

83

Usuario

Livro

no

mesmo usurio
que retirou ?
sim

coloca disponvel

retira livro na
carga do usurio

erro

OK

Fig. 9.5(c) - Diagrama de Atividades para Devoluo

UsuarioProfessor

Livro

no

disponvel ?

sim
calcula data final
guarda dados
do bloqueio

erro

OK

Fig. 9.5(d) - Diagrama de Atividades para Bloqueio

Cap. 9 / Estudo de Caso: Controle de Biblioteca

84

UsuarioProfessor

Livro

no

mesmo usurio
que bloqueou ?
sim

coloca disponvel

erro

OK

Fig. 9.5(e) - Diagrama de Atividades para Desbloqueio


9.6. Implementao das Classes
9.6.1.

Classe Usuario

No projeto da classe Usuario esto definidos como atributos o nome do usurio e a lista
de livros retirados. O nome do usurio pode ser armazenado num atributo do tipo String,
que uma classe nativa de Java para representar cadeias de caracteres. Para armazenar a
lista de livros retirados, iremos utilizar uma outra classe nativa de Java, chamada Vector.
Os objetos dessa classe suportam operaes como incluso e remoo de itens no vetor,
que sero utilizadas pela classe Usuario.
As operaes definidas no projeto da classe so: criao de novo usurio, retirada de livro e
devoluo de livro. A criao de um novo usurio pode ser implementada atravs de um
mtodo construtor que receba como parmetro o nome do usurio. Para as outras
operaes definiremos dois mtodos: retiraLivro() e devolveLivro(). Ambos
recebem como parmetro o livro que est sendo retirado ou devolvido e retornam uma
condio para indicar se a operao foi aceita.
Podemos, portanto, iniciar a implementao da classe com a seguinte estrutura geral, a ser
includa num arquivo de nome Usuario.java:
import java.util.Vector;
import java.util.Enumeration;
class Usuario {
private String nome;
private Vector livrosRetirados;
Usuario (String st) {
nome=st;
livrosRetirados=new Vector(5);
}
public boolean retiraLivro (Livro it) {
}
public boolean devolveLivro (Livro it) {
}
}

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

85

As duas linhas iniciais (comandos import) so necessrias para que possamos utilizar a
classe Vector, que pertence ao pacote java.util.
O mtodo construtor simplesmente guarda o nome do usurio e cria o vetor para armazenar
os livros retirados.
Antes de detalhar os mtodos retiraLivro() e devolveLivro() iremos definir alguns
mtodos auxiliares que iro simplificar essa tarefa. Como os parmetros quantidade mxima
de livros e prazo mximo para emprstimo podem variar conforme o tipo de usurio e seu
estado, ao invs de trata-los como atributos da classe vamos definir dois mtodos getCotaMaxima() e getPrazoMaximo() - que ficaro responsveis pela determinao
desses parmetros no momento em que sejam necessrios. Na classe Usuario esses
mtodos retornam valores constantes, conforme abaixo:
public int getCotaMaxima() { return 2; }
public int getPrazoMaximo() { return 4; }

Posteriormente, na definio das classes UsuarioAluno e UsuarioProfessor esses


mtodos sero redefinidos de acordo com as especificaes para cada tipo de usurio.
De uma maneira geral, o comportamento de um objeto depende de seu estado, o que nos
obriga a interrogar o estado do objeto nos mtodos que implementam suas operaes.
Muitas vezes a determinao do estado de um objeto no trivial, o que pode obscurecer a
implementao das operaes e propiciar inconsistncias na determinao do estado por
diferentes mtodos. Torna-se conveniente, portanto, definirmos mtodos auxiliares que
sejam responsveis por determinar, a qualquer momento, o estado do objeto de uma forma
simples e segura. Para cada estado previsto no projeto da classe definimos um mtodo de
nome isNomeDoEstado(), que retorna uma condio indicando se o objeto se encontra
no estado NomeDoEstado.
No caso da classe usurio iremos definir os mtodos isAptoARetirar()
isADevolver(), de acordo com o diagrama de estados da figura 9.4(a):

public boolean isADevolver() {


return((livrosRetirados.size()>=getCotaMaxima()
||temPrazoVencido()) ?
true:false );
}
public boolean isAptoARetirar() {
return(!isADevolver());
}

O mtodo size(), da classe Vector, retorna o nmero de elementos no vetor. A


expresso livrosRetirados.size() ser, portanto, igual ao nmero de livros retirados
pelo usurio.
O mtodo temPrazoVencido() ir verificar se algum dos livros retirados pelo usurio est
com seu prazo de devoluo vencido. Para isso ser necessrio a colaborao da classe
Livro, responsvel por controlar a situao de cada livro individualmente.

86

Cap. 9 / Estudo de Caso: Controle de Biblioteca

O cdigo abaixo verifica se h algum livro em atraso, na lista de livros retirados pelo usurio:
public boolean temPrazoVencido () {
Livro livro;
Enumeration lista=livrosRetirados.elements();
while (lista.hasMoreElements()) {
livro=(Livro)lista.nextElement();
if (livro.isEmAtraso())return(true);
}
return(false);
}

Iremos definir o mtodo isEmAtraso(), na classe Livro, de forma similar aos mtodos
isAptoARetirar() e isADevolver() da classe Usuario.
Com o suporte dos mtodos definidos acima, a implementao dos mtodos
retiraLivro() e devolveLivro() pode ser feita com facilidade, a partir dos
diagramas de atividades correspondentes (figura 9.5(a) e 9.5(c)):
public boolean retiraLivro (Livro it) {
if (isAptoARetirar())
if (it.empresta(this, getPrazoMaximo())) {
livrosRetirados.addElement(it);
return (true);
}
else return (false);
else return (false);
}
public boolean devolveLivro (Livro it) {
if (it.retorna(this)) {
livrosRetirados.removeElement(it);
return (true);
}
else
return (false);
}

Os mtodos empresta() e retorna() sero definidos na classe Livro, para


implementar a parte dessas operaes de responsabilidade daquela classe, conforme os
diagramas acima mencionados.
Para concluir a definio dessa classe iremos acrescentar alguns mtodos auxiliares que
permitem a objetos de qualquer classe observar partes do estado do objeto:
isProfessor() de acordo com o diagrama de atividades 9.5(b), a classe Periodico
ir precisar testar se o usurio que solicita uma retirada um professor. Para
simplificar essa tarefa iremos definir o mtodo isProfessor() na classe Usuario
retornando sempre false e redefini-lo na classe UsuarioProfessor para
retornar true;
getNome() permite que objetos de outras classes possam obter o nome do usurio,
mantendo o atributo nome como private;
toString() fornece uma String com a identificao do usurio (categoria de usurio
e nome);
listaCarga() imprime ficha com os dados do usurio e a lista dos livros de posse do
mesmo.

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

87

O cdigo seguinte implementa esses quatro mtodos:


public boolean isProfessor()
{ return(false); }
public String getNome()
{ return nome; }
public String toString () {
return("Usuario "+nome);
}
public void listaCarga() {
System.out.println
(toString()+" Limite: "+ getCotaMaxima()+
" Carga atual: "+livrosRetirados.size());
Enumeration lista=livrosRetirados.elements();
while (lista.hasMoreElements())
System.out.println(lista.nextElement());
}

9.6.2.

Classe UsuarioAluno

No projeto da classe UsuarioAluno foi definido um nico atributo especializado, que a


data de expirao do cadastro. Para armazenar essa data utilizaremos a classe Date, do
pacote java.util, que oferece facilidades para manuseio de datas. A nica operao
especializada a renovao do cadastro, que simplesmente substitui a data de expirao do
cadastro.
Podemos, portanto, iniciar a definio da classe com:
import java.util.Date;
class UsuarioAluno extends Usuario {
private Date dataLimite;
UsuarioAluno (String st, Date dt) {
super (st);
dataLimite=dt;
}
public void renovaCartao (Date dt) {
dataLimite=dt;
}
}

Tal como foi feito para a classe Usuario, iremos definir dois mtodos auxiliares para a
determinao do estado atual do aluno:
public boolean isRegular () {
Date hoje=new Date();
return(dataLimite.after(hoje));
}
public boolean isARenovar() { return(!isRegular()); }

O comando new Date() cria um objeto do tipo Date com a data e hora atual. O mtodo
after(), da classe Date, retorna true se a data armazenada no objeto posterior
data fornecida como parmetro.
Podemos agora redefinir os mtodos getCotaMaxima() e getPrazoMaximo(), de
acordo com os critrios aplicveis a um aluno:
public int getCotaMaxima()
{ return (isRegular() ?
3 : super.getCotaMaxima()); }
public int getPrazoMaximo()
{ return (isRegular() ?
7 : super.getPrazoMaximo()); }

Cap. 9 / Estudo de Caso: Controle de Biblioteca

88

Resta, finalmente, apenas o mtodo toString() a ser redefinido:


public String toString () {
return("Aluno "+getNome());
}

9.6.3.

Classe UsuarioProfessor

No projeto da classe UsuarioProfessor so definidas apenas as operaes


especializadas de bloqueio e desbloqueio de livros, conforme detalhadas nos diagramas
9.5(d) e 9.5(e). Nos dois casos a nica responsabilidade de um objeto da classe
UsuarioProfessor chamar os mtodos correspondentes do objeto da classe Livro.
Podemos, portanto, iniciar a definio da classe com:
class UsuarioProfessor extends Usuario {
UsuarioProfessor (String st) {
super (st);
}
public boolean bloqueiaLivro (Livro it, int prazo) {
return(it.bloqueia((Usuario)this, prazo));
}
public boolean desbloqueiaLivro (Livro it) {
return (it.desbloqueia((Usuario)this));
}
}

Note que o objeto this, nessa classe, do tipo UsuarioProfessor e no Usuario.


Para uniformizar a interface da classe Livro, estamos promovendo o tipo do objeto para
Usuario nas chamadas dos mtodos bloqueia() e desbloqueia().
Para concluir a definio dessa classe resta redefinir os mtodos abaixo:
public int
getCargaLimite() { return 5; }
public int
getPrazoMaximo() { return 14; }
public boolean isProfessor()
{ return(true); }
public String toString () {
return("Prof. "+getNome());
}

9.6.4.

Classe Livro

No projeto da classe Livro so definidos como atributos o ttulo do livro, dados do


emprstimo e dados do bloqueio. Os atributos do emprstimo e do bloqueio so: usurio que
realizou a operao, data da operao e data prevista para devoluo ou desbloqueio.
Tal como foi feito para a classe Usuario, iremos definir mtodos auxiliares para determinar
o estado de um Livro, de acordo com o diagrama da figura 9.4(d).

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

89

Podemos, portanto, iniciar a definio da classe com a seguinte estrutura geral:


import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Date;
class Livro {
private String titulo;
private Usuario retiradoPor;
private Date dtEmprestimo;
private Date dtDevolucao;
private Usuario bloqueadoPor;
private Date dtBloqueio;
private Date dtDesbloqueio;
public boolean isDisponivel() {
}
public boolean isEmprestado() {
}
public boolean isBloqueado() {
}
public boolean isEmAtraso() {
}
public Livro (String tit) {
titulo=tit;
}
public boolean bloqueia (Usuario u,int prazo){
}
public boolean desbloqueia (Usuario u) {
}
public boolean empresta (Usuario u, int prazo) {
}
public boolean retorna (Usuario u) {
}
}

Para determinar o estado atual de um livro, conforme o diagrama de estados da figura


9.4(d), iremos utilizar a rvore de decises da figura 9.6.4. Esse tipo de rvore nos permite
definir o estado de forma perfeitamente determinista, sem ambigidade ou indefinies. Note
que a condio "em atraso" subordinada condio "emprestado" - um livro s pode estar
em atraso se est emprestado. Dizemos que o estado "em atraso" um sub-estado de
"emprestado". Sendo assim, podemos deixar a rvore que contm "em atraso" incompleta, j
que no estamos interessados no estado "emprestado E em dia".
emprestadoPor
== null ?

false

true

emprestado
false
dtDevolucao
< hoje ?

bloqueadoPor
== null ?

true

true
false

dtDesbloqueio
< hoje ?

true

disponivel

em atraso
bloqueado

disponivel

Fig. 9.6.4 - rvore de Decises para Estado de Livro

90

Cap. 9 / Estudo de Caso: Controle de Biblioteca

O cdigo seguinte implementa os mtodos auxiliares com base nessa rvore de decises.
public boolean isEmprestado() {
return (!(retiradoPor==null));
}
public boolean isEmAtraso() {
Date hoje=new Date();
return(isEmprestado()&&
dtDevolucao.before(hoje));
}
public boolean isBloqueado() {
Date hoje=new Date();
return(retiradoPor==null&&
!(bloqueadoPor==null)&&
!(dtDesbloqueio.before(hoje)));
}
public boolean isDisponivel() {
Date hoje=new Date();
return(retiradoPor==null&&
(bloqueadoPor==null||
dtDesbloqueio.before(hoje)));
}

Com esses mtodos j definidos, podemos implementar as operaes principais com


facilidade, conforme os diagramas de atividades da Seo 9.5.
public boolean bloqueia (Usuario u, int prazo) {
GregorianCalendar cal=new GregorianCalendar();
if (isDisponivel()&&u.isProfessor()) {
bloqueadoPor=u;
dtBloqueio=cal.getTime();
cal.add(Calendar.DATE, (prazo>20?20:prazo));
dtDesbloqueio=cal.getTime();
return(true);
}
else return(false);
}
public boolean desbloqueia (Usuario u) {
if (u==bloqueadoPor) {
bloqueadoPor=null;
return(true);
}
else return (false);
}
public boolean empresta (Usuario u, int prazo) {
GregorianCalendar cal=new GregorianCalendar();
if (isDisponivel()) {
retiradoPor=u;
dtEmprestimo=cal.getTime();
cal.add(Calendar.DATE, prazo);
dtDevolucao=cal.getTime();
return(true);
}
else return(false);
}

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

91

public boolean retorna (Usuario u) {


if (u==retiradoPor) {
retiradoPor=null;
return(true);
}
else return (false);
}

Para completar a definio da classe iremos definir o mtodo toString() para fornecer
um String com o ttulo do livro e sua situao atual:
public String toString() {
String st=new String();
if (isDisponivel())
return(titulo+" disponivel");
if (isEmprestado())
st=" retirado por "+retiradoPor+
" em "+dma(dtEmprestimo)+
" ate "+dma(dtDevolucao);
else
st=" bloqueado por "+bloqueadoPor+
" em "+dma(dtBloqueio)+
" ate "+dma(dtDesbloqueio);
return(titulo+st);
}
private String dma(Date dt) {
GregorianCalendar cal=new GregorianCalendar();
cal.setTime(dt);
return( cal.get(Calendar.DATE)
+"/"+
(cal.get(Calendar.MONTH)+1)+"/"+
cal.get(Calendar.YEAR) );
}

O mtodo auxiliar dma()transforma uma data num String no formato dia / ms /ano.
Como utilizado apenas pela classe Livro, foi definido como private.
9.6.5.

Classe Periodico

No projeto da classe Periodico definida apenas uma operao de emprstimo


especializada, conforme o diagrama de atividades 9.5(b).
O cdigo seguinte implementa essa classe:
class Periodico extends Livro {
public Periodico (String tit) {
super(tit);
}
public boolean empresta (Usuario u, int prazo) {
if (u.isProfessor())
return(super.empresta (u, 7));
else
return(false);
}
}

O mtodo empresta() apenas verifica se o usurio um professor, utilizando para isso o


mtodo isProfessor(), definido nas classes Usuario e UsarioProfessor, e, em caso
afirmativo, executa o mtodo de emprstimo da superclasse, com o prazo de emprstimo
fixado em 7 dias.

92

Cap. 9 / Estudo de Caso: Controle de Biblioteca

9.7. O Programa Principal


O programa apresentado a seguir (Cap9.java) utiliza todas as classes desenvolvidas nesse
captulo, simulando uma aplicao completa.
Na fase inicial o programa permite incluir livros e usurios, em duas etapas sucessivas. Em
seguida o programa entra no modo de atendimento, solicitando o nmero do usurio e
apresentando as opes disponveis para aquele tipo de usurio: retirada de livros,
devoluo e consulta da posio do usurio para todos eles e, adicionalmente, bloqueio e
desbloqueio apenas para professores. Nas operaes de retirada, devoluo, bloqueio e
desbloqueio o programa exibe a situao do livro antes da operao e, caso a mesma seja
aceita, o seu estado aps a operao.
Deixamos como exerccio para o estudante a anlise mais detalhada desse programa.
import java.io.*;
import java.util.*;
class Cap9 {
static BufferedReader r=new BufferedReader
(new InputStreamReader (System.in));
static StreamTokenizer st=new StreamTokenizer(r);
static Vector vetorUsuarios=new Vector(10);
static Vector vetorLivros=new Vector(10);
public static void main (String Arg[])
throws IOException {
Usuario usuario;
Livro livro;
int i, op;
cadastraLivros();
cadastraUsuarios();
System.out.println("\nAtendimento aos usuarios");
usuario=getUsuario(); // seleciona usuario
while(usuario!=null) {
System.out.println(usuario);
op=getOperacao(usuario); // seleciona operacao
executaOperacao(usuario,op); // e executa
usuario=getUsuario();
}
}
static void cadastraLivros() throws IOException {
Livro livro;
String titulo;
int op;
System.out.println("Cadastramento dos livros");
titulo=getString("titulo (\"fim\" para encerrar)");
while (!titulo.equals("fim")) {
op=getInt("1=livro, 2=periodico",1,2);
if (op==1) livro=new Livro(titulo);
else livro=new Periodico(titulo);
vetorLivros.addElement(livro);
System.out.println(livro+" incluido com # "+
vetorLivros.size()+"\n");
titulo=getString
("proximo titulo (\"fim\" para encerrar)");
}
}

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca


static void cadastraUsuarios() throws IOException {
Usuario usuario;
String nome;
int op;
GregorianCalendar cal=new GregorianCalendar();
cal.add(Calendar.MONTH, 6);
Date dt=cal.getTime();
System.out.println("Cadastramento dos usuarios");
nome=getString("nome (\"fim\" para encerrar)");
while (!nome.equals("fim")) {
op=getInt
("1=usuario externo, 2=aluno, 3=professor",1,3);
if (op==1) usuario=new Usuario(nome); else
if (op==2) usuario=new UsuarioAluno(nome, dt);
else
usuario=new UsuarioProfessor(nome);
vetorUsuarios.addElement(usuario);
System.out.println(usuario+" incluido com # "+
vetorUsuarios.size()+"\n");
nome=getString
("proximo nome (\"fim\" para encerrar)");
}
}
static int getOperacao(Usuario usuario)
throws IOException {
int op;
if(usuario.isProfessor())
op=getInt("operacao:\n"+
" 1=retira, 2=devolve, 3=ver carga,"+
" 4=bloqueia, 5=desbloqueia",1,5);
else
op=getInt("operacao:\n"+
" 1=retira, 2=devolve, 3=ver carga",1,3);
return(op);
}
static Usuario getUsuario() throws IOException {
int i=getInt
("numero do usuario (0=fim)",0,vetorUsuarios.size());
if (i>0)
return((Usuario)vetorUsuarios.elementAt(--i));
else
return(null);
}
static Livro getLivro() throws IOException {
int i=getInt("livro",1,vetorLivros.size());
return((Livro)vetorLivros.elementAt(--i));
}

93

94

Cap. 9 / Estudo de Caso: Controle de Biblioteca


static void executaOperacao(Usuario usuario, int op)
throws IOException {
Livro livro;
boolean r=false;
int i;
if(op==3)usuario.listaCarga();
else {
livro=getLivro();
System.out.println(livro);
switch(op) {
case 1: r=usuario.retiraLivro(livro); break;
case 2: r=usuario.devolveLivro(livro); break;
case 4: i=getInt("prazo",1,20);
r=((UsuarioProfessor)usuario).bloqueiaLivro(livro,i);
break;
case 5:
r=((UsuarioProfessor)usuario).desbloqueiaLivro(livro);
break;
}
if (r==true)
System.out.println(livro);
else System.out.println
("Operacao rejeitada");
}
}
static int getInt(String str, int de, int ate)
throws IOException {
do {
System.out.println("Entre com "+str);
try {st.nextToken();}
catch (IOException e) {
System.out.println
("Erro na leitura do teclado");
return(0);
}
} while ( st.ttype!=StreamTokenizer.TT_NUMBER ||
st.nval<de || st.nval>ate );
return((int)st.nval);
}

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

95

static String getString(String str)


throws IOException {
String in=new String();
System.out.println("Entre com "+str);
int quoteChar='"';
st.eolIsSignificant(true);
do {
try {st.nextToken();}
catch (IOException e) {
System.out.println
("Erro na leitura do teclado");
return("");
}
if ( st.ttype==quoteChar ||
st.ttype==StreamTokenizer.TT_WORD ) {
if (in.length()>0)
in=in.concat(" ");
in=in.concat(st.sval);
}
} while ( in.length()==0 ||
st.ttype!=StreamTokenizer.TT_EOL );
st.eolIsSignificant(false);
return (in);
}
}

Segue um exemplo de sesso de teste desse programa. As entradas fornecidas esto


destacadas em negrito .
Cadastramento dos livros
Entre com titulo ("fim" para encerrar)
Tecnicas de Programacao
Entre com 1=livro, 2=periodico (1 - 2)
1
Tecnicas de Programacao disponivel incluido com # 1
Entre com proximo titulo ("fim" para encerrar)
Analise Orientada a Objetos
Entre com 1=livro, 2=periodico (1 - 2)
1
Analise Orientada a Objetos disponivel incluido com # 2
Entre com proximo titulo ("fim" para encerrar)
Curso de Java
Entre com 1=livro, 2=periodico (1 - 2)
1
Curso de Java disponivel incluido com # 3
Entre com proximo titulo ("fim" para encerrar)
PC Magazine
Entre com 1=livro, 2=periodico (1 - 2)
2
PC Magazine disponivel incluido com # 4
Entre com proximo titulo ("fim" para encerrar)
IEEE Computer
Entre com 1=livro, 2=periodico (1 - 2)
2
IEEE Computer disponivel incluido com # 5
Entre com proximo titulo ("fim" para encerrar)
fim
Cadastramento dos usuarios
Entre com nome ("fim" para encerrar)

96

Cap. 9 / Estudo de Caso: Controle de Biblioteca


Joao da Silva
Entre com 1=usuario externo, 2=aluno, 3=professor (1 - 3)
1
Usuario Joao da Silva incluido com # 1
Entre com proximo nome ("fim" para encerrar)
Antonio Pereira
Entre com 1=usuario externo, 2=aluno, 3=professor (1 - 3)
2
Aluno Antonio Pereira incluido com # 2
Entre com proximo nome ("fim" para encerrar)
Clara Nunes
Entre com 1=usuario externo, 2=aluno, 3=professor (1 - 3)
3
Prof. Clara Nunes incluido com # 3
Entre com proximo nome ("fim" para encerrar)
fim
Atendimento aos usuarios
Entre com numero do usuario (0=fim) (0 - 3)
1
Usuario Joao da Silva
Entre com operacao:
1=retira, 2=devolve, 3=ver carga (1 - 3)
1
Entre com livro (1 - 5)
1
Tecnicas de Programacao disponivel
Tecnicas de Programacao retirado por Usuario Joao da Silva em 1/7/99 ate
5/7/99
Entre com numero do usuario (0=fim) (0 - 3)
2
Aluno Antonio Pereira
Entre com operacao:
1=retira, 2=devolve, 3=ver carga (1 - 3)
1
Entre com livro (1 - 5)
1
Tecnicas de Programacao retirado por Usuario Joao da Silva em 1/7/99 ate
5/7/99
Operacao rejeitada
Entre com numero do usuario (0=fim) (0 - 3)
3
Prof. Clara Nunes
Entre com operacao:
1=retira 2=devolve 3=consulta 4=bloqueia 5=desbloqueia(1-5)
4
Entre com livro (1 - 5)
2
Analise Orientada a Objetos disponivel
Entre com prazo (1 - 20)
10
Analise Orientada a Objetos bloqueado por Prof. Clara Nunes em 1/7/99 ate
11/7/99
Entre com numero do usuario (0=fim) (0 - 3)
1
Usuario Joao da Silva
Entre com operacao:
1=retira, 2=devolve, 3=ver carga (1 - 3)
1

Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

Cap. 9 / Estudo de Caso: Controle de Biblioteca

97

Entre com livro (1 - 5)


2
Analise Orientada a Objetos bloqueado por Prof. Clara Nunes em 1/7/99 ate
11/7/99
Operacao rejeitada
Entre com numero do usuario (0=fim) (0 - 3)
3
Prof. Clara Nunes
Entre com operacao:
1=retira 2=devolve 3=consulta 4=bloqueia 5=desbloqueia(1-5)
5
Entre com livro (1 - 5)
2
Analise Orientada a Objetos bloqueado por Prof. Clara Nunes em 1/7/99 ate
11/7/99
Analise Orientada a Objetos disponivel
Entre com numero do usuario (0=fim) (0 - 3)
2
Aluno Antonio Pereira
Entre com operacao:
1=retira, 2=devolve, 3=ver carga (1 - 3)
1
Entre com livro (1 - 5)
2
Analise Orientada a Objetos disponivel
Analise Orientada a Objetos retirado por Aluno Antonio Pereira em 1/7/99
ate 8/7/99
Entre com numero do usuario (0=fim) (0 - 3)
0

9.8. Exerccios de Fixao