Trabalho Prático #2 design técnico destina-se à equipa de desenvolvimento responsável pela...

46
Faculdade de Ciências e Tecnologia Engenharia de Software Desenho da Arquitectura em UML Autores: Bruna Nogueira 2010130465 José Marques 2011151227 Ricardo Mendes 2011154225 March 25, 2015

Transcript of Trabalho Prático #2 design técnico destina-se à equipa de desenvolvimento responsável pela...

Faculdade de Ciências e Tecnologia

Engenharia de Software

Desenho da Arquitectura em UML

Autores:

Bruna Nogueira 2010130465José Marques 2011151227

Ricardo Mendes 2011154225

March 25, 2015

ÍndiceIntrodução 1

Referências . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

Consolidação de Requisitos 2Descrição Geral do Produto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Funções do Produto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3Especificação de Requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Requisitos Funcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3Diagramas de Casos Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

Design Conceptual 7Design da interface do utilizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Descrição da arquitectura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19Análise comparativa da arquitectura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21Decisões sobre a arquitectura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

Design Técnico 24Arquitectura do Sistema Principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24Arquitectura do Módulo Ficheiros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25Descrição de cenários principais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26Design do Código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

Estruturas de Dados do Sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30Implementação dos Métodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32Organização do código-fonte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

Conclusão 44

Introdução

Esta segunda fase do projecto prende-se principalmente sobre a temática do desenho da Arquitetura em UML.Assim sendo, o conteúdo do documento divide-se em três secções principais: Consolidação de Requisitos, DesignConceptual e Design Técnico.

A consolidação de requisitos foi produto da reunião da equipa de desenvolvimento com o cliente, após a apre-sentação do documento desenvolvido na primeira etapa do projecto - System Requirements Specification (SRS).Assim, na primeira fase deste documento, aprensentam-se as alterações que foram feitas de modo a poder-se iniciara segunda fase. As alterações mais relevantes serão aqui identificadas, e o SRS actualizado seguirá em anexo.

Os designs conceptual e técnico descrevem uma solução particular para o problema definido pelos requisitos.

O primeiro é direccionado principalmente para o cliente. O seu objectivo fulcral é dar a entender como o sistemaimplementado funciona. Desta maneira, são conceptualmente definidas a organização das estruturas de dados, acomunicação entre elas e a interactividade do utilizador com estas. Por fim, é apresentada uma análise comparativaentre a solução tomada e possíveis soluções alternativas, justificando as opções de implementação.

O design técnico destina-se à equipa de desenvolvimento responsável pela programação e tem como objectivodescrever minunciosamente o funcionamento do sistema. Isto implica uma projecção técnica sobre a solução aimplementar que se prende na descrição da implementação, dos tipos e estruturas de dados, métodos e algoritmosutilizados. Descreve ainda a organização dos ficheiros utilizados e das inter-dependências de todos os componentesconstituintes do sistema.

Sendo o Graphical user interface (GUI) um componente fulcral do software em desenvolvimento, vai ser abordadocom detalhe, tanto a nível de design conceptual como de design técnico, sendo que no primeiro terá uma abordagemmais funcional e visual, e no segundo serão exploradas com mais detalhe as suas implementação e estruturação.

Referências

• [1] S. L. Pfleeger and J. M. Atlee, Software Engineering: Theory and Practice, 4rd edition, Pear-son Interna-tional Edition, Pearson Prentice Hall, lSBN-10: 0.13-606169-9, ISBN-13: 978-0-13-606169-4

• [2] QT Documentation.http://doc.qt.io/[Conferido em: 24 de Março de 2015

]• [3] QT Documentation Snapshots.

http://doc-snapshots.qt.io/[Conferido em: 24 de Março de 2015

]

1

Consolidação de Requisitos

Esta secção visa esclarecer e completar conceitos do documento de SRS que, após reunião e discussão com o cliente,se provaram insuficientes para uma percepção inequívoca dos conteúdos. Assim, são destacados alguns pontosessenciais devidamente corrigidos, para clarificação desses conceitos, seguindo a sequência do referido documento.Nesta secção são apenas destacadas as alterações com mais relevância. Para consulta de todas as actualizações deveser lido o documento de SRS actualizado na íntegra, entregue juntamente com este documento.

2

Descrição Geral do Produto

No âmbito da Descrição Geral do Produto, são seguidamente enumeradas as funções definitivas do produto.

Funções do Produto

Esta aplicação destina-se ao agregado familiar, sendo, como já foi referido, usado por um único utilizador decada agregado. Tratando-se de um programa que visa a ajuda na gestão financeira da família de forma intuitiva, énecessário que este contenha as seguintes funcionalidades:

• Registar o lançamento de crédito;

• Registar o lançamento de débito;

• Alteração ou eliminação de movimentos;

• Gestão do agregado familiar;

• Consulta de balanço;

• Edição das tipologias;

• Exportação dos dados;

Especificação de Requisitos

Dentro desta secção procede-se a uma redefinição do sistema qualitativo de atribuição de prioridades, bem como dealguns diagramas de casos de uso.

Requisitos Funcionais

Para a definição das prioridades nos requisitos funcionais, fizemos uma junção entre dois sistemas. O primeiro éum sistema númerico, onde o 1 indica prioridade máxima e o 5 prioridade mínima. Sendo que todos os requisitossão essenciais, o segundo sistema é um classificador temporal. Assim, distinguimos 3 classes diferentes de acordocom a urgência de implementação:

• Máxima prioridade: Algo que tem de ser implementado numa fase inicial (Prioridades 1 e 2);

• Média Prioridade: Algo que deve ser implementado após o correcto funcionamento dos classificados commáxima prioridade (Prioridades 3 e 4);

• Baixa prioridade: A implementar na fase final do trabalho. (Prioridade 5);

Os requisitos que consideramos de maior urgência, de prioridade máxima, são aqueles sem os quais o programanão consegue funcionar correctamente, e é fácil entender a razão. Sendo que se trata de uma aplicação para ajudaruma família a gerir o seu dinheiro, é imperativo que se monitorize o saldo, algo que é impossível sem lançar créditosou débitos, movimentos estes que precisam de ser associados a um membro do agregado. Por fim, é necessáriovisualizar, no mínimo, um resultado final com os totais dos movimentos (balanço resumido).

3

Requisitos que são também essenciais, mas um pouco menos prioritários que os anteriores são por exemploregularidade de movimentos e o lançamento automático de movimentos regulares. Têm a mesma prioridade porquenão fariam sentido um sem o outro. Em termos de gerir informação, dá-se prioridade a apagar membros e movimentosa corrigi-los, uma vez que apagar e voltar a lançar pode substituir o corrigir o movimento ou membro, numa etapainicial.

O único requisito classificado com baixa prioridade é a salvaguarda de ficheiros, caso o utilizador deseje exportardados, pois não é algo que influencie verdadeiramente o funcionamento do programa, sendo que é dada então amenor prioridade.

Aos restantes requisitos é dada prioridade média, porque são funções que o programa deve realizar para ummelhor funcionamento, mas sem as quais este consegue cumprir o propósito primário para o qual foi criado.

Diagramas de Casos de Uso

Nesta secção podem ser encontradas versões actualizadas dos diagramas de casos de uso que se revelaramincompletos numa primeira fase. No campo Alterações estão destacadas as alterações efectuadas no diagrama.

Sistema.Consultar Informação

Fig. 1: Diagrama de casos de uso relativo à consulta de informação no sistema

Actores: Utilizador

Alterações: Em adição ao diagrama homónimo do documento de especificação de requisitos, no contexto daconsulta de um balanço insere-se a acção de calcular balanços.

