Você está na página 1de 16

INSTITUTO SUPERIOR MANUEL TEIXEIRA GOMES

CURSO DE LICENCIATURA EM ENGENHARIA INFORMÁTICA


Ano Letivo 2019/2020

RELATÓRIO DO TRABALHO PRÁTICO I

Discentes:
Luís André Marreiros Silva nº21907478
Nelson Filipe Paulos Moreira nº21901240

Docente:
Prof. Doutor Tiago Candeias

Portimão, dezembro 2019


ÍNDICE

ÍNDICE..........................................................................................................................2

ÍNDICE DE FIGURAS ...................................................................................................3

INTRODUÇÃO..............................................................................................................4
Programação Orientada a Objetos ............................................................................5

Test Driven Development ..........................................................................................5

ANÁLISE INICIAL ........................................................................................................6


Classe POI ................................................................................................................6

Classe Client .............................................................................................................6

Classe Circle e Point .................................................................................................6

DESENVOLVIMENTO ..................................................................................................8
Classe Centroid .........................................................................................................9

Classe POI ................................................................................................................9

Classe Circle .............................................................................................................9

Classe Square .........................................................................................................10

Classe Shape ..........................................................................................................10

Classe Client ...........................................................................................................11

TESTES ......................................................................................................................13

CONSIDERAÇÕES FINAIS ........................................................................................14

REFERÊNCIAS ..........................................................................................................16

2
ÍNDICE DE FIGURAS

Figura 1 - Disposição dos pontos no mapa bidimensional .............................................4


Figura 2 - Diagrama UML inicial ....................................................................................7
Figura 3 - Diagrama UML final ....................................................................................12
Figura 4 - Diagrama UML das classes de teste ...........................................................13
Figura 5 - Situação do teste isInside() não funciona corretamente. .............................15

3
INTRODUÇÃO

Este relatório foi desenvolvido no âmbito da unidade curricular de Programação


Orientada a Objetos do curso de Licenciatura em Engenharia Informática, cujo docente
responsável é o Sr. Prof. Doutor Tiago Candeias.
Este relatório tem como objetivo a descrição pormenorizada do problema,
análise, metodologia de desenvolvimento e uma breve explicação dos métodos
implementados para o alcance da solução do primeiro trabalho prático.
O trabalho prático incide sobre os conceitos de encapsulamento e herança,
estudados no âmbito de programação orientada a objetos. Atribuímos o nome de “POI”
ao projeto, sigla de “Point Of Interest” pois o foco é maioritariamente nos pontos de
interesse. Este trabalho prático tem como objetivo o desenvolvimento de um programa
com a linguagem de programação Java que permita resolver o seguinte problema:
- Dado um conjunto de pontos dispersos num mapa bidimensional, pretende-se
encontrar os pontos de interesse (POI), de acordo com a disposição desses pontos, tal
como exemplificado na figura seguinte.

Figura 1 - Disposição dos pontos no mapa bidimensional


É encontrado um POI num conjunto disperso de pontos, quando mais de 70%
dos pontos estão contidos no círculo com centro na posição do centroide1 desses
pontos. Para um melhor entendimento do problema, recomendamos a leitura do
enunciado disponível em anexo neste documento.

1
Em geometria, o centroide (pré-AO 1990: centróide) é o ponto associado a uma forma
geométrica também conhecida como centro geométrico. Caso a forma geométrica represente
uma seção homogênea de um corpo, então o centroide coincide com o centro de massa. [2]

4
O desenvolvimento do trabalho prático conta com a imposição dos seguintes
requisitos:
• Realizar o planeamento através do desenho do diagrama de classes UML que
identifica as classes do problema e da solução;
• Utilizar os princípios e técnicas estudadas sobre programação orientada a
objetos, identificando e implementando classes coesas;
• Seguir uma metodologia de desenvolvimento baseado em testes (TDD – Test
Driven Development);
• Considerar a utilização de classes invariantes e de exceções.

