|
|
| (500 intermediate revisions by the same user not shown) |
| Line 1: |
Line 1: |
| {{PRJPOAvisosEN20242025}}
| | #REDIRECT [[Programação com Objectos/Projecto de Programação com Objectos/Enunciado do Projecto de 2024-2025]] |
| {{PRJPOMandatory20242025}}
| |
| {{TOCright}}
| |
| '''<font color="red">EM PREPARAÇÃO</font>'''
| |
| <!--
| |
| '''<font color="red">ÉPOCA NORMAL</font>'''-->
| |
| | |
| O objectivo do projecto é desenvolver uma aplicação de gestão de um hotel veterinário que dispões de tratadores, veterinários e ecossistemas com árvores.
| |
| | |
| = Propriedades e funcionalidade =
| |
| | |
| Os animais são mantidos por tratadores que são responsáveis por distribuir a comida e pela limpeza dos habitats, e por veterinários, que têm a responsabilidade de zelar pela saúde dos animais. Quando um animal recebe uma vacina não apropriada à sua espécie, por causa de um erro veterinário, por exemplo, fica com a saúde afectada até ao fim da sua vida. Os habitats têm árvores. É possível calcular o grau de satisfação dos animais e dos funcionários.
| |
| | |
| == Animais ==
| |
| | |
| Os animais possuem uma chave única (cadeia de caracteres definida na altura do registo).
| |
| | |
| Cada animal é identificado ainda pelo nome (cadeia de caracteres; não única) e possui ainda informação acerca da sua espécie (cadeia de caracteres) e o estado de saúde (cadeia de caracteres).
| |
| | |
| == Funcionários ==
| |
| | |
| Os funcionários possuem uma chave única (cadeia de caracteres definida na altura do registo).
| |
| | |
| Os tratadores e veterinários são identificados ainda pelo nome (cadeia de caracteres; não única). Cada tratador possui ainda informação acerca dos habitats da sua responsabilidade. Associada a cada veterinário existe ainda informação relativa às espécies que sabe medicar e cujas doenças sabe diagnosticar.
| |
| | |
| == Habitats ==
| |
| | |
| Os habitats uma chave única (cadeia de caracteres definida na altura do registo).
| |
| | |
| Cada habitat tem ainda um nome (cadeia de caracteres; não única) e uma área (número inteiro). Os habitats são ainda caracterizados pelas árvores que contêm e informação relativa às espécies que residem nesse habitat e cuja satisfação este influencia.
| |
| | |
| == Árvores ==
| |
| | |
| As árvores possuem uma chave única (cadeia de caracteres definida na altura do registo).
| |
| | |
| As árvores podem ser de folha caduca ou perene e são caracterizadas pela dificuldade de limpeza (número inteiro) que colocam no recinto onde estão implantadas. As árvores de folha perene exigem sempre o mesmo esforço de limpeza do recinto, enquanto que as árvores de folha caduca exigem um esforço diferenciado (factor multiplicativo do grau de dificuldade: um inteiro), consoante o seu ciclo biológico: com folhas, sem folhas, a largar folhas, a gerar folhas.
| |
| | |
| == Vacinas ==
| |
| | |
| As vacinas possuem uma chave única (cadeia de caracteres definida na altura do registo).
| |
| | |
| Cada vacina é identificada ainda pelo nome (cadeia de caracteres; não única) e possui ainda informação acerca das espécies de animais a que pode ser aplicada, e o número de vezes que foi aplicada a cada animal.
| |
| | |
| A aplicação deve manter um registo da aplicação de vacinas a animais pelos veterinários.
| |
| | |
| = Funcionalidade da aplicação =
| |
| | |
| A aplicação além de permitir gerir informação relativa a todos aos conceitos acima, permite ainda calcular o estado de satisfação (um número inteiro) dos animais e funcionários, assim como a satisfação global (i.e., somatório da satisfação de todos os animais e funcionários: também um número inteiro).
| |
| | |
| Possui ainda a capacidade de preservar o seu estado (não é possível manter várias versões do estado da aplicação em simultâneo).
| |
| | |
| Deve ser possível efectuar pesquisas sujeitas a vários critérios e sobre as diferentes entidades geridas pela aplicação.
| |
| | |
| Uma base de dados textual com conceitos pré-definidos pode ser [[#Inicialização por Ficheiro de Dados Textuais|carregada no início da aplicação]].
| |
| | |
| {{Suggestion|Note-se que não é necessário nem desejável implementar de raiz a aplicação: já existem classes que representam e definem a interface geral da funcionalidade do ''core'' da aplicação, tal como é visível pelos comandos da aplicação.}}
| |
| {{CVSCode|A interface geral do ''core'' já está parcialmente implementada na classe '''hva.HotelManager''' e outras fornecidas (cujos nomes devem ser mantidos), devendo ser adaptadas onde necessário. É ainda necessário criar e implementar as restantes classes que suportam a operação da aplicação.}}
| |
| | |
| == Operações sobre animais ==
| |
| | |
| É possível registar, visualizar, e operar sobre animais. As operações podem corresponder a alteração da relação dos animais com outras entidades, como transferir animais entre habitats ou vacinar um animal, ou operar sobre um animal específico, e.g., consultar o estado de saúde ou a satisfação do animal num dado momento.
| |
| | |
| Não é possível remover animais.
| |
| | |
| == Operações sobre funcionários ==
| |
| | |
| É possível registar, visualizar, e operar sobre funcionários. As operações podem corresponder a alteração da relação dos funcionários com outras entidades, como atribuir ou retirar responsabilidades, ou operar sobre um funcionário específico, e.g., consultar a satisfação do funcionário num dado momento.
| |
| | |
| Não é possível remover funcionários.
| |
| | |
| == Pesquisas ==
| |
| | |
| É possível efectuar pesquisas sob vários critérios e sobre as diferentes entidades geridas: (i) animais que residem num determinado habitat; (ii) animais que tomaram uma determinada vacina; (iii) vacinas que foram dadas a um determinado animal; (iv) habitats da responsabilidade de um tratador; (v) árvores que pertencem a um determinado habitat.
| |
| | |
| == Serialização ==
| |
| | |
| É possível guardar e recuperar o estado actual da aplicação, preservando toda a informação relevante, descrita acima.
| |
| | |
| = Requisitos de desenho =
| |
| | |
| Devem ser possíveis extensões ou alterações de funcionalidade com impacto mínimo no código produzido: em particular, deve ser simples definir novos tipos de problemas decorrentes da aplicação incorrecta de vacinas. A definição de árvores com novos estados e diferentes formas de estimar a sua evolução; e novas políticas de cálculo da satisfação dos funcionários e animais.
| |
| | |
| Deve ser possível introduzir novos métodos de pesquisa com um impacto mínimo na implementação desenvolvida.
| |
| | |
| = Interação com o utilizador =
| |
| | |
| Descreve-se nesta secção a '''funcionalidade máxima''' da interface com o utilizador. Em geral, os comandos pedem toda a informação antes de procederem à sua validação (excepto onde indicado). Todos os menus têm automaticamente a opção '''Sair''' (fecha o menu).
| |
| | |
| As operações de pedido e apresentação de informação ao utilizador '''devem''' realizar-se através dos objectos ''form'' e ''display'', respectivamente, presentes em cada comando. As mensagens são produzidas pelos métodos das [[Programação com Objectos/Projecto de Programação com Objectos/Material de Apoio ao Desenvolvimento|bibliotecas de suporte]] ('''po-uilib''' e '''xxl-app'''). As mensagens não podem ser usadas no núcleo da aplicação ('''xxl-core'''). Além disso, não podem ser definidas novas. Potenciais omissões devem ser esclarecidas antes de qualquer implementação.
| |
| | |
| De um modo geral, sempre que no contexto de uma operação com o utilizador aconteça alguma excepção, então a operação não deve ter qualquer efeito no estado da aplicação, excepto se indicado em contrário na operação em causa.
| |
| | |
| As excepções usadas na interacção (subclasses de '''pt.tecnico.uilib.menus.CommandException'''), excepto se indicado, são lançadas pelos comandos (subclasses de '''pt.tecnico.uilib.menus.Command''') e tratadas pelos menus (instâncias de subclasses de '''pt.tecnico.uilib.menus.Menu'''). Outras excepções não devem substituir as fornecidas nos casos descritos.
| |
| | |
| {{CVSCode|Note-se que o programa principal e os comandos e menus, a seguir descritos, já estão parcialmente implementados nas ''packages'' '''xxl.app''', '''xxl.app.main''', '''xxl.app.edit''', '''xxl.app.search'''. Estas classes são de uso obrigatório e estão disponíveis no [[Programação com Objectos/Projecto de Programação com Objectos/Repositório GIT|GIT]] (módulo '''xxl-app''').}}
| |
| | |
| == Endereçamento de Células ==
| |
| | |
| Para o pedido de uma gama, utiliza-se a mensagem '''Prompt.address()'''. A excepção '''xxl.app.edit.InvalidCellRangeException''' é lançada se forem especificados endereços inválidos (excedem o limite da folha de cálculo ou representam gamas de células que não são intervalos verticais ou horizontais).
| |
| | |
| == Menu Principal ==
| |
| As acções deste menu permitem gerir a salvaguarda do estado da aplicação, abrir submenus e aceder a alguma informação global. A lista completa é a seguinte: [[#Salvaguarda do estado actual da aplicação|Criar]], [[#Salvaguarda do estado actual da aplicação|Abrir]], [[#Salvaguarda do estado actual da aplicação|Guardar]], [[#Gestão e consulta de dados da aplicação|Menu de Edição]], [[#Gestão e consulta de dados da aplicação|Menu de Consultas]].
| |
| | |
| As etiquetas das opções deste menu estão definidas na classe '''xxl.app.main.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos em '''xxl.app.main.Prompt''' e '''xxl.app.main.Message'''.
| |
| | |
| {{CVSCode|Estes comandos já estão implementados nas classes da ''package'' '''xxl.app.main''' (disponível no GIT), respectivamente: '''DoNew''', '''DoOpen''', '''DoSave''', '''DoMenuOpenEdit''', '''DoMenuOpenSearch'''.}}
| |
| | |
| === Salvaguarda do estado actual da aplicação ===
| |
| | |
| Inicialmente, a aplicação não tem nenhuma folha, excepto quando usada a propriedade '''import''' (ver abaixo) para pré-carregar dados iniciais. Na situação em que a aplicação começa sem nenhuma folha, apenas são apresentadas as opções Criar e Abrir, pois as restantes necessitam da existência de uma folha. As opções irrelevantes nesta situação devem ser omitidas.
| |
| O conteúdo da aplicação (toda a informação actualmente em memória) pode ser guardado para posterior recuperação (via serialização Java: '''java.io.Serializable'''). Na leitura e escrita do estado da aplicação, devem ser tratadas as excepções associadas. A funcionalidade é a seguinte:
| |
| | |
| * '''Criar''' -- Cria uma nova folha vazia: pedem-se as dimensões da nova folha, devendo ser utilizadas as mensagens '''Prompt.lines()''' e '''Prompt.columns()'''. Esta folha não fica associada a nenhum ficheiro (é anónima).
| |
| * '''Abrir''' -- Carrega os dados de uma sessão anterior a partir de um ficheiro previamente guardado (ficando este ficheiro associado à aplicação, para futuras operações de salvaguarda). Pede-se o nome do ficheiro a abrir ('''Prompt.openFile()'''). Caso ocorra um problema na abertura ou processamento do ficheiro, deve ser lançada a excepção '''FileOpenFailedException'''. A execução bem-sucedida desta opção substitui toda a informação da aplicação.
| |
| * '''Guardar''' -- Guarda o estado actual da aplicação no ficheiro associado. Se não existir associação, pede-se o nome do ficheiro a utilizar, ficando a ele associado (para operações de salvaguarda subsequemtes). Esta interacção realiza-se através do método '''Prompt.newSaveAs()'''. Não é executada nenhuma acção se não existirem alterações desde a última salvaguarda.
| |
| | |
| Apenas existe uma folha na aplicação. Quando se abandona uma folha com modificações não guardadas (porque se cria ou abre outra), deve perguntar-se se se quer guardar a informação actual antes de a abandonar, através de '''Prompt.saveBeforeExit()''' (a resposta é obtida invocando '''readBoolean()''' ou de '''Form.confirm()''').
| |
| | |
| Note-se que a opção '''Abrir''' não permite a leitura de ficheiros de texto (estes apenas podem ser utilizados no início da aplicação).
| |
| | |
| A opção '''Sair''' nunca implica a salvaguarda do estado da aplicação, mesmo que existam alterações.
| |
| | |
| === Gestão e consulta de dados da aplicação ===
| |
| | |
| Além das operações de manipulação de ficheiros, existem ainda no menu principal as seguintes opções.
| |
| | |
| * '''Menu de Edição''' -- Abre o menu de edição.
| |
| * '''Menu de Consultas''' -- Abre o menu de consultas (pesquisas).
| |
| | |
| Estas opções só estão disponíveis quando existir uma folha activa válida.
| |
| | |
| == Menu de Edição ==
| |
| | |
| O menu de edição permite visualizar e alterar o conteúdo das células da folha activa. A lista completa é a seguinte: [[#Visualizar|Visualizar]], [[#Inserir|Inserir]], [[#Copiar|Copiar]], [[#Apagar|Apagar]], [[#Cortar|Cortar]], [[#Colar|Colar]] e [[#Visualizar cut buffer|Visualizar cut buffer]]. As secções abaixo descrevem estas opções.
| |
| | |
| As etiquetas das opções deste menu estão definidas na classe '''xxl.app.edit.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos em '''xxl.app.edit.Prompt''' e '''xxl.app.edit.Message'''.
| |
| | |
| {{CVSCode|Estes comandos já estão implementados nas classes da ''package'' '''xxl.app.edit''' (disponível no GIT), respectivamente: '''DoShow''', '''DoInsert''', '''DoCopy''', '''DoDelete''', '''DoCut''', '''DoPaste''', '''DoShowCutBuffer'''.}}
| |
| | |
| === Visualizar ===
| |
| | |
| Permite visualizar a gama especificada ([[#Endereçamento de Células|Endereçamento]]), de acordo com os formatos abaixo. Se o conteúdo não for um literal, deve ser apresentado o seu valor e a sua expressão. Não deve ser apresentado qualquer conteúdo para células vazias.
| |
| | |
| Formatos (''valor'' representa o valor final da célula, inteiro ou cadeia de caracteres, depois de efectuadas todas as avaliações):
| |
| * Célula vazia:
| |
| ''linha''''';'''''coluna'''''|'''
| |
| * Célula com um valor (literal):
| |
| ''linha''''';'''''coluna'''''|'''''valor''
| |
| * Célula com um valor (calculado a partir de ''expressão'': referência ou função):
| |
| ''linha''''';'''''coluna'''''|'''''valor'''''='''''expressão''
| |
| * Intervalo vertical (''conteúdo'' é um dos três casos iniciais):
| |
| ''linha1''''';'''''coluna'''''|'''''conteúdo''
| |
| ''linha2''''';'''''coluna'''''|'''''conteúdo''
| |
| ''linha3''''';'''''coluna'''''|'''''conteúdo''
| |
| * Intervalo horizontal (''conteúdo'' é um dos três casos iniciais):
| |
| ''linha''''';'''''coluna1'''''|'''''conteúdo''
| |
| ''linha''''';'''''coluna2'''''|'''''conteúdo''
| |
| ''linha''''';'''''coluna3'''''|'''''conteúdo''
| |
| | |
| === Inserir ===
| |
| | |
| É pedida a gama ([[#Endereçamento de Células|Endereçamento]]). É especificado o conteúdo a inserir ([[#Conteúdo: Literais, Referências, Funções|Conteúdo]]), através da mensagem '''Prompt.contents()'''. O conteúdo é inserido em todas as células da gama. Se for inserido um nome de função inexistente, é lançada a excepção '''xxl.app.edit.UnknownFunctionException'''.
| |
| | |
| === Copiar ===
| |
| | |
| É pedida a gama ([[#Endereçamento de Células|Endereçamento]]) cujo conteúdo deve ser copiado para o cut buffer.<!-- Os conteúdos copiados são independentes da folha (i.e., alterações aos originais não são propagadas para o cut buffer).-->
| |
| | |
| === Apagar ===
| |
| | |
| É pedida a gama ([[#Endereçamento de Células|Endereçamento]]) cujo conteúdo deve ser apagado.
| |
| | |
| === Cortar ===
| |
| | |
| É pedida a gama ([[#Endereçamento de Células|Endereçamento]]). Esta acção corresponde à execução sequencial das acções descritas em [[#Copiar|Copiar]] e [[#Apagar|Apagar]].
| |
| | |
| === Colar ===
| |
| | |
| É pedida a gama ([[#Endereçamento de Células|Endereçamento]]). Insere o conteúdo do cut buffer na gama especificada.
| |
| | |
| === Visualizar cut buffer ===
| |
| | |
| Permite visualizar o conteúdo do cut buffer. O formato de apresentação é o descrito em [[#Visualizar|Visualizar]].
| |
| | |
| == Menu de Consultas ==
| |
| | |
| O menu de consultas permite efectuar pesquisas sobre as células da folha activa, produzindo listas de células. Sempre que for feita uma consulta e nenhuma entidade satisfizer as condições associadas ao pedido, nada deve ser apresentado.
| |
| | |
| A lista completa das consultas é a seguinte: [[#Procurar Valor|Procurar Valor]], [[#Procurar Função|Procurar Função]]. As secções abaixo descrevem estas opções.
| |
| | |
| As etiquetas das opções deste menu estão definidas na classe '''xxl.app.search.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos em '''xxl.app.search.Prompt''' e '''xxl.app.search.Message'''.
| |
| | |
| {{CVSCode|Estes comandos já estão implementados nas classes da ''package'' '''xxl.app.search''' (disponível no GIT), respectivamente: '''DoShowValues''', '''DoShowFunctions'''.}}
| |
| | |
| === Procurar Valor ===
| |
| Pede-se o valor a procurar ('''Prompt.searchValue()''') e apresentam-se os resultados.
| |
| | |
| O termo de pesquisa deve ser comparado com o valor avaliado de cada célula. As células que obedecem ao critério de procura devem ser apresentadas por ordem ascendente de linha e coluna e utilizando o formato especificado em [[#Visualizar|Visualizar]]. Assim, considere-se o exemplo:
| |
| | |
| 1;1|4
| |
| 1;2|1
| |
| 1;3|5
| |
| 2;1|5=ADD(1;1,1;2)
| |
| 2;2|
| |
| 2;3|
| |
| | |
| Neste exemplo, uma pesquisa pelo valor 5 encontraria as células 1;3 e 2;1.
| |
| | |
| 1;3|5
| |
| 2;1|5=ADD(1;1,1;2)
| |
| | |
| ===Procurar Função ===
| |
| | |
| Pede-se o segmento a procurar num nome de função ('''Prompt.searchFunction()''') e apresentam-se os resultados ordenados (são apresentados como especificado em [[#Visualizar|Visualizar]]), de forma ascendente, por nome de função, linha e coluna (por esta ordem).
| |
| | |
| = Inicialização por Ficheiro de Dados Textuais =
| |
| | |
| Por omissão, quando a aplicação começa, não contém nenhuma informação. No entanto, além das opções de manipulação de ficheiros descritas no [[#Salvaguarda do Documento Actual|menu principal]], é possível iniciar exteriormente a aplicação com um ficheiro de texto especificado pela propriedade Java '''[[#Execução dos Programas e Testes Automáticos|import]]'''. Quando se especifica esta propriedade, a aplicação é povoada com os objectos correspondentes ao conteúdo do ficheiro indicado.
| |
| | |
| No processamento destes dados, assume-se que não existem entradas mal-formadas. Sugere-se a utilização do método '''String.split()''' para dividir uma cadeia de caracteres em campos.
| |
| | |
| No seguinte exemplo, o conteúdo do ficheiro inicial ('''test.import''') correspondente à folha apresentada a seguir.
| |
| {{CollapsedCode|Exemplo de ficheiro de entrada textual|
| |
| <source lang="text">
| |
| TREE|T1|Pinheiro 1|20|PERENE
| |
| TREE|T4|Pinheiro 4|20|PERENE
| |
| TREE|T2|Acácia|10|COMFOLHAS
| |
| TREE|T6|Eucalipto|10|SEMFOLHAS
| |
| TREE|T3|Oliveira|20|COMFOLHAS
| |
| TREE|01|Oliveira preta|20|GERARFOLHAS
| |
| TREE|30|Oliveira verde|20|LARGARFOLHAS
| |
| HABITAT|AR1|Aldeia dos Macacos|20|T3,01,30,T2
| |
| HABITAT|AR2|Floresta tropical|30|T1,T4,T6
| |
| HABITAT|AR3|Deserto|3
| |
| SPECIES|C10|ave
| |
| SPECIES|C8|mamífero
| |
| SPECIES|C1|peixe
| |
| ANIMAL|A1|Alex|C10|ruuuuuuuuuuuuu|AR1
| |
| ANIMAL|A2|Nemo|C1|gluglu|AR2
| |
| ANIMAL|AA|Bobi|C8|ãoão rrrrrrrrr|AR1
| |
| ANIMAL|MA|Chita|C8|huhu huhu|AR2
| |
| VET|V2|Jorge Figueiredo|C10,C8,C1
| |
| VET|V4|Filomena Figueiredo
| |
| VET|VR|Abdul Figueiredo|C8
| |
| KEEPER|W2SO4|John Figueiredo|AR2,AR3
| |
| KEEPER|W2O|Rohit Figueiredo|AR1
| |
| KEEPER|W24|Rohit Figueiredo
| |
| VACCINE|V3|Tétano|C8
| |
| VACCINE|V200|Parasitas intestinais|C10,C8,C1
| |
| VACCINE|V42172|Tétano|C10
| |
| VACCINE|Vexperimental|Gripe A1|C8
| |
| </source>
| |
| }}
| |
| | |
| A codificação dos ficheiros a ler é garantidamente [[wp:UTF-8|UTF-8]].
| |
| | |
| {{Suggestion|Note-se que o programa nunca produz ficheiros com este formato.}}
| |
| | |
| = Execução dos Programas e Testes Automáticos =
| |
| | |
| Usando os ficheiros '''test.import''', '''test.in''' e '''test.out''', é possível verificar automaticamente o resultado correcto do programa. Note-se que é necessária a definição apropriada da variável '''CLASSPATH''' (ou da opção equivalente '''-cp''' do comando '''java'''), para localizar as classes do programa, incluindo a que contém o método correspondente ao ponto de entrada da aplicação ('''hva.app.App.main'''). As propriedades são tratadas automaticamente pelo código de apoio.
| |
| | |
| java -Dimport=test.import -Din=test.in -Dout=test.outhyp hva.app.App
| |
| | |
| Assumindo que aqueles ficheiros estão no directório onde é dado o comando de execução, o programa produz o ficheiro de saída '''test.outhyp'''. Em caso de sucesso, os ficheiros das saídas esperada ('''test.out''') e obtida ('''test.outhyp''') devem ser iguais. A comparação pode ser feita com o comando:
| |
| | |
| diff -b test.out test.outhyp
| |
| | |
| Este comando não deve produzir qualquer resultado quando os ficheiros são iguais. Note-se, contudo, que este teste não garante o correcto funcionamento do código desenvolvido, apenas verificando alguns aspectos da sua funcionalidade.
| |
| <!--
| |
| [[category: Ensino]]
| |
| [[category:PO]]
| |
| [[category: Projecto de PO]]
| |
| [[en:Object-Oriented Programming]]
| |
| -->
| |