4

Sistema.Editar Informação.Lançar Movimento

Fig. 2: Diagrama de casos de uso relativo ao lançamento de um movimento.

Actores: Utilizador

Alterações: Os casos de uso relativos aos lançamentos de créditos ou de débitos encontram-se agora con-jugados num só diagrama de caso de uso que de forma genérica descreve as acções possíveis no âmbito dequalquer tipo de movimento. A selecção entre lançamento de um débito ou de um crédito insere-se no casode uso Definir Tipo de Movimento.

Observações: A definição de Regularidade de um movimento, sendo ele de crédito ou débito, apenas permiteao utilizador definir se o período é regular ou não. No caso afirmativo, a regularidade do movimento é mensal,como referido na subsecção Acrónimos, Abreviações e Definições do documento de especificação de requisitos.

5

Sistema.Editar Informação.Alterar Informação de Membro do Agregado

Fig. 3: Diagrama de casos de uso relativo à alteração de informação respeitante a um membro do agregado.

Actores: Utilizador

Alterações: A especificação de data de óbito passa a tomar um sentido mais genérico - data de inactivação,que especifica a data em que o membro deixa de participar - deixa de ser activo - nas finanças do agregadofamiliar.

Observações: A definição de fontes de rendimento toma o sentido explicado no diagrama relativo à adiçãode um membro ao agregado familiar. Na situação de inactivação de um membro o utilizador pode especificá-lo– definindo-o como activo ou inactivo - e indicar a data de inactivação. Nesse caso, não serão admitidosmovimentos no nome desse membro do agregado. Quando é adicionado um membro, é assumido como activo,por omissão.

6

Design Conceptual

Para um dado problema de design de software existem infinitas soluções possíveis. Sendo que o SRS define umproblema deste género, cabe à equipa projectar uma solução possível. Deste modo, o design conceptual descrevepormenorizadamente a solução a um nível conceptual, de maneira a que sejam claras as funcionalidades querespondem aos requisitos do SRS. Cabe também à equipa de desenvolvimento fazer uma análise comparativa dasopções que teve em conta e concluir o porquê da solução final. Esta análise consta também nesta secção.

Primeiramente, é abordado o design conceptual respeitante à interface do utilizador, onde são abordadas as suasfuncionalidades,sendo a explicação completada com imagens do protótipo desenvolvido até à data. Seguidamente,é apresentada uma descrição conceptual da arquitectura lógica do sistema global, englobando todos os módulosfuncionais intervenientes.

Design da interface do utilizador

Fig. 4: Aba inicial.

Quando o utilizador inicializa o programa, é esta a aba inicial. Aqui o utilizador pode encontrar os dados maisrelevantes sobre a economia da família, como os movimentos mais recentes, alguns movimentos futuros e o saldoactual. Uma vez que se trata de um programa que ajuda uma família a gerir o seu estado financeiro, decidimos que

7

na lista de "Movimentos Futuros", quando exista algum débito que coloque o saldo negativo, esses movimentos vãoestar assinalados a vermelho.

Estando na aba inicial, é possível a movimentação para outras abas que representam pontos fulcrais do programa,como Movimentos (Fig 5), Agregado (Fig 6) e Tipologias (Fig 7), quer através do clique do rato nas respectivasabas, quer através de duas combinações de teclas de atalho:

• Alt + ← : Movimentação para a aba à esquerda da actual. Caso esteja na primeira, vai para a última;

• Alt + → : Movimentação para a aba à direita da actual. Caso esteja na última, passa para a primeira;

Aqui é também possível aceder ao menu de ajuda, que abre uma nova janela (Fig something) e fechar o programa.

Se tivermos em conta a lista de requisitos funcionais presentes no relatório da Etapa 1 deste projecto, esta abacumpre os seguintes:

• Monitorizar saldo (ID 2);

• Calcular e apresentar balanço resumido (ID 9);

Fig. 5: Aba de movimentos.

8

Nesta aba, o utilizador pode seleccionar uma data de início e outra de fim, sendo que o programa exibe todos osmovimentos feitos entre essas datas. Se o utilizador apenas quiser movimentos de certas tipologias, ou que tenhamsido feitos por certos membros, então pode usar os filtros que se encontram na metade inferior esquerda da janela.Lá irão estar 2 listas onde é possível escolher os membros ou tipologias a filtrar. As checkboxes Membros 1 e 2e Tipologias 1 a 3 são meramente indicativas de como irão ser apresentadas as listas. De referir também que aoseleccionar qualquer uma das datas, aparece um calendário, para uma minimização do uso do teclado.

Para além disso, o utilizador pode carregar num de 5 botões, que permite desempenhar diversas funções:

• Adicionar Movimento - (Fig 8);

• Editar Movimento - (Fig 9);

• Apagar Movimento - (Fig 10);

• Calcular Balanço - Ao premir este botão, o utilizador actualiza a lista de movimentos em função dos filtrose das datas introduzidas;

• Exportar Dados - Permite ao utilizador exportar os movimentos em função dos filtros usados. De notar,no entanto, que é necessário Calcular Balanço para os dados exportados serem os mais actualizados;

Aqui, é possível completar os seguintes requisitos funcionais:

• Calcular e apresentar balanço detalhado (ID 10);

• Agregação de movimentos (ID 11);

• Apresentar balanço consolidado (ID 12);

• Exportar dados (ID 13);

Quando o utilizador decide explorar a aba Agregado, é confrontado com algo igual à Fig 6. Aqui é possívelescolher um membro que esteja presenta na lista e ver:

• Imagem;

• Nome;

• Data de Nascimento;

• Fonte de Rendimento - Diz se o membro em questão possui fontes de rendimento ou não. No caso afirmativo,mostra também o montante;

• Estado - Mostra se o membro está activo ou inactivo. No último caso, mostra também a data de desactivação;

Para além disso, a aba também permite aceder, usando os botões existentes, aos seguintes menus:

• Adicionar Membro - (Fig 11);

• Editar Membro - (Fig 12);

9

Fig. 6: Aba do agregado familiar.

Por fim, o utilizador pode aceder a mais uma aba na janela principal do programa: Tipologias. Aqui o utilizadortem duas listas: Tipologias de Créditos e Tipologias de Débitos. Escolhendo uma tipologia à sua escolha, o utilizadorpode ver a descrição associada. A aba permite a visualização de duas tipologias simultaneamente, uma de cadatipo.

Analogamente às abas referidas anteriormente, aqui também é possível aceder a menus usando botões:

• Adicionar Tipologia - (Fig 13);

• Editar Tipologia - (Fig 14);

Todas estas abas fazem parte da janela principal, e têm 3 aspectos em comum:

• Movimentação entre abas;

• Saldo total do agregado;

• Botão de ajuda - (Fig 15);

10

Fig. 7: Aba de tipologias.

11

Fig. 8: Janela para adicionar um novo movimento.

Quando o utilizador decide introduzir um novo movimento, é aberta o seguinte menu, quer carregando no botãoque se encontra na aba "Movimentos" (Fig 5), ou usando as teclas de atalho: Alt + C. Aqui, é necessário quesejam introduzidos os campos associados a um movimento:

• Montante;

• Regularidade;

• Tipo de movimento;

• Membros associados ao movimento;

• Tipologia;

No que diz respeito ao tipo de movimento, o utilizador pode escolher "Crédito" ou "Débito", sendo que as duassão mutuamente exclusivas. Qualquer umas das escolhas influencia a lista de tipologias disponíveis.

No caso do utilizador, ao lançar um movimento, sentir necessidade de adicionar um novo membro ou tipologia,pode fazê-lo, utilizando os botões presentes no canto inferior direito, que levam o utilizador aos menus presentesem Fig 11 e Fig 13.