Programação Orientada a Objetos


A programação orientada a objetos(POO, ou OOP segundo as suas siglas) é um
paradigma de programação baseado no conceito de “objetos”. Objetos são instâncias
de classes, que determinam qual informação um objeto contém e como ele pode
manipulá-la. Um dos grandes diferenciais da programação orientada a objetos em
relação a outros paradigmas de programação que também permitem a definição de
estruturas e operações sobre essas estruturas está no conceito de herança, mecanismo
através do qual definições existentes podem ser facilmente estendidas. Juntamente com
a herança deve ser enfatizada a importância do polimorfismo, que permite selecionar
funcionalidades que um programa irá utilizar de forma dinâmica, durante sua execução.
[1]
Entre as linguagens orientadas a objetos, encontramos o Java, a linguagem
utilizada para o desenvolvimento da solução deste trabalho prático.

Test Driven Development


O Test Driven Development (TDD) é uma metodologia de programação que
instrui os programadores a escrever código novo apenas se um teste automatizado
falhar. Isso evita a duplicação de código. O desenvolvimento orientado a testes
começa com o design e o desenvolvimento de testes para todas as pequenas
funcionalidades de um programa. Na abordagem TDD, inicialmente, é desenvolvido o
teste que especifica e valida o que o código fará. TDD significa "Desenvolvimento
Orientado a Testes". O objetivo principal do TDD é tornar o código mais claro, simples
e sem erros. [2]

5
ANÁLISE INICIAL

Após uma análise inicial ao enunciado do trabalho prático, decidimos separar o


desenvolvimento em diferentes partes ou classes e usar a metodologia de
desenvolvimento “TDD”(Test Driven Development) lecionada durante as aulas.
Inicialmente e com facilidade verificámos a necessidade da existência de quatro
classes diferentes. Estas classes seriam a classe Client, Point, POI e Circle. As classes
Point e Circle foram disponibilizadas pelo docente, sendo que apenas precisariam de
alguns ajustes para adaptá-las à nossa necessidade.

Classe POI
Rapidamente verificámos a necessidade de um método para o cálculo do centroide
através dos pontos fornecidos no input. Esse método retornaria um objeto Point
composto pelas coordenadas cartesianas X e Y do centroide.

Classe Client
Na nossa análise compreendemos que o termo cliente se refere a qualquer entidade
que requer um serviço de outra entidade. O cliente não se importa como a entidade
fornece o serviço, apenas que o forneça. Por assim ser, a classe Client processaria o
input, criaria um Objeto POI composto por centroides e após chamada do método
“solve()” trataria de resolver o input.

Classe Circle e Point


Ambas as classes foram fornecidas pelo professor, inicialmente não verificámos
necessidade de alteração da classe Point.
Na classe Circle achámos necessário o desenvolvimento de um método que verificasse
se um determinado ponto se inseria dentro do círculo. Este método “checkInside()”
receberia um objeto Point como argumento e retornaria um Boolean2.

2
Em ciência da computação, boolean é um tipo de dado primitivo que possui dois valores, que
podem ser considerados como 0 ou 1, falso ou verdadeiro. [3]

6
A figura abaixo representa o diagrama UML inicial, a nossa primeira análise das
classes/estruturas. Esta apresenta bastantes diferenças em relação ao diagrama UML
final que está disponibilizado mais à frente neste relatório.

Figura 2 - Diagrama UML inicial


Na classe Point havia a necessidade da conversão das

7
DESENVOLVIMENTO

O desenvolvimento da solução deste trabalho passou pela divisão de tarefas e


atribuição das mesmas a cada elemento do grupo. Sendo assim as tarefas foram
divididas e distribuídas da seguinte forma:
• Desenvolvimento da classe Client – ambos os elementos;
• Desenvolvimento da classe POI – ambos os elementos;
• Desenvolvimento da classe Circle e respetivos testes– Luís Silva;
• Desenvolvimento da classe Square e respetivos testes – Nelson Moreira;
• Desenvolvimento da classe Centroid e respetivos testes – ambos;
• Desenvolvimento da classe Shape – ambos.

