livrojava cap 09

22
Copyright © 2003, Cecília Rubira. Todos os direitos reservados. 9. Estudo de Caso: Controle de Biblioteca Neste capítulo é desenvolvida uma pequena aplicação onde são empregados os quatro conceitos fundamentais de orientação a objetos: tipos abstratos de dados, encapsulamento, herança e polimorfismo. São apresentadas também algumas técnicas de modelagem especialmente úteis para programação orientada a objetos. Ao final deste capítulo o estudante deverá ser capaz de interpretar, projetar e desenvolver programas que utilizam hierarquias de classes. 9.1. Descrição do Problema A aplicação que vamos desenvolver se destina a uma escola que possui uma biblioteca aberta aos seus alunos, professores e ao público em geral. O objetivo do sistema é manter um registro dos empréstimos efetuados, visando controlar a situação de cada volume individualmente e garantir que os empréstimos sejam efetuados de acordo com as normas da biblioteca, descritas a seguir. Os livros só podem ser retirados da biblioteca por usuários cadastrados numa das seguintes categorias: aluno da escola, professor ou usuário externo. Os alunos devem renovar seu cadastro a cada período letivo. O número máximo de volumes que um usuário pode retirar, num mesmo período, e o prazo de empréstimo dependem da categoria do usuário, de acordo com a seguinte tabela: Categoria Quantidade Dias de Prazo Usuários comuns 2 4 Alunos 3 7 Professores 5 14 Os limites acima são reduzidos nos seguintes casos: (i) o aluno com cadastro vencido fica sujeito aos mesmos limites de um usuário comum, até que providencie sua renovação; (ii) o usuário com algum prazo de devolução vencido fica impedido de retirar outros volumes, retornando à sua condição normal após a devolução do(s) livro(s) em atraso; (iii) periódicos, como revistas e jornais, só podem ser retirados por professores, por um prazo máximo de 7 dias; (iv) um professor pode bloquear um número qualquer de livros ou periódicos, impedindo que os mesmos sejam retirados da biblioteca durante um período de até 20 dias. 9.2. Projeto das Classes Uma primeira análise das informações acima nos permite perceber a existência de dois principais tipos de objetos envolvidos no problema: de um lado os usuários cadastrados e de outro os livros do acervo da biblioteca. As principais operações envolvidas são empréstimos e devoluções de livros pelos usuários. Os usuários são divididos em três categorias: usuários externos, alunos e professores. Os usuários externos são os mais limitados quanto às operações que podem efetuar. Iremos considerar alunos e professores como subtipos desses usuários, já que tanto um aluno como um professor pode "substituir" um usuário em qualquer das operações previstas para o mesmo: retirada e devolução de livros. Note que o inverso não é verdadeiro: as operações

Upload: vitor-marcal

Post on 16-Sep-2015

217 views

Category:

Documents


0 download

DESCRIPTION

Livro de java implementando sistema

TRANSCRIPT

  • Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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 2 4

    Alunos 3 7 Professores 5 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

  • 78 Cap. 9 / Estudo de Caso: Controle de Biblioteca

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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.

  • Cap. 9 / Estudo de Caso: Controle de Biblioteca 79

    Usuario

    UsuarioAluno UsuarioProfessor

    Livro

    Periodico

    Retira

    Bloqueia

    1 0..*

    1

    0..*

    Controle daBiblioteca

    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

    devolve

    prazo de emprstimo vencidoatingiu cota mxima OU

    apto aa devolverretirar

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

  • 80 Cap. 9 / Estudo de Caso: Controle de Biblioteca

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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

    devolve

    prazo de emprstimo vencidocom + de 2 livros OU

    renova

    cadastrovencido

    cadastro

    devolve

    prazo de emprstimo vencidocom + de 1 livro OU

    renova

    cadastrovencido

    cadastro

    retira / devolve

    apto a retirar a devolverE regular

    apto a retirarE a renovar

    a devolverE a renovar

    E regular

    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

    devolve

    prazo de emprstimo vencidoatingiu cota mxima OU

    bloqueia / desbloqueia bloqueia / desbloqueia

    apto a a devolverretirar

    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.

  • Cap. 9 / Estudo de Caso: Controle de Biblioteca 81

    empresta

    retorna

    desbloqueia OUbloqueia

    disponvel emprestado

    bloqueado

    prazo de

    E em atraso

    emprstimovencido

    emprestado

    retornaprazo de bloqueiovencido

    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.

    apto a retirar ?

    Usuario Livro

    disponvel ?

    guarda dadosdo emprstimo

    sim

    sim

    adiciona livro nacarga do usurio

    no

    no

    calcula datade retorno

    OKerro

    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.

  • 82 Cap. 9 / Estudo de Caso: Controle de Biblioteca

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    apto a retirar ?

    Usuario Peridico

    disponvel ?

    guarda dadosdo emprstimo

    sim

    sim

    adiciona livro nacarga do usurio

    no

    no

    calcula datade retorno

    Livro

    professor ?simno usurio

    OKerro

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

  • Cap. 9 / Estudo de Caso: Controle de Biblioteca 83

    Usuario Livro

    que retirou ?

    coloca disponvel

    sim

    retira livro nacarga do usurio

    no mesmo usurio

    OKerro

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

    UsuarioProfessor Livro

    disponvel ?

    guarda dadosdo bloqueio

    sim

    no

    calcula data final

    OKerro

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

  • 84 Cap. 9 / Estudo de Caso: Controle de Biblioteca

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    UsuarioProfessor Livro

    mesmo usurio

    sim

    noque bloqueou ?

    coloca disponvel

    OKerro

    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) { } }

  • 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() e 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

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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.

  • 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()); }

  • 88 Cap. 9 / Estudo de Caso: Controle de Biblioteca

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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).

  • 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

    dtDevolucao< hoje ? true

    em atraso

    bloqueadoPor== null ?false

    dtDesbloqueio< hoje ? true

    disponivel

    false

    bloqueado

    true

    disponivel

    Fig. 9.6.4 - rvore de Decises para Estado de Livro

  • 90 Cap. 9 / Estudo de Caso: Controle de Biblioteca

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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); }

  • 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

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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)"); } }

  • Cap. 9 / Estudo de Caso: Controle de Biblioteca 93

    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)); }

  • 94 Cap. 9 / Estudo de Caso: Controle de Biblioteca

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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.nvalate ); return((int)st.nval); }

  • 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

    Copyright 2003, Ceclia Rubira. Todos os direitos reservados.

    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

  • 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