Fazendo a correspondência com os requisitos funcionais, com este menu conseguimos completar os seguintes:

• Lançamento de Crédito (ID 3);

• Lançamento de Débito (ID 4);

• Regularidade de movimentos (ID 5);

12

Fig. 9: Janela para editar um movimento.

Caso o utilizador deseje editar um movimento já existente, a janela é em tudo semelhante à janela para adicionarum movimento. A diferença irá ser detectada numa versão funcional do programa, pois por defeito irão aparecer ascaracterísticas do movimento a alterar.

Com a possibilidade de editar movimentos, cumpre-se o seguinte requisito funcional:

• Corrigir movimentos (ID 15)

Fig. 10: Janela de aviso quando se tentar apagar um movimento.

13

Se a opção escolhida pelo utilizador for apagar um movimento, é criada uma janela que pergunta ao utilizador sedeseja apagar o movimento, sendo que o utilizador apenas pode confirmar ou cancelar a acção.

Com essa confirmação, cumpre-se o seguinte requisito funcional:• Apagar movimentos (ID 16);

Fig. 11: Janela para adicionar um novo membro.

Para criar um novo membro, o utilizador pode utilizar os botões que se encontram presentes na aba "Agregado"(Fig 6), na janela de introdução de um novo movimento (Fig 8) e na janela de edição de um movimento (Fig 9).Pode também usar a combinação de teclas Alt + M. Estando nesta janela, o utilizador deve introduzir:

• Nome;

• Data de nascimento;

• Se possui ou não rendimentos;

• Salário;

• Data de depósito;

• Imagem;

O utilizador pode seleccionar uma checkbox para o caso de ter fontes de rendimento. No caso negativo, desactiva-sea introdução do salário e data de depósito.

Ao possibilitar a introdução de um novo membro, completa-se o seguinte requisito funcional:• Adicionar membros (ID 8);

14

Fig. 12: Janela para editar um membro existente.

Para o caso do utilizador querer apenas editar informação de um membro, a janela é usada da mesma forma quena Fig 11, com a diferença que inicialmente, os campos estarão preenchidos com a informação actual do membro.No caso de querer apagar um membro, é necessária a introdução da data de desactivação. De notas que "EditarInformação" e "Apagar Membro" são acções mutuamente exclusivas, e a escolha de uma delas desactiva os camposda outra escolha.

Tendos estas duas escolhas, cumprem-se os seguintes requisitos:

• Editar Membro do Agregado (ID 17);

• Apagar Membro do Agregado (ID 18);

15

Fig. 13: Janela para adicionar uma nova tipologia.

O utilizador pode aceder a esta janela de duas formas: através de um clique num botão (presente na aba"Tipologias" (Fig 7), na janela de introdução de um novo movimento (Fig 8) ou de edição de um movimento (Fig9)), ou usando a combinação Alt + T. Para criar a tipologia é necessário preencher os seguintes campos:

• Designação;

• Tipo de movimento;

• Descrição;

Com esta janela, completa-se o seguinte requisito funcional:

• Adicionar Tipologias (ID 7);

16

Fig. 14: Janela para editar tipologia.

Se o utilizador quiser editar uma tipologia, irá usar uma janela igual à de criação de uma tipologia, com adiferença que a primeira irá ter os campos preenchidos por defeito com a informação da tipologia a editar.

Um aspecto a notar é que as janelas de criação e edição de informação (Fig 8 até Fig 14) possuem dois botões:

• Confirmar;

• Cancelar;

O resultado de carregar em qualquer um dos botões nessas janelas é o mesmo em termos de interface gráfica:a janela é fechada. A diferença irá ser notada numa fase futura do projecto, onde carregando em "Confirmar", ainformação é guardada, enquanto que "Cancelar" irá descartar por completo a informação introduzida nos camposrespectivos.

17

Fig. 15: Janela de ajuda.

Caso o utilizador necessite de ajuda pode carregar no botão presente no fundo da janela principal, ou usando acombinação de atalho Alt + H e é direccionado para esta janela, onde consoante a dúvida que tem, escolhe a aaba indicada para a dúvida, que contém um texto informativo sobre como proceder para o bom funcionamento doprograma.

De referir que todas as janelas que são abertas tomam precedência sobre as janelas que as abrem, sendo queé necessário confirmar ou cancelar para poder regressar à janela original. Por exemplo, ao adicionar um novomovimento, a janela da Fig 8 toma precedência sobre a janela principal, e só é possível regressar a esta fechando ajanela de novo movimento. No entanto, se decidirmos adicionar um novo membro ou uma nova tipologia enquantoadicionamos um movimento, estas tomam precedência, sendo necessário fechá-las ou confirmar qualquer acção.

18

Descrição da arquitectura

A arquitectura do sistema foi desenhada tendo em conta os requisitos previstos e consolidados. O objectivoprincipal aquando do projecto da arquitectura foi apresentar um sistema que, respondendo a todas as funcionali-dades impostas pelo cliente, seguisse uma implementação eficiente, investindo na minimização da redundância deinformação e das dependências entre os seus componentes.

A arquitectura lógica do sistema pode ser descrita em diferentes níveis de abstracção:Uma primeira abordagem descreve a arquitectura do sistema no nível de mais alta abstracção. Neste contexto,

o sistema é decomposto em três módulos funcionais fundamentais: GUI, Sistema Principal e Ficheiros.Seguidamente, é explorada com maior detalhe a arquitectura intrínseca ao módulo Sistema Principal.

Nível de Abstracção 1

Uma representação ilustrativa da arquitectura lógica do sistema e principais dependências inter-módulos, quandodescrita num nível de elevada abstracção, pode ser encontrada do diagrama de pacotes UML da figura 16.

Fig. 16: Representação da arquitectura do sistema no nível de abstracção mais elevado.

Como já foi referido, o sistema pode ser decomposto em três módulos funcionais fundamentais:

• Ficheiros: Módulo responsável pela gestão do conjunto de ficheiros armazenados em disco. Estes ficheirosserão utilizados pelo Sistema Principal para leitura e escrita, de modo a manter a informação guardada deforma permanente e consistente; também serão utilizados para exportação de balanços sempre que o utilizadordesejar.

• GUI: Componente responsável pela interacção do Utilizador com o Sistema Principal. Permite consultare modificar informação contida no Sistema Principal.

• Sistema Principal: Componente que contém as funcionalidades de resposta aos requisitos funcionais, bemcomo toda a informação, em memória temporária, referente às classes e estruturas de dados utilizadas.

Para além dos módulos, ou pacotes, o diagrama apresenta também as respectivas dependências entre eles. De notarque apenas estão marcadas as dependências na direcção em que têm mais força. Contudo, existem dependênciasnas duas direcções:

Sistema Principal - Ficheiros:

• O módulo Ficheiros é dependente do Sistema Principal, na medida em que é responsável pelo armazena-mento toda a informação do sistema nos ficheiros devidos. Os ficheiros do sistema têm de ser actualizadossempre que uma alteração de informação no Sistema Principal implique perda de consistência de dadosarmazenados em disco, para assegurar um certo grau de fiabilidade.

19

• Não obstante, o Sistema Principal é extremamente dependente dos ficheiros, uma vez que este lê dosficheiros a informação necessária à inicialização da aplicação. Sem a informação de Ficheiros, o sistemaglobal não pode funcionar.

Tal como indicado no diagrama de pacotes, o Sistema Principal está mais fortemente dependente do módulode Ficheiros do que o recíproco.