Após a sugestão do docente de desenvolver a classe Square, após o desenvolvimento


da classe Circle, com o objetivo de generalizarmos o nosso programa para o
funcionamento com qualquer forma geométrica, decidimos criar uma classe abstrata
Shape. As classes Circle e Square extendem a classe Shape. Na classe abstrata Shape
definimos os métodos de integração obrigatórios das classes hierárquicas, assim como
o método “percentageInside” que é comum a ambas.
Assim sendo as nossas classes Circle e Square implementam os seguintes métodos:
• calculateArea();
• isInside();
• solver();

O método calculateArea() é responsável pelo cálculo da área da forma geométrica.


O método isInside() recebe um ponto como argumento e verifica se o mesmo está
contido na forma geométrica.
O método percentageInside() calcula a percentagem de pontos que se encontram
dentro da forma geométrica.
O método solver() recebe um objeto POI e um instante de tempo e calcula o raio/largura
da forma geométrica na qual se encontram pelo menos 70% dos pontos.

Em todas as classes foram criados os respetivos “getters” e “setters” de todos os


argumentos que compõem a construção desses mesmos objetos.

8
Classe Centroid
Desenvolvemos a classe Centroid à qual anteriormente tínhamos dado o nome de
Container por ser um objeto que alberga dois argumentos. Um objeto Centroid é
composto por um ponto e um instante. Este ponto representa as coordenadas
cartesianas x e y num mapa bidimensional num determinado instante.

Classe POI
De acordo com a análise inicial houve a necessidade da criação da classe POI.
Esta classe é responsável por grande parte do tratamento da resolução do problema.
Um objeto POI é composto por ArrayList de Centroides. A classe POI conta com classes
tais como:
• findCentroid() – responsável pelo cálculo do centroide num determinado
instante;
• uniqueTime() – método que através de um iterador e uma estrutura de controlo
condicional, percorre todos os centroides do ArrayList de Centroides e filtra os
tempos únicos. Este método foi implementado para reforçar a generalização da
classe, desta forma o programa lê funcionar com qualquer instante(ex.:
0,1,2,3,10,...).
• pointsAtTime() – método que com um instante como argumento de entrada,
devolve um ArrayList de pontos nesse determinado instante. Este método, à
semelhança do método anterior, faz recurso de um iterador e uma estrutura de
controlo condicional para atingir o objetivo.

Classe Circle
De acordo com o mencionado anteriormente neste relatório, esta classe estende a
classe abstrata Shape, nesta classe implementámos todos os métodos impostos pela
mesma. Estes são:
• isInside() – Este método verifica se um ponto passado como argumento se
encontra dentro do objeto Circle. Esta verificação é feita através de uma
estrutura de controlo condicional “if”, que com recurso ao método “dist()” da
classe Point verifica se a distância entre o ponto de argumento e o centro do
objeto Circle é menor que o raio do mesmo ou não.
• solver() – Este método foi implementado para calcular o raio do objeto Circle
em que se encontrem pelo menos 70% dos pontos. Esta função aceita um

9
objeto Point e um instante como argumento. Este método recursivo verifica
através de uma estrutura de controlo condicional “if” se a percentagem de
pontos dentro do objeto Square é superior a 70% com recurso ao método
“percentageInside()” da classe hierárquica Shape, que por sua vez faz recurso
ao método “isInside()”, criando assim uma interdependência dos mesmos. O
raio do objeto Circle é aumentado até que a percentagem seja igual ou
superior a 70%; retorna o raio.
• calculateArea() – Método que calcula a área do Círculo.

