Trabalho Integrado das disciplinas de Programação Orientada a Objetos II, Banco de Dados II e Projeto de Sistemas
com os Professores Felipe Frechiani, Moisés Omena e Rodrigo Calhau em 2019/1
- Anne Caroline Silva: carolinesilva4@hotmail.com
- Ivana Amorim Julião: ivanaajuliao@gmail.com
- Jennifer Gonçalves do Amaral: jennifergamaral@gmail.com
- Mellyssa Stephanny de Jesus Mendes: mellyssah.mendes@gmail.com
A seguir apresentamos o Canvas de Aquecimento, com imagens individuais de cada integrante do grupo
O diário de bordo do grupo pode ser encontrado no seguinte link: diário
Nosso canvas de projeto é apresentação a seguir
O repositório do projeto pode ser acessado no GitHub através do seguinte link: repositório
A Canopus Tecnologia propõe um sistema chamado Delphos - Inteligência Emocional, um sistema que tem como objetivo guiar os usuários na jornada pelo autoconhecimento, autodesenvolvimento e plenitude emocional; Contribuindo assim para mitigar pensamentos danosos, controlar impulsos destrutivos dentre outras ações negativas, impedindo que esses transtornos venham a atrapalhar os usuários em sua vida. No primeiro contato, é necessário coletar algumas informações sobre o usuário. É necessário que ele informe nome, data de nascimento e e-mail. Posteriormente, o mesmo pode acrescentar mais informações ao cadastro. Em seguida, é necessário conhecer melhor o usuário. Assim, ele é submetido a um teste - Conhecido como Big 5, e o diagnóstico revelado pelo teste é exibido para o usuário e armazenado em um banco de dados. Nesse teste são realizadas cinquenta perguntas, divididas em cinco categorias: (i) extroversão, (ii) estabilidade emocional, (iii) afabilidade, (iv) consciência e (v) abertura para experiências. Na seguinte tabela, estão descritas as perguntas (que ainda não foram traduzidas) e sua respectiva sigla.
Extroversão | Estabilidade Emocional | Afabilidade | Consciência | Abertura para Experiências |
---|---|---|---|---|
EXT1 I am the life of the party. | EST1 I get stressed out easily. | AGR1 I feel little concern for others. | CSN1 I am always prepared. | OPN1 I have a rich vocabulary. |
EXT2 I don't talk a lot. | EST2 I am relaxed most of the time. | AGR2 I am interested in people. | CSN2 I leave my belongings around. | OPN2 I have difficulty understanding abstract ideas. |
EXT3 I feel comfortable around people. | EST3 I worry about things. | AGR3 I insult people. | CSN3 I pay attention to details. | OPN3 I have a vivid imagination. |
EXT4 I keep in the background. | EST4 I seldom feel blue. | AGR4 I sympathize with others' feelings. | CSN4 I make a mess of things. | OPN4 I am not interested in abstract ideas. |
EXT5 I start conversations. | I am easily disturbed. | AGR5 I am not interested in other people's problems. | CSN5 I get chores done right away. | OPN5 I have excellent ideas. |
EXT6 I have little to say. | EST6 I get upset easily. | AGR6 I have a soft heart. | CSN6 I often forget to put things back in their proper place. | OPN6 I do not have a good imagination. |
EXT7 I talk to a lot of different people at parties. | EST7 I change my mood a lot. | AGR7 I am not really interested in others. | CSN7 I like order. | OPN7 I am quick to understand things. |
EXT8 I don't like to draw attention to myself. | EST8 I have frequent mood swings. | AGR8 I take time out for others. | CSN8 I shirk my duties. | OPN8 I use difficult words. |
EXT9 I don't mind being thecenter of attention. | EST9 I get irritated easily. | AGR9 I feel others' emotions. | CSN9 I follow a schedule. | OPN9 I spend time reflecting on things. |
EXT10 I am quiet around strangers. | EST10 I often feel blue. | AGR10 I make people feel at ease. | CSN10 I am exacting in my work. | OPN10 I am full of ideas. |
O teste só poderá ser realizado novamente no mínimo seis meses após o anterior. Isso será importante para criar um histórico, permitindo assim, acompanhar a evolução do usuário. Em seguida deverá ser apresentado o resultado completo do teste. Contendo uma descrição sobre cada aspecto de sua personalidade e suas pontuações, pontos positivos e negativos. A partir do diagnóstico, o sistema se concentra no prognóstico, que é o que fazer a partir da obtenção dessas informações. Após determinar a qual categoria de personalidade (e suas qualidades e atributos) o usuário está classificado, o sistema tem suas funções calibradas para aquele tipo. O menu principal, apelidado de oráculo, é o local onde são exibidos os serviços oferecidos pelo aplicativo, a saber: resultados do teste de personalidade, os materiais explicativos recomendados ao usuário e o diário. Vale destacar que o sistema não substitui uma terapia. Ele funciona mais como uma ferramenta acessível a qualquer usuário que está em busca de formas para se autoconhecer e, por consequência, estimular a procura por algo mais eficaz no mundo real. Obviamente, um serviço digital não substitui o trabalho de um profissional da saúde. No entanto, a intenção é que este seja o primeiro passo rumo a um tratamento para problemas psicológicos com profissionais.
Tomando por base o contexto do sistema, foram identificados os seguintes requisitos de usuário:
Identificador | Descrição | Categoria | Escopo |
---|---|---|---|
RNF01 | O sistema deve cadastrar e autenticar usuários | Autenticação | Sistema |
RNF02 | O sistema deve autorizar o administrador a fazer alterações nos testes | Autorização | Funcionalidade |
RNF03 | O sistema deve permitir que o usuário modifique os próprios dados (exceto chave primária) | Modificabilidade | Funcionalidade |
RFN04 | O sistema deve efetuar o controle de itens recomendados, realizando criação, inserção, modificação e exclusão | Operacionalidade | Funcionalidade |
RFN05 | O sistema deve utilizar as notas do resultado do teste de personalidade para a recomendação de materiais | Reusabilidade | Sistema |
RFN06 | O sistema deve mostrar os resultados dos testes de forma clara e concisa em uma janela dedicada a isso | Inteligibilidade | Funcionalidade |
RFN07 | O sistema deve ser capaz de inferir uma classificação sobre a personalidade do usuário a partir das respostas dadas no teste | Analisabilidade | Funcionalidade |
RNF08 | Sistema deve ser acessado por plataforma web | Portabilidade | Sistema |
RNF09 | A persistência das informações deve ser implementada através de um banco de dados remoto | Manutenibilidade | Sistema |
RNF10 | O sistema deve armazenar todas as respostas e resultados do teste de personalidade em um histórico | Funcionalidade | Sistema |
RNF11 | O sistema deve possuir interface amigável e de fácil utilização | Usabilidade | Sistema |
RNF12 | O sistema deve ser confiável e com o mínimo de erros | Estabilidade | Sistema |
RNF13 | É necessário ser um usuário cadastrado para ter acesso às funcionalidades do sistema | Funcionalidade | Sistema |
RNF14 | O sistema deve manter um histórico dos testes realizados | Funcionalidade | Sistema |
Identificador | Descrição | Categoria | Escopo |
---|---|---|---|
RN01 | O cálculo do resultado do teste será realizado através da seguinte fórmula: (i) NotaExt = 20 + EXT1 - EXT2 + EXT3 - EXT4 + EXT5 - EXT6 + EXT7 - EXT8 + EXT9 - EXT10 (ii) NotaEst = 38 - EST1 + EST2 - EST3 + EST4 - EST5 - EST6 - EST7 - EST8 - EST9 - EST10 (iii) NotaAgr = 14 - AGR1 + AGR2 - AGR3 + AGR4 - AGR5 + AGR6 - AGR7 + AGR8 + AGR9 + AGR10 (iv) NotaCsn = 14 + CSN1 - CSN2 + CSN3 - CSN4 + CSN5 - CSN6 + CSN7 - CSN8 + CSN9 + CSN10 (v) NotaOpn = 8 + OPN1 - OPN2 + OPN3 - OPN4 + OPN5 + OPN6 + OPN7 + OPN8 + OPN9 + OPN10 | Cálculo | Sistema |
RN02 | O teste de personalidade só poderá ser realizado novamente com no mínimo seis meses após o anterior | Restrição | Funcionalidade |
RN03 | A nota de cada fator tem que estar entre zero e quarenta https://openpsychometrics.org/printable/big-five-personality-test.pdf | Restrição | Sistema |
RN04 | O restante dos recursos do sistema só serão liberados depois que o usuário realizar o primeiro teste de personalidade | Ativadores de Ação | Funcionalidade |
RN05 | O sistema deve restringir as respostas dos testes com valores pré-estabelecidos de 1 a 5 para impedir o usuário de responder com valores fora do escopo | Restrição | Sistema |
RN06 | O sistema deve efetuar o controle de itens recomendados, realizando criação, inserção, modificação e exclusão | Operacionalidade | Funcionalidade |
O diagrama de classes de análise da solução proposta é mostrado na seguinte imagem
A seguir, é mostrado o diagrama de classes de projeto
Um objeto do tipo Gabarito reúne informações acerca da data em que foi gerado, as respostas que foram dadas pelo usuário em questão e as perguntas que serão exibidas, percebe-se então que são construção não é tão simples e depende de outras classes. Para organizar melhor a ordem dessa construção foi utilizado o padrão de criação Builder.
Diagrama de classes - Recorte com implementação do padrão builder.
A estrutura desse padrão aplicada ao nosso projeto é a seguinte: a classe DiretorGabarito contém uma sequência de chamadas de métodos organizados em uma ordem específica para a construção do objeto Gabarito; a implementação desses métodos fica implementada na classe BuilderGabarito. Abaixo estão os trechos de código que exibem a implementação das mesmas.
public class DiretorGabarito {
public DiretorGabarito(){
}
public Gabarito builder(Usuario cliente, HashMap<String, String> perguntas, HashMap<String,Integer> respostas) throws Exception{
Gabarito testeP = new Gabarito();
BuilderGabarito builder = new BuilderGabarito(cliente,perguntas,respostas);
/*adicionar a sequência de tarefas*/
//verifica se o cliente é cadastrado ou não
builder.VerificaUsuario();
//preenche as respostas do cliente
builder.preencheRespostas(perguntas);
//testeP.setListaRespostas(respostas);
//registra data do teste
builder.registraData();
//Preenche o objeto teste com os dados retornados pelos métodos anteriores
return builder.montarTestePersonalidade(testeP);
}
}
public class BuilderGabarito{
private Usuario cliente;
private HashMap<String,Integer> respostas;
private HashMap<String,String> perguntas;
private Date dataHora;
public BuilderGabarito(Usuario cliente, HashMap<String, String> perguntas, HashMap<String,Integer> respostas){
this.cliente = cliente;
this.perguntas = perguntas;
this.respostas = respostas;
}
/*tarefas*/
public void preencheRespostas(HashMap<String, String> perguntas){
ControleTela tela = new ControleTela();
this.respostas = tela.realizaTeste(perguntas);/*armazena na variável declarada do builder*/
}
/*registra hora e data da realização do teste*/
public void registraData(){
Date date = new Date();
this.dataHora = date;
//DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
//this.dateFormat.format(date);
}
//adiciona todos os atributos preenchidos em teste e guarda os valores no banco
public Gabarito montarTestePersonalidade(Gabarito testeP)
testeP.setIdTeste(IdGeneratorSingleton.getInstance().getNextSerial());
testeP.setCliente(this.cliente);
testeP.setListaRespostas(this.respostas);
testeP.setDataHora(this.dataHora);
return testeP;
}
}
O Padrão Singleton tem como definição garantir que uma classe tenha apenas uma instância de si mesma e que forneça um ponto global de acesso a ela. Ou seja, uma classe gerencia a própria instância dela além de evitar que qualquer outra classe crie uma instância dela. Para criar a instancia tem-se que passar pela classe obrigatoriamente, nenhuma outra classe pode instanciar ela. O Padrão Singleton também oferece um ponto global de acesso a sua instância. A própria classe sempre vai oferecer a própria instância dela e caso não tenha ainda uma instância, então ela mesma cria e retorna essa nova instância criada.
Nosso trabalho implementa o singleton para criar instâncias únicas de id para o teste de personalidade no gabaritoBuilder. A figura a seguir é uma amostra do diagrama de classes onde o padrão está representado.
O padrão Flyweight cria uma estrutura de compartilhamento de objetos pequenos. É um padrão de projeto de software apropriado quando vários objetos devem ser manipulados em memória sendo que muitos deles possuem informações repetidas. Dado que o recurso de memória é limitado, é possível segregar a informação repetida em um objeto adicional que atenda as características de imutabilidade e comparabilidade (que consiga ser comparado com outro objeto para determinar se ambos carregam a mesma informação).
No projeto, utilizamos o peso mosca para criar as perguntas do teste de personalidade. Ao todo são 50 perguntas que são instanciadas apenas uma vez no processo. A figura a seguir é uma amostra do diagrama de classes onde o padrão está representado.
O Observer é um padrão de projeto de software que define uma dependência um-para-muitos entre objetos de modo que quando um objeto muda o estado, todos seus dependentes são notificados e atualizados automaticamente. Permite que objetos interessados sejam avisados da mudança de estado ou outros eventos ocorrendo num outro objeto.
No projeto, o objetivo era utilizar o observer para notificar o usuário. As notificações envolvem:
- Adição de Materiais Informativos;
- Prazo para fazer o teste (visto que o teste só pode ser feito a cada 6 meses, é enviado um lembrete quando o prazo estiver próximo. - Outro ponto é que pode ser massante para o usuário responder as 50 perguntas de uma só vez. Pensando nisso, o usuário tem a liberdade de nao concluir o teste, mas o sistema o notifica que ele tem um prazo para terminar de responder, se não será necessário refazer o teste);
- Lembretes diários das tarefas a serem realizadas, a fim de ficarem registradas no seu histórico de desempenho;
Para a parte do projeto que engloba a persistência dos dados optamos por utilizar o padrão Data Access Object (DAO), que encapsula os mecanismos de acesso a dados, fornecendo uma interface genérica com métodos de acesso que podem ser alterados, independentemente do código que utiliza os dados.
Diagrama de classes - Recorte com implementação do Padrão DAO.
Em nosso projeto a interface genérica corresponde a GenericDAO e as classes que implementam a mesma são representadas com a junção do nome da classe com o sufixo 'DAOimpl'. A seguir há dois trechos de código que representam a interface e uma das classes implementadoras da mesma, a UsuarioDAOImpl.
public interface GenericDAO<G> {
public List<G> getAll() throws SQLException, ClassNotFoundException;
public G getById(int id) throws SQLException, ClassNotFoundException;
public boolean insert(G obj) throws SQLException, ClassNotFoundException;
public void update(G obj) throws SQLException, ClassNotFoundException;
public void delete(G obj) throws SQLException, ClassNotFoundException;
}
public class UsuarioDAOImpl<G> extends Conector implements GenericDAO<G> {
private static final String SELECT = "SELECT * FROM usuario ";
private static final String SELECT_LOGIN = "SELECT * FROM cliente where email = ? and senha = ?;";
private static final String INSERT = "INSERT INTO usuario (id_usuario,nome,cpf,"
+ "email,senha,dataNascimento) VALUES(?,?,?,?,?,?);";
private static final String DELETE = "DELETE FROM cliente WHERE id_cliente = ?;";
private static final String UPDATE = "UPDATE usuario SET (nome,cpf,"
+ "email,senha,dataNascimento) = (?,?,?,?,?) WHERE id_usuario = ?;";
private static final String ID_USUARIO = "id_usuario";
private static final String NOME = "nome";
private static final String EMAIL = "email";
private static final String SENHA = "senha";
private static final String CPF = "cpf";
private static final String ORDER = "ORDER BY id_usuario ASC";
private static final String DATA = "dataNascimento";
@Override
public boolean insert(G obj) throws SQLException, ClassNotFoundException {
boolean stat = false;
try (Connection connection = this.openConnection();
PreparedStatement statement = connection.prepareStatement(INSERT);) {
statement.setInt(1, this.getNextId(SELECT + ORDER, ID_USUARIO));
statement.setString(2, ((Usuario) obj).getNome());
statement.setString(3, ((Usuario) obj).getCpf());
statement.setString(4, ((Usuario) obj).getEmail());
statement.setString(5, ((Usuario) obj).getSenha());
statement.setString(6,((Usuario) obj).getDataNascimento());
stat = statement.execute();
} finally {
this.closeConnection(con);
}
return stat;
}