Sistema Principal - GUI: A mesma análise pode ser feita para a interacção do Sistema Principal com oGUI:

• Quando o utilizador está a consultar informações, a informação apresentada é obtida do Sistema Principal.Além do propósito primário do display de informação relativa ao Sistema Principal, o GUI tambémresponde a mensagens de controlo (como por exemplo recebendo indicativos de erros da parte SistemaPrincipal).

• No entanto, quando o utilizador efectiva uma modificação de algum valor no GUI, esta informação invocaráacções por parte do Sistema Principal e comunicar-lhe-á informação a actualizar.

Nesta interacção, o GUI está mais fortemente dependente do módulo Sistema Principal do que o recíproco.

Nível de Abstracção 2

Este ponto pretende detalhar a arquitectura lógica intrínseca ao módulo Sistema Principal referenciado noponto anterior. A figura 17 ilustra a solução implementada, identificando os módulos fundamentais constituintesdo sistema assim como principais dependências entre estes.

Fig. 17: Diagrama de pacotes do Sistema Principal

Os módulos representados modelam as entidades fundamentais do sistema e acções que estas devem assegurar,concretamente: Movimento, Balanço, Membro e Tipologia. Devem salientar-se as principais dependênciasinter-modulares:

Membros-Movimentos: Cada movimento contém referências a membros a que está associado.

20

Movimentos - Balanços: Um elemento da classe Balanço contém uma lista de referências a movimentos efectu-ados no período compreendido entre as datas de início e fim do balanço. Assim, a alteração de um campo de ummovimento (data, montante, regularidade, eliminação e adição) implica na maior parte das vezes a necessidade deactualização de balanços consolidados.

Movimentos - Tipologias: Um objecto da classe Movimento contém uma referência a um objecto da classe deTipologias.

Análise comparativa de arquitecturas

Conjugando a informação do ponto anterior, segue-se uma análise e justificação das opções tomadas e comparaçãocom possíveis alternativas. Contudo em primeiro lugar é fundamental fazer algumas observações: Analisandoa perspectiva de maior abstracção, dada a natureza dos propósitos básicos do GUI e de Ficheiros, existe umconjunto de dependências inevitáveis, que existem independentemente da solução implementada. Concretamente,por exemplo, dependências que se inserem no contexto de control coupling, medida em que eventos do GUI invocamrespostas por parte do Sistema Principal. Descendo no nível de abstracção, as quatro entidades fundamentais doSistema Principal apresentam dependências também elas incontornáveis, dada a necessidade do seu relacionamentopara o funcionamento global do sistema. Assim, a decomposição do sistema em módulos não permitiu eliminaras dependências, mas localizá-las, dividindo o problema gestão das mesmas também em módulos. Tendo sobconsideração estas observações, a solução implementada visa a eficiência e optimização da gestão das dependênciasentre os diferentes módulos, minimizando a circulação de informação redundante, reduzindo o acoplamento aoestritamente necessário e promovendo a coesão dos componentes do sistema.

Gestão de dependências:

Este ponto pretende explorar a arquitectura do Sistema Principal sob uma perspectiva de gestão dependências,determinante nos níveis de acoplamento da solução implementada. Por outras palavras, aborda a gestão deinformação comum a vários componentes e a forma como se garante a coerência desta.

No que respeita ao Sistema Principal, como já foi referido, identificam-se vários casos em que um componentecontém referências a outro componente. A utilização de referências visa a eficiência na actualização de informaçãoalterada. Desta forma, cada alteração de dados de um módulo é feita uma única vez, exclusivamente editável poresse mesmo módulo, ficando instantaneamente actualizada para uma próxima leitura por parte de outro componente.Para o assegurar, os atributos do módulo são privados e lidos através de métodos constantes que permitem obterinformação acerca destes, não susceptível a alterações. Desta forma alcança-se um nível de acoplamento reduzidodentro das restrições impostas, no campo do Data Coupling;

Esta solução opõe-se a outras soluções possíveis, com base, por exemplo, na passagem de cópias de informaçãoaos componentes necessários, aumentando a redundância de informação e o tempo de actualização dos dados. Aabordagem seleccionada reduz esta redundância e permite coerência imediatamente. Uma outra possibilidadeseria gerir a comunicação de informação por memória partilhada, que implicaria implementação de mecanismosadicionais no sentido de assegurar exclusividade mútua no acesso a esta e transportaria o acoplamento para grausmais elevados, no nível do content coupling / common coupling. A abordagem seleccionada evita este tipo desituações, assegurando ainda um nível reduzido de acoplamento.

No que toca a coesão, os módulos contêm os atributos e métodos estritamente necessários à modelação daentidade pretendida e da sua interacção com os restantes módulos do sistema. Dessa forma, os módulos apresentam

21

elevada coesão, no domínio funcional. Contudo, deve notar-se que a opção tomada pela equipa no que respeita aarmazenamento de informação, analisada de seguida, tem uma influência negativa na coesão dos módulos.

Gestão de Ficheiros :

Na abordagem ao problema da gestão de entrada e saída e de armazenamento em disco foram tidas sob consider-ação três alternativas principais:

• Implementação de uma base de dados: O uso de uma base de dados requeriria uma conecção à internet,o que não foi definido no SRS e que poderia, também, limitar o uso do programa. Esta hipótese foi descartada,também, devido à inexperiência da equipa nesta área , que poderia comprometer a qualidade do produto e ocumprimento das metas temporais estabelecidas.

• Armazenamento em ficheiros: A abordagem escolhida para gerir o armazenamento permanente de informaçãoinsere-se nesta categoria. Nesta, destacam-se duas alternativas principais:

Leitura e escrita intrínseca a cada módulo: Nesta abordagem, cada módulo seria responsável pela gestãodo ficheiro que lhe diz respeito Esta alternativa não afecta a coesão ou acoplamento no sistema, mas dificulta aevolução/mudança de métodos utilizados para armazenamento de informação

Implementação de um módulo isolado responsável pela gestão de armazenamento de informação. Estaopção oferece a vantagem de isolar a operação de entrada e saída, facilitando a evolução e alteração dos mecanismosde entrada e saída sem ter a necessidade de alterar outros módulos. Por outro lado, introduz maior acoplamentono sistema ( todos os restantes módulos invocam acções deste), e diminui a coesão dos módulos quando comparadacom a alternativa anterior.

Para dar alguma flexibilidade à evolução de métodos de entrada e saída, possibilitando a reutilização dosrestantes módulos sem necessidade de modificar o código, a equipa optou pela última abordagem. Mais detalhesacerca dos ficheiros utilizados pelo sistema podem ser encontrados no ponto seguinte, bem como na subsecçãoDesign do código.

Gestão de informação global do sistema:

Para organização e armazenamento da informação no sistema em run-time, são mantidas listas ligadas globais(listas de Membros, Movimentos, Balanços Consolidados, Tipologias, Movimentos Regulares, etc.), estruturadas deforma a tornar a navegação e pesquisa de informação do sistema mais rápida e organizada. A equipa optou poruma forma de armazenamento dinâmica, dada a incerteza nas quantidades de informação a armazenar. Os detalhestécnicos da implementação podem ser encontrados na secção Design Técnico.

Outras decisões sobre a arquitectura

A equipa de desenvolvimento, face aos requisitos definidos, enveredou pelas seguintes soluções:

• Linguagem de programação:

22

Foram dadas como opção para desenvolvimento do software as linguagens de programação Java e C++. Aequipa de desenvolvimento enveredou pelo C++, visto que todos os membros serem mais proficientes nestalinguagem. De outro modo, seria necessário dedicar mais tempo à pesquisa e estudo do sintaxe do Java, oque poderia levar a atrasos indesejados.