Classe Square
À semelhança da classe Circle, esta classe estende a classe abstrata Shape, nesta
classe implementámos todos os métodos impostos pela class Shape, assim como
métodos necessários no alcance da solução. Estes são:
• topRightCorn() – Implementámos este método para calcular o ponto superior
direito do objeto Square;
• botLeftCorn() – À semelhança do anterior, este método foi implementado para
calcular o ponto inferior esquerdo do objeto;
• isInside() – Este método booleano verifica se um ponto passado como
argumento se encontra dentro do objeto Square. Esta verificação é feita
através de uma estrutura de controlo condicional “if” que com recurso aos
métodos “topRightCorn()” e “botLeftCorn()” verifica se a coordenadas do ponto
passado como argumento se encontram dentro do objeto Square.
• solver() – à semelhança da classe Circle, este método aceita um objeto Point e
um instante como argumento. Este método recursivo verifica através de uma
estrutura de controlo condicional “if” se a percentagem de pontos dentro do
objeto Square é superior a 70% com recurso ao método “percentageInside()”
da classe hierárquica Shape, que por sua vez faz recurso ao método
“isInside()”, criando assim uma interdependência dos mesmos. O raio do objeto
Square é aumentado até que a percentagem seja igual ou superior a 70%;
retorna o raio.

Classe Shape
Implementámos a classe abstrata Shape para que o nosso programa possa operar de
forma generalizada, desta forma esta classe engloba as classes Circle e Square. No
futuro poderá englobar qualquer outra forma geométrica desde que a mesma

10
implemente os métodos obrigatórios “calculateArea” e “isInside”, este último
imprescindível na solução do trabalho prático. Esta classe abstrata conta com os
seguinte método comum a ambas as classes que extendem esta classe:
• percentageInside() – este método recebe uma lista de pontos, percorre todos
os elementos e com recurso a um iterador e uma estrutura de controlo
condicional, calcula a percentagem de pontos dentro do objeto Circle.
Inicialmente este método e o método “isInside()” eram um só. Posteriormente
achámos necessário a separação de ambos pois o método “isInside()” deu
bastante jeito na verificação de determinados pontos durante esta fase de
desenvolvimento.

Classe Client
Foi implementada uma estrutura de controlo “for” para o processamento do input. A
leitura do input foi feita da seguinte forma:
1. Leitura do número de pontos;
2. Leitura das coordenadas X e Y, e o tempo;
3. Criação de um objeto Point com as coordenadas X e Y;
4. Criação de um objeto centroide composto pelo ponto criado e o tempo;
5. Adição do centroide a um ArrayList de objetos.
Criámos um objeto POI composto pelo ArrayList de centroides e uma lista de números
inteiros que com recurso ao método “uniqueTime()” guarda todos os instantes únicos
de tempo.
Através de um iterador percorremos cada instante e para cada, corremos o método
solver no nosso objeto Circle ou Square, e imprimimos o valor do centroide.

11
Após o desenvolvimento do programa e com recurso ao plugin UML do IDE IntelliJ,
gerámos o diagrama UML da figura abaixo.

Figura 3 - Diagrama UML final

Este diagrama contém todas as classes desenvolvidas assim como as classes de


teste usadas durante o desenvolvimento do projeto com a metodologia movida por
testes (TDD).

12
TESTES

Ainda que tenhamos tido alguma dificuldade em acompanhar esta metodologia,


principalmente devido ao planeamento inicial, implementámos testes para todos os
métodos das classes desenvolvidas. Todos os testes implementados e que
acompanham a entrega deste documento estão validados e sem erros. Só avançámos
com o desenvolvimento de determinados métodos após verificarmos que os que
estavam em desenvolvimento operavam corretamente. As classes dos testes
implementados podem ser consultados na figura abaixo.

Figura 4 - Diagrama UML das classes de teste

13
CONSIDERAÇÕES FINAIS

A realização deste trabalho foi bastante positiva pois permitiu consolidar as