• Ambiente de desenvolvimento:

Foi escolhido o software Qt como ambiente de desenvolvimento pelas seguintes razões:

– Possibilidade de desenvolvimento entre diferentes sistemas operativos.– Open Source - Esta característica é bastante valiosa para a equipa. Ao aumentar o conhecimento sobre

este software, o seu uso em futuros projectos será facilitado e há ainda a possibilidade de os publicar semcustos adicionais.

• Método de gravação de informação no disco:

Dois tipos de ficheiros serão armazenados:

– Ficheiros que guardam as informações referentes ao programa em si, ou seja, os movimentos, os balanços,os membros do agregado familiar e as tipologias. Estes ficheiros serão apenas alterados pelo sistemaaquando qualquer alteração ou adição de informação por parte do utilizador no GUI. Assim sendo, estesficheiros serão guardados em binário, para os proteger de alteração por parte do utilizador.

– Exportações de balanços executadas pelo utilizador. Serão guardados em formato CSV, para uma fácilleitura e análise por parte do utilizador.

Uma vez que ambos os tipos de ficheiros guardados serão utilizados e consultados pelo mesmo utilizador - ousistema num mesmo computador - serão guardados no disco rígido do computador. Assim, garantimos umrápido e constante acesso às informações.

23

Design TécnicoSeguindo os níveis de abstracção definidos no design conceptual, esta secção pretende descrever detalhadamente

a vertente técnica da implementação do projecto. Para os módulos intervenientes na descrição da arquitecturado sistema, representada na figura 16, são especificadas as estruturas de dados a utilizar e o seu modo de inter-relacionamento, procedendo-se posteriormente a uma explicação detalhada dos métodos a implementar.

Arquitectura do Sistema Principal

Este ponto tem como objectivo detalhar, do ponto de vista técnico, a arquitectura conceptualmente descrita nocontexto do Design Conceptual. A modelação das entidades constituintes do módulo Sistema Principal, definidaspreviamente na abordagem conceptual de menor abstracção, tem por base os atributos e métodos patentes nodiagrama de classes UML da figura 18.

Fig. 18: Diagrama de Classes do Sistema

Convém referir alguns pormenores respeitantes à implementação das classes:

24

• Os atributos de cada classe são privados, sendo apenas acessíveis para leitura por métodos constantes externosà classe - estes métodos estão referidos no diagrama de classes como getX(), onde X diz respeito ao atributoa ser lido.

Particularmente para cada classe, chama-se a atenção para as seguintes observações:

Classe CMembro:

• Não é permitido ao utilizador criar um membro à partida inactivo, pelo que todos os construtores desta classe colocamo atributo booleano activo a true.

• O método ApagarMembro() não apaga o objecto em questão, coloca-o apenas inactivo - activo = false. Isto permite quemovimentos passados possam ainda referenciar este elemento, mas que movimentos novos já não possam.

Classe CBalanco:

• A variável booleana consolidado é utilizada para o controlo de desalocação de balanços. Ver subsecção Implementaçãodos Métodos para detalhes.

• O método EConsolidado() retorna o valor da booleana acima referida, isto é, tendo em contas as datas de início e fimde um balanço, especifica se trata de um balanço consolidado ou não.

Classe CMovimento:

• O long int id será utilizado na inicialização do programa para auxiliar a descobrir quais os movimentos referenciadospor um balanço consolidado.

• O static long int proxID contém o valor do próximo id a atribuir na criação de um novo movimento. Este valor éincrementado sempre que se cria um novo movimento.

É de notar que apenas os movimentos precisam deste identificador, uma vez que para objectos das classes CMembro eCTipologia se podem distinguir pelo nome e designação, respectivamente.

Arquitectura do Módulo Ficheiros

O módulo Ficheiros, além de englobar os ficheiros de armazenamento de informação propriamente ditos, também abrangeas funções de gestão de leitura e escrita para estes ficheiros. Na classe CGestãoFicheiros concentram-se os atributos e métodosnecessários a esta gestão, , especificados na figura 19. Esta classe é responsável por todas as transacções do sistema principalcom os ficheiros, sejam eles em formato binário ou de texto. Permite então a leitura e escrita de todas as adições ou ediçõesde informação para/do disco rígido.

25

Fig. 19: Diagrama referente à classe CGestaoFicheiros

Descrição de cenários principaisEsta secção visa ilustrar o comportamento do software em alguns cenários relevantes, definidos no documento de especificação

de requisitos como casos de uso. Assim, pretende-se dar continuidade à exploração da vertente técnica do projecto com maiordetalhe, descendo no nível de abstracção. Para completar esta descrição são utilizados diagramas de sequência UML, quepossibilitam a compreensão da interacção inter-classes e a observação, numa perspectiva temporal , do desenrolar da acção.

Aquando da visualização dos diagramas seguintes, deve ter-se em conta que algumas setas apresentam uma pequenainclinação. No entanto, a inclinação deverá ser desprezada. Não existe uma comunicação entre objectos que demore umintervalo de tempo considerável. Esta situação deveu-se a problemas na utilização da ferramenta de edição dos diagramas; denotar também que os diagramas são auto-explicativos na maioria dos casos, sendo sempre que necessário destacadas observaçõespara clarificar situações menos evidentes. Sendo assim, apresentam-se em baixo alguns diagramas de sequência relativos aoscasos de uso de maior prioridade:

Adicionar um membro ao agregado familiar:

Fig. 20: Diagrama de sequência relativo ao caso de uso "Adicionar Membro" ao agregado familiar.

Adicionar uma nova tipologia ao sistema:

26

Fig. 21: Diagrama de sequência relativo ao caso de uso "Adicionar Tipologias"

Observações: Note-se que existem duas listas para tipologias. A lista representada no diagrama 21 por tipoCredList éuma lista que contém todos os objectos da classe tipologia com a categoria crédito e tipoDebList contém todas as tipologiasdo tipo débito.

Calcular Balanço:

Seguidamente apresenta-se o diagrama de sequências relativo à implementação da funcionalidade de calcular um balanço;no entanto, há que ter em conta que este diagrama foi desenhado a um nível de abstracção elevado. Existem alguns pormenoresque aqui não foram representados pois dificultariam a percepção do diagrama. Para mais detalhes, consultar a subsecçãoImplementação dos Métodos.

27

Fig. 22: Diagrama de sequência relativo ao caso de uso "Calcular Balanco"

Lançar Movimento:

Por fim, ilustra-se a sequência de interacções efectuadas na sequência de invocar o lançamento de um movimento, onde seinserem os lançamentos de créditos e de débitos. Este último diagrama de sequência ilustra o lançamento de um crédito ou deum débito, dependendo da escolha do utilizador.

Os cenários explorados até aqui são exemplos particulares de funcionalidades importantes que o utilizador pode solicitarao sistema por intermédio do GUI. Os caminhos possíveis que um utilizador pode percorrer no GUI podem ser descritos pelodiagrama de actividades da figura 24:

28

Fig. 23: Diagrama de sequência relativo ao caso de uso "Lançar Movimento"

Fig. 24: Diagrama de actividades

Como se verifica pela figura, o GUI permite a escolha das operações definidas nos requisitos funcionais. Fechar programa échamado pela tecla de atalho definida para o efeito ou pelo clique na "cruz" da janela, como em qualquer programa.

Note-se que a opção Apagar na acção Editar Membro do Agregado corresponde de facto a apagar um membro. No entanto,tecnicamente, o membro não é totalmente apagado. Esse elemento será considerado inactivo daí em diante, e após a datade desactivação não poderá lançar movimentos. Uma vez que podem haver movimentos associados a membros do agregadofamiliar, caso se apague (desactive) um membro, mantêm-se as referências a este nos movimentos pré-existentes.

29

Design do CódigoEsta subsecção pretende abordar ainda a mais baixo nível a arquitectura do software. Isto passa por:

- definição das estruturas de dados a utilizar em cada um dos componentes e a nível global- especificação do funcionamento concreto de funções do sistema e métodos das classes- explicitação da organização do código fonte; o nome dos ficheiros intervenientes, conteúdos e dependências

Estes são precisamente os objectivos dos próximos pontos abordados. Começa-se, então, pela definição de tipos deestruturas de dados utilizados no projecto, e do seu propósito no sistema.

Estruturas de Dados do SistemaNeste contexto, diferenciam-se estruturas de dados internas e externas às classes (estruturas globais).

Estruturas de Dados Globais:

Como já foi referido, para organização e armazenamento da informação no sistema em run-time, são mantidas listas ligadasglobais (listas de Membros, Movimentos, Balanços Consolidados, Tipologias, Movimentos Regulares, etc.), estruturadas deforma a tornar a navegação e pesquisa de informação do sistema mais rápida e organizada. Em baixo são enumeradas as listasglobais intervenientes na gestão de informação do sistema:

• list struct ano movsList - Armazena todos os movimentos já introduzidos.• list CMovimento* futurMovsList - Lista que contém referências aos movimentos regulares a serem lançados.• list CMembro membsList - Contém todos os membros do agregado familiar.• list CBalanco balsList - Guarda todos os balanços consolidados• list CTipologia tipoCredList - Contém todas as tipologias de crédito existentes.• list CTipologia tipoDebList - Contém todas as tipologias de débito existentes.• float saldoAgregado - Variável Float que contém o saldo do agregado familiar.

A lista futurMovsList contém ponteiros para os exemplares (as instâncias) mais recentes de cada movimento regular. Estalista de ponteiros permitirá o lançamento automático de movimentos regulares.

Exceptuando as listas movsList e futurMovsList, todas as restantes listas acima referidas contêm apenas objectos da classea que se referem. No entanto, a lista movsList foi estruturada para conter todos os movimentos de uma forma hierárquica e derápido acesso. Assim, são utilizados para cada nó da lista, três tipos de estruturas (além do ponteiro para o próximo objecto):

• struct dia - Contém um inteiro referente ao número do dia do mês e uma lista de movimentos.• struct mes - Contém um inteiro com o número do mês e uma lista de estruturas do tipo struct dia.• struct ano - Contém um inteiro referente ao ano em questão e uma lista de estruturas do tipo struct mes.

Assim, movsList é uma lista de structs ano, que corresponde ao ano em que o movimento foi efectuado. Dentro dos anostemos os meses e dentro dos meses os dias, e só dentro dos dias é que temos os movimentos referentes à data completa. Afigura 25 sumariza esta estruturação. Cada moldura representa uma estrutura do tipo dia, mês ou ano.

Esta organização hierárquica de listas permite uma maior eficiencia na edição/consulta dos movimentos, que é um processovital para o programa. Seguindo esta estrutura, todas as listas deverão ser ordenadas por ordem crescente de datas, e nocaso da lista de movimentos, ordenada por ordem de criação dos movimentos. Para tal, é necessário que os métodos dasclasses que adicionem elementos às listas localizem a posição de inserção ordenada antes de proceder à adição (ver subsecçãoImplementação dos Métodos).

30

Fig. 25: Estruturação da lista movsList

É também utilizada uma estrutura de dados para definir datas, struct Data. Esta é definida por três inteiros, que definem oano, o mês e o dia - indicado no canto superior esquerdo da primeira moldura da lista.

Estruturas de Dados internos às classes:

Os tipos de dados dos atributos que modelam as classes CMembro, CMovimento, CTipologia e CBalanco estão devidamenteespecificados no diagrama de classes da aquitectura do sistema principal. Convém salientar que os objectos da classe CBalancopossuem uma lista de ponteiros para movimentos organizada analogamente à lista global de movimentos movsList.

31

Implementação dos Métodos

Esta subsecção pretende providenciar um molde de elevada especificidade para a implementação de funções globais e métodosde classes prioritários. Primeiramente são abordadas funções globais do sistema, seguindo-se a implementação de métodosespecíficos de cada classe principal.

Funções Globais

Neste campo inserem-se essencialmente as funções de inicialização e de gestão de informação nas listas, entre outrasseguidamente abordadas.

As funções procuraMembro e procuraTipologia são funções globais que procuram nas respectivas listas pelo elementoque contém a designação igual à string passada como parâmetro e retorna um ponteiro para esse elemento. No caso daprocuraTipologia, o boolean credDeb serve para discernir qual a lista de tipologias a procurar, se na lista de créditos ou nalista de débitos.

Algorithm 1 procurarMembro1: procedure procurarMembro((String nomeMembro))2: for all membro in membsList do3: if nomeMembro == membro.nome then4: return (&membro)5: end if6: end for7: return (null)8: end procedure

Algorithm 2 procurarTipologia1: procedure procurarTipologia((String desTipo, boolean tipCredDeb))2: if tipCredDeb then3: for all tipologia in tipoDebList do4: if desTipo == tipologia.nome then5: return (&tipologia)6: end if7: end for8: else9: for all tipologia in tipoCredList do10: if desTipo == tipologia.nome then11: return (&tipologia)12: end if13: end for14: end if15: return (null)16: end procedure

32

Algorithm 3 procurarMovimentos1: procedure procurarMovimentos((Data dInicio, Data dFim))2: list <CMovimento*> auxiliar;3: for all movimento in movsList do4: if (movimento.data ≤ dF im)&(movimento.data ≥ dInicio) then5: auxiliar.add(&movimento)6: end if7: end for8: return (auxiliar) . Retorna todos os movimentos entre as datas dos parametros9: end procedure

Algorithm 4 eConsolidado1: procedure eConsolidado((Data dInicio, Data dFim))2: CBalanco* auxiliar=null;3: if dInicio e dFim definem um mes then4: for all balanco in balsList do5: if (dInicio == balanco.dInicio) && (dFim == balanco.dFim) then6: auxiliar ← &balanco;7: break;8: end if9: end for10: end if11: return(auxiliar);12: end procedure

Algorithm 5 CalcularSaldo1: procedure CalcularSaldo2: saldo← 03: for all movimento in movsList do4: if movimento.credDeb then5: saldo← saldo−movimento.montante6: else7: saldo← saldo + movimento.montante8: end if9: end for10: return (saldo)11: end procedure

Algorithm 6 LancamentoAutomatico1: procedure LancamentoAutomatico2: for all movimento in futurMovsList do3: if movimento.initData e data actual perfaz um mês ou mais then4: Lançar movimento para mês seguinte5: Actualizar ponteiro na lista de futuros movimentos para apontar para este novo movimento.6: end if7: end for8: end procedure

33

Os métodos das classes foram criados de modo a haver uma gestão lógica da informação, seja intra-classe ou inter-classes.Alguns métodos não serão aqui detalhados, por se tratarem de simples procedimentos de retorna de atributos de uma classeou de inicializações de atributos. A implementação feita segue os seguintes pseudo-códigos:

Classe CMembro:

Algorithm 7 CriarMembro1: procedure CriarMembro(String, Data, Data, Boolean)2: membro← CMembro(String, Data, Data, Boolean)3: Adiciona membro à ListaMembros4: Actualiza ficheiro binário dos membros5: return (&membro)6: end procedure