aprendizagens adquiridas e praticadas ao longo das aulas. Com a elaboração do
mesmo conseguimos aprofundar conhecimento e desenvolver diversas competências
relacionadas com a programação em Java, programação orientada a objetos e ainda
metodologias de desenvolvimento orientadas a testes.
Para a execução deste projeto foi necessário o recurso das soluções dos
exercícios práticos elaborados nas aulas, slides disponibilizados pelo docente, assim
como o recurso constante à pesquisa online para resolução de dúvidas, fortalecer
conceitos já adquiridos e desenvolver competências na construção de conhecimentos.
Na área de tecnologias da informação, nomeadamente a área da programação, é
indispensável que os programadores estejam em permanente formação e atualização.
Acreditamos até que o tempo a programar é relativamente pequeno quando comparado
com o tempo de debug.
Durante o desenvolvimento deparámo-nos com diversas situações em que
houve necessidade de fazer debug com recurso ao IDE, assim como pesquisa online
para esclarecimento de algumas dúvidas, entre elas, javadoc, implementação de alguns
objetos e testes, sendo que nesta última algumas ainda não foram totalmente
decifradas.
Como podemos verificar o diagrama UML inicial é bastante diferente do
diagrama final. Acreditamos que esta situação está diretamente ligada à pouca
experiência e que esta se deve ao facto de estarmos a inicializar um percurso na direção
da programação orientada a objetos. Cremos ainda que futuramente com a prática
frequente de programação orientada a objetos, a estrutura destes diagramas serão cada
vez mais semelhantes.
Ainda que a nossa interpretação do enunciado do trabalho prático tenha sido
feita de acordo com a descrição no capítulo Análise Inicial neste documento, e que o
programa desenvolvido atinga a solução pretendida, acreditamos que existirá uma
melhor forma para a solução do mesmo.
Achámos o conceito de generalização bastante interessante e bastante importante
neste conceito de programação orientada a objetos, no entanto cremos que é um
conceito que merece e necessita um período mais alargado de tempo para a sua total
compreensão. Ainda assim acreditamos de certa forma que conseguimos com sucesso
a aplicação deste conceito nas classes Shape, Circle e Square.

14
Tendo o TDD como requisito na elaboração da solução, tivemos em conta a
necessidade de criar testes para cada método e verificar a correta operabilidade dos
mesmos, antes de avançar com o desenvolvimento de outros. No entanto a alteração
constante da estrutura de desenvolvimento das classes e métodos e da
interdependência dos mesmos dificultou e atrasou bastante o desenvolvimento da
solução. Situações como a imagem abaixo, em que um teste do isInside() da classe
Square com AssertTrue ou AssertFalse davam erro, sendo que quando corríamos esse
mesmo comando na classe Client corria sem problemas.

Figura 5 - Situação do teste isInside() não funciona corretamente.

A geração do JavaDoc e a criação de comentários no código foram pontos


fulcrais no desenvolvimento, pois com a atribuição de tarefas a diferentes elementos do
grupo, permitiu um melhor entendimento do método operacional de cada função.
Concluímos que o JavaDoc é imprescindível para programas com alguma
dimensão, isto é, com diversas classes/objetos e diversos métodos. A sua consulta é
uma mais valia para a compreensão da operabilidade de todos os elementos de um
programa.
Aguardamos ansiosamente conhecer as diferentes análises feitas pelos outros
grupos, assim como as suas soluções.
Concluímos assim que conseguimos com sucesso atingir a maior parte dos
objetivos delineados na introdução a partir da solução por nós desenvolvida.

15
REFERÊNCIAS

[1 “Programação orientada a objetos – Wikipédia, a enciclopédia livre,” [Online].


] Available:
https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_objetos#cit
e_note-1. [Acedido em 13 Dezembro 2019].
[2 “Centroide – Wikipédia, a enciclopédia livre,” [Online]. Available:
] https://pt.wikipedia.org/wiki/Centroide. [Acedido em 14 Dezembro 2019].

16

Você também pode gostar