Convém referir que aquando a criação de um membro coloca-se sempre a booleana activo a verdadeiro. Isto é, ambos osconstrutores da classe colocam a 1 este atributo.

Algorithm 8 ApagarMembro1: procedure ApagarMembro()2: activo← false3: Actualiza ficheiro binário dos membros4: end procedure

O método ApagarMembro não apaga o objecto, uma vez que o Membro poderá estar a ser utilizado em movimentos dopassado. Assim, para manter a informação consistente, é colocado a false o atributo activo, indicando que este membro nãopoderá executar mais nenhum movimento, após a data de inactivação. Caso um membro não esteja activo, a única operaçãopossível é de colocar novamente activo, chamando a função Activa() da mesma classe.

34

Classe CTipologia:

Algorithm 9 CriarTipologia1: procedure CriarTipologia(String, Boolean, String)2: tipologia← CT ipologia(String, Boolean, String)3: if tipologia.credDeb == falso then4: Adiciona tipologia à lista de tipologias crédito5: else6: Adiciona tipologia à lista de tipologias dédito7: end if8: Actualiza ficheiro binário das tipologias9: return (&tipologia)10: end procedure

Algorithm 10 EditarTipologia1: procedure EditarTipologia(String, BooleannewCredDeb, String)2: if credDeb 6= newCredDeb then3: Troca a tipologia da lista onde se encontra para a outra lista de tipologias4: end if5: Actualiza dados da instância6: Actualiza ficheiro binário das tipologias7: end procedure

35

Classe CBalanco:

Algorithm 11 CriarBalanco1: procedure CriarBalanco(Data dInicio, Data dFim)2: Boolean defineMes← false3: if dInicio e dFim definem um mês (mes) then4: defineMes← true5: CBalanco ∗ consolidado← EConsolidado(dInicio, dF im)6: if (consolidado 6= null) then7: return(&balanço consolidado);8: end if9: end if10: list CMovimento* auxiliar ← null;11: totDeb ← 012: totCred ← 013:14: for all movimento in movsList do15: if (movimento.data ≤ dF im)&(movimento.data ≥ dInicio) then16: auxiliar.add(&movimento)17: if movimento.credDeb then18: totDeb← totDeb + movimento.montante19: else20: totCred← totCred + movimento.montante21: end if22: end if23: end for24: saldo← totCred− totDeb25: if (defineMes == true) then26: Adiciona Balanço à lista de Balanços consolidados27: Actualiza ficheiro binário dos balanços28: end if29: balanco ← CBalanco(dInicio, dFim, totDeb, totCred, saldo, auxiliar)30: return(&balanco)31: end procedure

Convém notar que EConsolidado(Data, Data) retorna um ponteiro para o balanço consolidado já existente, ou retorna nullcaso este não exista.

Algorithm 12 loadBalanco1: procedure loadBalanco(Data, Data, F loat, F loat, F loat)2: balanco ← CBalanco(Data,Data,Float,Float,Float) . com os parametros de entrada de loadBalanco3: balanco.List_ptrs_Movs_Bal ← procurarMovimentos(Data, Data)4: return(&balanco)5: end procedure

36

Classe CMovimento:

Algorithm 13 lancarMovimento1: procedure lancarMovimento(Float, Data, Data, Boolean,long int, list CMembro*, Tipologia*)2: movimento← CMovimento(Float, Data, Data, Boolean, long int, list CMembro*, Tipologia*)3: if movimento.reg && id não existente na futurMovsList then4: futurMovsList.add(&movimento)5: movimento.id ← proxID6: Incrementar proxID7: end if8: for all CMembro in ListaMembros do9: Adicionar CMembro à lista de membros do movimento10: Adicionar montante ao totCred ou totDeb do CMembro - CMembro.addCredDeb(float, boolean)11: end for12: if (Lista de membros não está vazia) then13: Atribuir os restantes atributos14: Adicionar movimento à lista de movimentos global15: end if16: Actualizar Saldo17: Actualiza ficheiro binário dos movimentos18: return(&movimento)19: end procedure

A lista de membros que entra como parâmetro nesta função não é a lista global que contêm todos os membros. É uma listaque contêm os elementos do agregado familiar que estão associados ao movimento em questão.

O construtor da classe CMovimento coloca sempre o id do objecto a criar a 0. Somente movimentos regulares terão iddiferente de 0. Estes ID’s servem para diferenciar os movimentos regulares que estarão referenciados na lista futurMovsList.Ser

Algorithm 14 EditarMovimento1: procedure EditarMovimento(F loat, Data, Data, BooleannewCredDeb, BooleannewReg, longint, listCMembro∗, T ipologia∗)2: if CredDeb 6= newCredDeb then3: Actualiza saldo.4: end if5: if reg 6= newReg then6: if ( thennewReg == 1)7: futurMovsList.add(*this)8: else9: futurMovsList.remove(*this);10: end if11: end if12: Actualizar atributos13: if (data movimento compreendida na data de um balanço consolidado existente) then14: CalBalanco() para esse balanço . Actualiza balanço15: end if16: Actualiza ficheiro binário dos movimentos17: end procedure

Aquando a mudança do boolean credDeb, o GUI obrigará o utilizar a alterar o tipo de tipologia também, uma vez que astipologias de crédito são diferentes das de débito.

37

A função inicializar() tem como objectivo inicializar o programa com as informações guardadas nos ficheiros, caso existam.Deste modo, deve ler todos os ficheiros necessários e criar os objectos que estes ficheiros referem.

Classe CGestaoFicheiros:

Algorithm 15 inicializar()1: procedure inicializar()2:3: open ficheiro Membros.bin4: if Abriu com sucesso then5: for all linha in Membros.bin do6: CriarMembro(parametros retirados do ficheiro); . Ver CriarMembro em Classe CMembro7: end for8: end if9:10: open ficheiro Tipologias.bin11: if Abriu com sucesso then12: for all linha in Tipologias.bin do13: CriarTipologia(parametros retirados do ficheiro); . Ver CriarTipologia em Classe CTipologia14: end for15: end if16:17: open ficheiro Movimentos.bin18: if Abriu com sucesso then19: list CMembro* memList20: for all linha in Movimentos.bin do21: for all membro in linha do22: memList.add(procurarMembro(String relativa ao nome do membro))23: end for24: CTipologia* tipPtr = procurarTipologia(String relativa à designação da tipologia, boolean credDeb retirado do ficheiro)25: LancarMovimento(parametros retirados do ficheiro, memList, tipPtr); . Ver LancarMovimento em Classe CMovimento26: end for27: end if28:29: open ficheiro Balanco.bin30: if Abriu com sucesso then31: for all linha in Balanco.bin do32: Data dInicio← primeiros 3 campos da linha33: Data dF im← 3 campos seguintes da linha34: float totCred← campo seguinte na linha35: float totDeb← último campo da linha36: loadBalanco(dInicio, dFim, totCred, totDeb); . Ver CriarBalanco em Classe CBalanco37: end for38: end if39: end procedure

38

Algorithm 16 Exportar1: procedure Exportar(String nome)2: if nome.csv existe then3: Perguntar se quer reescrever ficheiro;4: if Quer preservar ficheiro then5:6: return;7: end if8: end if9: Guarda balanço no ficheiro nome.csv;10: end procedure

39

Organização do código-fonteNesta secção são especificados os tipos, nomes e formatos de ficheiros mantidos pelo sistema global, bem como as dependências

entre estes. Para facilitar a compreensão da organização dos ficheiros, são apresentados diagramas de componentes dos ficheirosreferentes aos módulos Sistema Principal, Ficheiros e GUI.

Organização de ficheiros de Sistema Principal e Ficheiros

A figura 26 ilustra a organização e as dependências dos diferentes ficheiros que constituem os módulos Sistema Principal eFicheiros.

Fig. 26: Diagrama de Componentes representativo da organização de ficheiros em Sistema Principal e Ficheiros.

Identificam-se três conjuntos de ficheiros essenciais:

- Ficheiros de Armazenamento:

Para gestão do sistema principal, serão mantidos 4 ficheiros essenciais em formato binário: "Membros.bin", "Movi-mentos.bin", "Balancos.bin" e "Tipologias.bin". Estes ficheiros armazenarão a informação relativa a todas as instânciasdas estruturas de dados homónimas, essencial ao correcto funcionamento do programa. A figura 28 apresenta umaperspectiva mais detalhada da organização dos ficheiros de armazenamento. Assim, os diferentes ficheiros contêm asseguintes informações:

– Membros.bin - Armazena informação de todos os objectos da classe CMembro no sistema em disco.– Movimentos.bin - Armazena informação de todos os objectos da classe CMovimento no sistema em disco.– Tipologias.bin - Armazena informação de todos os objectos da classe CTipologia no sistema em disco.– Balancos.bin - Armazena informação de todos os objectos da classe CBalanco no sistema em disco.

- Ficheiros Exportados:

O utilizador poderá exportar um balanço sempre que desejar. O nome do ficheiro de exportação, na figura 26representado por ExportacaoDMA.csv, poderá ser escolhido pelo utilizador.

- Ficheiros de código fonte:

40

Nesta categoria de ficheiros encontra-se:

– Ficheiro de código fonte principal "GestaoAG.cpp".– Ficheiros código fonte e header files respeitantes a definição de classes e funções. Uma perspectiva mais detalhada

da organização dos ficheiros de código fonte do Sistema Principal pode ser observada na figura 27. Os ficheirosintervenientes são:

- CMembro.h, CBalanco.h, CMovimento.h, CTipologia .h, CFiles.h - Contêm definições das classes respectivas.- DefGlobal.h - Contém definições de estruturas de dados globais e e declarações de funções globais.- CMembro.cpp, CBalanco.cpp, CMovimento.cpp, CTipologia.cpp, CFiles.cpp - Contêm definições dos métodosdas classes respectivas.

- DefGlobal.cpp - Contém definições de funções globais.

- Ficheiros Objecto: Ficheiros objecto correspondentes aos ficheiros .cpp referidos.

- Ficheiros Executáveis: Ficheiro GestãoAG.exe, aplicação final.

41

Fig. 27: Diagrama de Componentes representativo da organização de ficheiros em Sistema Principal

Fig. 28: Diagrama de Componentes representativo da organização de ficheiros em Ficheiros de Armazenamento

42

Organização de ficheiros do GUI

A organização de ficheiros do GUI foi alvo de uma abordagem isolada dos outros dois módulos principais.

Fig. 29: Diagrama de Componentes representativo da organização de ficheiros do GUI.

No diagrama da figura 29 temos presentes os ficheiros que fazem parte do GUI. É possível distinguir 2 grandes grupos decomponentes:

• Window;

• Source:

– Ficheiros .h;– Ficheiros .cpp;

O primeiro grupo, "Window", são os ficheiros que fazem parte da interface do utilizador (.ui), que contém todo o ambientegráfico com que o utilizador vai interagir, como botões, calendários, menus, entre outros.

Dentro do segundo grupo, "Source", estão os ficheiros header (.h), que para além de incluir as bibliotecas necessárias para ofuncionamento do programa, contém também a inicialização da classe associada à janela específica, bem como a declaração deatributos públicos e privadas e declaração de funções específicas da classe, que podem resultar de eventos despoletados pelainterface gráfica.

Por fim, estão os ficheiros de código source (.cpp). Estes são os ficheiros sobre os quais o programa assenta. Aqui, cada .cppvai ter a inicialização das funções das correspondentes classes, fazendo a ligação entre o ambiente gráfico e o programa. Parauma explicação mais detalhada sobre cada conjunto de ficheiros .h, .cpp e .ui, e de maneira a evitar repetições desnecessárias,sempre que referirmos ficheiros sobre cada classe usada, iremos ocultar os tipos de ficheiro, por nos referirmos aos 3 de umaforma global, para aquela classe em específico. As classes que usamos para a GUI são:

• AddMemberWindow, que trata da janela para adicionar um novo membro, inicializa os calendários com as datas actuais.No caso da caixa que indica fontes de rendimento ser conferido ou não, desactiva ou activa a introdução do montante edata de depósito;

• AddMovementWindow, trata da janela que permite adicionar um novo movimento. Para além de permitir adicionar umnovo movimento, também são criados atalhos que permitem adicionar membros ou tipologias, sendo que são criadas asjanelas correspondentes em funções desta classe;

43

• AddTipology, trata da janela que permite criar uma nova tipologia;

• EditMemberWindow, trata da janela que permite editar a informação de um membro, que aquando da criação da janela,coloca os calendários com a data actual. Seleccionando a opção de desactivar o membro é chamada uma função quedesactiva os campos da edição de informação, e seleccionando a opção de editar membro, faz o inverso. Tal comona classe AddMemberWindow, no caso de ser indicado que não há fontes de rendimento, é chamada uma função quedesactiva montante e data de depósito;

• EditMovementWindow é uma classe cujos ficheiros, referentes ao GUI são iguais a AddMovementWindow, com o mesmotipo de funcionalidades implementadas, como criação de atalhos para adicionar membros e tipologias;

• EditTipologyWindow, trata da janela para a edição de uma tipologia, que é igual a AddTipologyWindow;

• EraseMovementWindow, trata da janela de aviso, que apenas pede a confirmação do utilizador para apagar o movimento;

• HelpWindow, trata da janela de ajuda;

• Menu, trata da janela principal. Aqui, inicializa-se os atalhos para a criação de membros, movimentos e tipologias, bemcomo atalhos para alternar entre as abas presentes no ficheiro .ui. Além disso tem a inicialização das funções que os vãocriar, criando todas as outras classes dentro das suas funções, que correspondem às janelas do GUI.

O outro ficheiro correspondente ao GUI é o main.cpp, que para já, apenas cria uma instância da classe Menu e lança-a.

Conclusão

O Desenho da Arquitectura permite conceptualizar todo o processo de desenvolvimento de uma maneira intuitiva. AConsolidação de Requisitos permite confirmar que a equipa e o cliente estão sintonizados em termos das funcionalidades queo programa deverá apresentar. O Design Conceptual permite detalhar as funcionalidades de uma maneira mais ilustrativa.Pretende, mais precisamente, mostrar ao cliente como serão implementadas as funcionalidades desejadas, comparando-ascom outro tipo de soluções abordadas pela equipa de desenvolvimento. Demonstra também o tipo de navegabilidade queo programa terá, de maneira a explicitar as opções de caminhos possíveis dentro na interface gráfica. O Design Técnicocontém, já, a formulação do problema a um nível técnico mais detalhado. Deste modo, desenvolve a solução adoptada ao níveldas estruturas usadas e delineia os mais importantes procedimentos que permitem as funcionalidades de maior prioridade.Esta última parte tem também que ser clara e informativa o suficiente para, caso este documento seja fornecido a uma outraequipa de desenvolvimento, esta seja capaz de criar um programa que vá de encontro ao que o cliente necessita, sem ser precisoexplicações adicionais.

Uma boa projecção do Desenho da Arquitectura facilita o desenvolvimento do projecto nas fases seguintes. Na verdade,este documento deverá ser seguido, com os devidos ajustes, durante a implementação da arquitectura.

44