desenvolvimento de software centrado no domínio · em domínios de elevada complexidade. em...
TRANSCRIPT
Desenvolvimento de Software Centrado no Domínio O caso da Distribuição do Serviço Docente
João Pedro Manaças Sitefane
Dissertação para a obtenção do Grau de Mestre em
Engenharia Informática e de Computadores
Júri Presidente: Doutor Pedro Nuno Ferreira da Rosa da Cruz Diniz
Orientador: Doutor António Manuel Ferreira Rito da Silva
Vogais: Doutor António Paulo Teles de Menezes Correia Leitão
Doutor José Luís Brinquete Borbinha
Setembro de 2007
Agradecimentos
Ao meu orientador, Professor António Rito da Silva, o meu sincero agradecimento por toda a
disponibilidade, apoio e orientação que me deu ao longo deste ano lectivo e pela oportunidade de
desenvolver este trabalho integrado no Projecto Fénix.
Queria agradecer também a todos os elementos da Equipa Fénix, em especial ao Nadir
Tarmahomed, João Alfaiate e Paulo Abrantes, pela disponibilidade e atenção que me deram sempre
que necessitei do vosso auxílio.
Não podia deixar de agradecer também a todos os meus amigos, da Eira e arredores. Apesar
de, neste último ano, eu andar “desaparecido”, obrigado por todos os genuínos momentos de prazer
com que me brindaram sempre que estivemos juntos.
Finalmente, um agradecimento especial para a família. Pai e mãe, obrigado por todo o amor,
apoio e as regalias que me deram, agora e ao longo da vida, e que fizeram com que eu sempre me
sentisse como uma pessoa privilegiada. Irmão e primas, obrigado por tudo de bom que me
proporcionam ao longo dos anos. (Futuros) sogros e cunhado, obrigado pela amizade e o carinho
com que sempre me estimaram. Sara, obrigado por toda a força que me deste e, principalmente, por
acreditares em mim. Sem a tua presença ao meu lado não teria conseguido concluir este trabalho.
Resumo
O típico processo de desenvolvimento de software contempla as actividades de análise,
desenho, implementação, testes e manutenção. Na actividade de desenho realiza-se a descrição
rigorosa do software a ser produzido. Esta descrição serve de passagem do espaço do problema
para o espaço da solução.
Quando o espaço do problema é de complexidade elevada, a passagem para o espaço da
solução pode tornar-se numa tarefa demasiado exigente para a equipa responsável pelo
desenvolvimento do software. De forma a suplantar-se esta dificuldade e a lidar-se correctamente
com domínios de elevada complexidade, o desenho centrado no domínio define um conjunto de
linhas de orientação que devem estar presentes durante a actividade de desenho de software.
A aplicação Distribuição do Serviço Docente foi inicialmente desenvolvida com o intuito de
automatizar o processo de distribuição do serviço docente. O elevado grau de complexidade
associado a este domínio originou o aparecimento de um conjunto de problemas ao nível do desenho
da aplicação. A correcção destas limitações requer a revisão do desenho.
Esta dissertação segue a abordagem do desenho centrado no domínio durante o processo de
revisão do desenho da aplicação Distribuição do Serviço Docente. Começa-se por descrever e
discutir os princípios do desenho centrado no domínio que facilitam o desenvolvimento de software
em domínios de elevada complexidade. Em seguida, usam-se estes princípios para guiar o processo
de redesenho da aplicação. Termina-se com a implementação do novo desenho da aplicação e,
consequentemente, com a garantia de que este fica alinhado com os princípios do desenho centrado
no domínio.
Abstract
The typical software development process is formed by the activities of analysis, design,
implementation, testing and maintenance. The design is the task of precisely describing the software
to be written. This description marks the transition from the problem space to the solution space.
When the problem space has high complexity, the correct transition to the solution space may
be an overwhelming task to a software development team. To overcome this difficulty and ease
software projects that have to deal with complex domains, the domain-driven design defines a set of
principles and guidelines that should be present during the software design activity.
The software Distribuição do Serviço Docente was initially developed with the purpose of
automating the teacher service distribution process. The high degree of complexity associated with
this domain caused the appearance of a set of problems in its design. The correction of these
limitations requires the revision of the software design.
This dissertation follows the approach of domain-driven design during the redesign process of
the software Distribuição do Serviço Docente. We start with the description of the principles and the
guidelines that ease the software development in complex domains. Then, we use these principles to
guide the software’s redesign process. We end with the implementation of the new design and,
consequently, with the guarantee that it stays aligned with the principles of domain-driven design.
Palavras-chave
Desenho Centrado no Domínio
Modelo de Domínio
Refactorização
Desenho Estratégico
Distribuição do Serviço Docente Keywords
Domain-driven Design
Domain Model
Refactoring
Strategic Design
Teacher Service Distribution
Índice
1 Introdução ......................................................................................................................................... 1 1.1 Definição do Problema .............................................................................................................. 2
1.1.1 Distribuição do Serviço Docente ..................................................................................... 2 1.2 Objectivos.................................................................................................................................. 3 1.3 Resultados................................................................................................................................. 3 1.4 Estrutura da Dissertação........................................................................................................... 3
2 Distribuição do Serviço Docente .................................................................................................... 5
2.1 Contexto .................................................................................................................................... 5 2.1.1 O Processo de Distribuição do Serviço Docente ............................................................ 5
2.2 Objectivos.................................................................................................................................. 7 2.3 Modelo de Domínio ................................................................................................................... 9
2.3.1 Distribuição do Serviço Docente ................................................................................... 10 2.3.2 Fase............................................................................................................................... 10 2.3.3 Agrupamentos ............................................................................................................... 11 2.3.4 Docentes........................................................................................................................ 13 2.3.5 Disciplinas...................................................................................................................... 14 2.3.6 Estimativa de disciplinas................................................................................................ 15 2.3.7 Atribuição de docentes a estimativas de disciplinas ..................................................... 16
2.4 Problemas e Desafios ............................................................................................................. 17
3 Desenho Centrado no Domínio..................................................................................................... 19
3.1 Pressupostos........................................................................................................................... 19 3.2 Relevância do Modelo de Domínio ......................................................................................... 20
3.2.1 Ligação entre Desenho e Implementação..................................................................... 21 3.2.2 Comunicação................................................................................................................. 22 3.2.3 Partilha do conhecimento .............................................................................................. 22
3.3 Linguagens Específicas do Domínio ....................................................................................... 23 3.3.1 Tipos de Linguagens Específicas do Domínio .............................................................. 24 3.3.2 Exemplo de Linguagem Específica do Domínio............................................................ 25
3.4 Padrões e o Desenho Centrado no Domínio .......................................................................... 26 3.5 Aplicação do Desenho Centrado no Domínio ......................................................................... 27
4 Construção do Modelo de Domínio.............................................................................................. 29
4.1 Arquitectura em camadas ....................................................................................................... 30 4.1.1 Motivação ...................................................................................................................... 30 4.1.2 Solução.......................................................................................................................... 30
4.1.3 Aplicação ....................................................................................................................... 31 4.2 A expressão do modelo........................................................................................................... 34
4.2.1 Motivação ...................................................................................................................... 34 4.2.2 Solução.......................................................................................................................... 34
4.2.2.1 Entidade e Valor..................................................................................................... 34 4.2.2.2 Serviço ................................................................................................................... 35 4.2.2.3 Módulo ................................................................................................................... 36
4.2.3 Aplicação ....................................................................................................................... 36 4.2.3.1 Entidade e Valor..................................................................................................... 36 4.2.3.2 Serviço ................................................................................................................... 37 4.2.3.3 Módulo ................................................................................................................... 38
4.3 Ciclo de vida de um objecto do domínio ................................................................................. 40 4.3.1 Motivação ...................................................................................................................... 40 4.3.2 Solução.......................................................................................................................... 41
4.3.2.1 Agregação.............................................................................................................. 41 4.3.2.2 Fábrica ................................................................................................................... 42 4.3.2.3 Repositório ............................................................................................................. 42
4.3.3 Aplicação ....................................................................................................................... 43 4.3.3.1 Agregação.............................................................................................................. 43 4.3.3.2 Fábrica ................................................................................................................... 45 4.3.3.3 Repositório ............................................................................................................. 46
4.4 Conclusão................................................................................................................................ 47
5 Refactorização ................................................................................................................................ 49
5.1 O Processo de Refactorização................................................................................................ 49 5.1.1 Motivação ...................................................................................................................... 50 5.1.2 Níveis de Refactorização............................................................................................... 50
5.2 Interface reveladora de intenção............................................................................................. 51 5.2.1 Motivação ...................................................................................................................... 51 5.2.2 Solução.......................................................................................................................... 51 5.2.3 Aplicação ....................................................................................................................... 52
5.3 Função sem efeitos secundários............................................................................................. 54 5.3.1 Motivação ...................................................................................................................... 54 5.3.2 Solução.......................................................................................................................... 54 5.3.3 Aplicação ....................................................................................................................... 55
5.4 Testes de software .................................................................................................................. 56 5.4.1 Motivação ...................................................................................................................... 56 5.4.2 Solução.......................................................................................................................... 56 5.4.3 Aplicação ....................................................................................................................... 58
5.5 Decomposição de conceitos ................................................................................................... 60 5.5.1 Motivação ...................................................................................................................... 60
5.5.2 Solução.......................................................................................................................... 60 5.5.3 Aplicação ....................................................................................................................... 61
5.6 Classes independentes ........................................................................................................... 63 5.6.1 Motivação ...................................................................................................................... 63 5.6.2 Solução.......................................................................................................................... 64 5.6.3 Aplicação ....................................................................................................................... 64
5.7 Conclusão................................................................................................................................ 65
6 Desenho Estratégico...................................................................................................................... 67
6.1 Integridade do modelo............................................................................................................. 68 6.1.1 Contexto ........................................................................................................................ 69
6.1.1.1 Motivação............................................................................................................... 69 6.1.1.2 Solução .................................................................................................................. 69 6.1.1.3 Aplicação................................................................................................................ 69
6.1.2 Integração...................................................................................................................... 71 6.1.2.1 Motivação............................................................................................................... 71 6.1.2.2 Solução .................................................................................................................. 71 6.1.2.3 Aplicação................................................................................................................ 71
6.1.3 Mapa de Contextos........................................................................................................ 72 6.1.3.1 Motivação............................................................................................................... 72 6.1.3.2 Solução .................................................................................................................. 72 6.1.3.3 Aplicação................................................................................................................ 72
6.1.4 Núcleo partilhado........................................................................................................... 73 6.1.4.1 Motivação............................................................................................................... 73 6.1.4.2 Solução .................................................................................................................. 73 6.1.4.3 Aplicação................................................................................................................ 74
6.1.5 Separação de interesses............................................................................................... 74 6.1.5.1 Motivação............................................................................................................... 74 6.1.5.2 Solução .................................................................................................................. 74 6.1.5.3 Aplicação................................................................................................................ 75
6.1.6 Conclusão...................................................................................................................... 75
7 Implementação ............................................................................................................................... 77
7.1 Metodologia ............................................................................................................................. 77 7.2 Arquitectura e Tecnologias da Solução................................................................................... 78
7.2.1 Camada de Infra-estrutura............................................................................................. 79 7.2.2 Camada do Domínio...................................................................................................... 79 7.2.3 Camada de Aplicação.................................................................................................... 79 7.2.4 Camada de Apresentação............................................................................................. 80
8 Conclusão ....................................................................................................................................... 81 8.1 Resultados............................................................................................................................... 81 8.2 Trabalho Futuro ....................................................................................................................... 82
9 Bibliografia...................................................................................................................................... 83
A Interfaces da Aplicação Distribuição do Serviço Docente........................................................ 87
B Terminologia .................................................................................................................................. 93
Lista de Figuras e Quadros
Figuras Figura 2.1. Exemplo de uma folha de cálculo usada para o processo de distribuição do serviço
docente. ................................................................................................................................................... 6 Figura 2.2. Modelo de domínio da aplicação DSD.................................................................................. 9 Figura 2.3. Entidade TeacherServiceDistribution..................................................................... 10 Figura 2.4. Visão das várias fases de um processo de distribuição do serviço docente...................... 11 Figura 2.5. Entidade ValuationPhase............................................................................................... 11 Figura 2.6. Visão de um agrupamento de docentes e disciplinas. ....................................................... 12 Figura 2.7. Entidade ValuationGrouping. ....................................................................................... 12 Figura 2.8. Visão dos docentes de um agrupamento. .......................................................................... 13 Figura 2.9. Entidade ValuationTeacher. ......................................................................................... 14 Figura 2.10. Visão das disciplinas de um agrupamento. ...................................................................... 14 Figura 2.11. Entidades ValuationCompetenceCourse e ValuationCurricularCourse......... 15 Figura 2.12. Visão das estimativas de disciplinas................................................................................. 15 Figura 2.13. Entidade CourseValuation........................................................................................... 16 Figura 2.14. Visão da atribuição de docentes a disciplinas. ................................................................. 16 Figura 2.15. Entidade ProfessorshipValuation. .......................................................................... 16
Figura 3.1. Exemplo do ficheiro de dados............................................................................................. 25 Figura 3.2. Exemplo do ficheiro de configuração.................................................................................. 26 Figura 3.3. Exemplo de linguagem específica do domínio. .................................................................. 26
Figura 4.1. Construção de um modelo através do desenho centrado no domínio. .............................. 29 Figura 4.2. Arquitectura em camadas da aplicação DSD. .................................................................... 32 Figura 4.3. Visão da separação entre a estrutura e o comportamento do domínio.............................. 33 Figura 4.4. Separação entre valor e entidade, através do padrão Extract Class. ................................ 35 Figura 4.5. Perspectiva do interior de um módulo e das relações entre módulos. ............................... 36 Figura 4.6. Módulo DSD e suas relações com outros módulos do sistema Fénix................................ 39 Figura 4.7. Exemplo de uma agregação. .............................................................................................. 41 Figura 4.8. Interacção de um cliente com uma fábrica. ........................................................................ 42 Figura 4.9. Interacção de um cliente com um repositório. .................................................................... 43 Figura 4.10. Identificação de agregações no contexto DSD................................................................. 44 Figura 4.11. Diagrama de sequência para a criação de uma distribuição do serviço docente. ........... 45 Figura 4.12. Diagrama de colaboração para a pesquisa de objectos do domínio................................ 46
Figura 4.13. Situação do modelo de domínio da aplicação DSD após a introdução dos princípios do
desenho centrado no domínio para a construção do modelo. .............................................................. 48
Figura 5.1. Mapa de navegação para o processo de refactorização. ................................................... 49 Figura 5.2. Exemplo de interface reveladora de intenção..................................................................... 52 Figura 5.3. Exemplo de uma função sem efeitos secundários. ............................................................ 55 Figura 5.4. Composição de uma estrutura de testes, de acordo com o padrão Composite................. 57 Figura 5.5. Exemplo do código de implementação de uma classe de testes. ...................................... 58 Figura 5.6. Exemplo de classe de testes. ............................................................................................. 59 Figura 5.7. Decomposição de conceitos através do padrão Extract Subclass. .................................... 61 Figura 5.8. Exemplo da lógica presente nos métodos de TSDTeacher, como consequência da classe
representar dois conceitos do domínio. ................................................................................................ 61 Figura 5.9. Decomposição de TSDTeacher......................................................................................... 62 Figura 5.10. Criação de TSDVirtualCourseGroup. ......................................................................... 62 Figura 5.11. Exemplo da multiplicação de métodos pelo tipo de aula existentes................................. 62 Figura 5.12. Aplicação do padrão Parameterize Method para a criação de métodos parametrizados.63 Figura 5.13. Decomposição de TSDCourse. ........................................................................................ 63 Figura 5.14. Modelo de domínio da aplicação DSD após a introdução dos princípios do desenho
centrado no domínio para o processo de refactorização. ..................................................................... 66
Figura 6.1. Princípios para a manutenção da integridade do modelo. ................................................. 68 Figura 6.2. Modelo de domínio do contexto DSD. ................................................................................ 70 Figura 6.3. Acção do contexto, mapa de contextos e núcleo partilhado. ............................................. 73
Figura 7.1. Ciclo de desenvolvimento da nova versão da aplicação DSD. .......................................... 77
Figura 10.1. Acesso à aplicação Distribuição do Serviço Docente....................................................... 87 Figura 10.2. Criação de um novo processo de distribuição do serviço docente................................... 87 Figura 10.3. Ecrã principal do processo de distribuição. ...................................................................... 88 Figura 10.4. Gestão de permissões. ..................................................................................................... 88 Figura 10.5. Gestão de fases. ............................................................................................................... 89 Figura 10.6. Gestão de docentes e disciplinas. .................................................................................... 89 Figura 10.7. Adição de docente. ........................................................................................................... 90 Figura 10.8. Criação de docente “virtual”. ............................................................................................. 90 Figura 10.9. Gestão de agrupamentos.................................................................................................. 90 Figura 10.10. Estimação da necessidade horária das disciplinas. ....................................................... 91 Figura 10.11. Estimação da atribuição de docentes a disciplinas. ....................................................... 92 Figura 10.12. Visualização do processo de distribuição. ...................................................................... 92
Quadros Quadro 6.1. Mapa de contextos DSD. ........................................................................................72
Lista de Abreviações
DML Domain Modeling Language
DSD Distribuição do Serviço Docente
GOP Gabinete de Organização Pedagógica
IST Instituto Superior Técnico
JVSTM Java Versioned Software Transactional Memory
STM Software Transactional Memory
TFC Trabalho Final de Curso
UML Unified Modeling Language
XML Extensible Markup Language
XP Extreme Programming
1
1 1
Introdução
Hoje em dia, parte significativa da produção de novo software rege-se por um processo de
desenvolvimento de software [Pfl01]. Este processo pode ser definido como uma série de actividades,
realizadas com a finalidade de obter um produto de software que responda às necessidades do seu
utilizador final. Todo o software está relacionado com alguma área de interesse do seu utilizador final.
Esta área, juntamente com as entidades que a constituem, forma o domínio do software.
As características do processo de desenvolvimento de software são estudadas dentro da área
de engenharia de software [Pfl01], sendo consideradas como um dos principais mecanismos
necessários para a obtenção de software de qualidade. A gestão do desenvolvimento de software é
uma tarefa difícil, uma vez que é necessário controlar muitas variáveis: a estrutura organizacional da
empresa, as competências da equipa, as tecnologias a serem usadas, etc. Por este motivo, não
existe um processo de desenvolvimento universalmente aplicável.
De modo geral, durante um processo de desenvolvimento de software realizam-se as seguintes
actividades:
Análise. Engloba o levantamento e análise dos requisitos para o software;
Desenho. Realização da descrição rigorosa e precisa do software a ser produzido. Esta
descrição define um modelo onde estão presentes os vários componentes do software, as
suas propriedades e as relações entre eles;
Implementação. Transformação do desenho em código fonte;
Teste. Verificação de que o programa desenvolvido apresenta o comportamento correcto e
cumpre todos os requisitos estabelecidos; e,
Manutenção. Visa corrigir novos problemas que são descobertos após o produto ser
disponibilizado ao cliente, assim como a integração de novas funcionalidades derivadas do
aparecimento de novos requisitos.
As diferentes actividades do processo dividem-se entre o espaço do problema e o da solução. A
análise situa-se no espaço do problema, uma vez que define o âmbito do problema em termos dos
requisitos a serem cumpridos pelo software. O desenho assinala a passagem do espaço do problema
para o espaço da solução, uma vez que estrutura o conhecimento resultante da análise com o
objectivo de construir um modelo da solução que dará resposta às necessidades do utilizador final.
2
As restantes actividades focam-se directamente no código fonte da aplicação e, por isso,
encontram-se no espaço da solução.
1.1 Definição do Problema
Na actividade de desenho descreve-se a estrutura final que o software irá ter. Esta descrição
assinala a passagem do espaço do problema para o espaço da solução. Contudo, quando o domínio
do software é de complexidade bastante elevada, esta passagem pode ser feita de forma incorrecta,
caso: 1) O desenho esteja desenquadrado com o domínio do software; ou, 2) A transformação do
desenho em código revele-se numa tarefa demasiado complexa de realizar. Estas dificuldades
determinam o insucesso do desenho e inviabilizam o sucesso das restantes actividades do processo.
A superação destas dificuldades é facilitada caso a abordagem ao domínio seja feita com
recurso a técnicas que facilitem o desenvolvimento de software em domínios de elevada
complexidade. Para tal, o desenho centrado no domínio [Eva03] propõe um conjunto de princípios
e linhas de orientação que devem estar presentes durante a actividade de desenho de software.
1.1.1 Distribuição do Serviço Docente
A abordagem ao desenho centrado no domínio será discutida num contexto específico. O
trabalho desenvolvido ao longo desta dissertação vai debruçar-se sobre a aplicação Distribuição do
Serviço Docente (DSD) [SK06], que se encontra integrada no sistema Fénix [PF05]. Esta aplicação foi
desenvolvida com o objectivo de disponibilizar uma ferramenta informática, acessível a todos os
departamentos do Instituto Superior Técnico (IST) [IST], a partir da qual fosse possível realizar o
processo de distribuição do serviço docente, ou seja, afectar recursos humanos para o ensino de
disciplinas.
A principal limitação da aplicação está relacionada com a qualidade do seu desenho. O
desenho, no seu estado actual, apresenta os seguintes problemas:
Fraca ligação entre o desenho e o domínio. Alguns componentes do desenho não se
enquadram de um modo natural e intuitivo com os demais componentes e com o próprio
domínio da aplicação. Esta ”desconexão” do desenho com o domínio faz com que, para
alguns componentes, seja necessário olhar-se para a sua implementação para se conseguir
ter uma ideia dos conceitos do domínio que representam;
Sobreposição de conceitos. Existem noções do domínio que se encontram sobrepostas
dentro do mesmo componente do modelo. Cada conceito do domínio deve estar decomposto
numa unidade individual, para que se consiga identificar facilmente qual o conceito do
domínio expresso por cada classe do modelo; e,
Falta de flexibilidade. Após o desenvolvimento da aplicação houve uma evolução do domínio
ao nível da estrutura curricular das disciplinas. Com a nova estrutura curricular de Bolonha
3
[Bol99] surgiram novos tipos de aula (como, por exemplo, seminários), que dificilmente se
conseguem representar no modelo actual da aplicação. O modelo deve ser reestruturado de
maneira a que se obtenha uma solução que permita representar os tipos de aula de um modo
flexível e, ao mesmo tempo, facilmente extensível.
A correcção destes problemas requer que sejam feitas reestruturações ao nível dos
componentes da aplicação. Alguns componentes deverão ser eliminados, outros terão de ser criados.
Relações entre componentes também serão modificadas. Assim, torna-se necessário reproduzir a
descrição de como os diferentes componentes da aplicação operaram em conjunto, ou seja, torna-se
necessário redesenhar o software.
1.2 Objectivos
O objectivo principal consistiu em seguir a abordagem do desenho centrado no domínio durante
o processo de revisão do desenho da aplicação DSD.
Este objectivo foi decomposto nos seguintes objectivos instrumentais:
Descrição e discussão dos princípios associados ao desenho centrado no domínio;
Avaliação da aplicabilidade de cada princípio do desenho centrado no domínio à aplicação
DSD; e,
Reestruturação da aplicação DSD de acordo com as linhas de orientação do desenho
centrado no domínio.
1.3 Resultados
Os resultados obtidos com o trabalho apresentado nesta dissertação foram:
Redesenho da aplicação DSD. Foi feita a revisão da versão iniciai do desenho da aplicação
DSD, como forma de corrigir as limitações apresentadas, de acordo com as linhas de
orientação do desenho centrado no domínio para: 1) A construção do modelo de domínio; 2)
A refactorização; e, 3) O desenho estratégico; e,
Implementação do novo desenho da aplicação DSD. Foi implementado o novo desenho da
aplicação DSD, ficando assim alinhado com os princípios do desenho centrado no domínio.
1.4 Estrutura da Dissertação
A dissertação está estruturada em 8 capítulos:
Capítulo 1 – Introdução. Apresenta o contexto da dissertação, a sua problemática e os
principais resultados do trabalho desenvolvido;
4
Capítulo 2 – Distribuição do Serviço Docente. Descreve a aplicação DSD, o contexto em
que surgiu e os problemas que inicialmente apresentava. Apresenta o modelo de domínio e
expõe os desafios e limitações apresentados pela aplicação;
Capítulo 3 – Desenho Centrado no Domínio. Caracteriza o desenho centrado no domínio e
evidencia as vantagens que este introduz para o processo de desenvolvimento de software;
Capítulo 4 – Construção do Modelo de Domínio. Define os fundamentos sobre os quais
está assente a construção de um modelo baseado no desenho centrado no domínio. Aplica os
fundamentos sobre o modelo de domínio da aplicação DSD;
Capítulo 5 – Refactorização. Apresenta os princípios do desenho centrado no domínio que
permitem simplificar a estrutura do modelo de domínio da aplicação DSD, para que este seja
mais facilmente interpretável e fique mais focado nos conceitos do domínio;
Capítulo 6 – Desenho Estratégico. Introduz os princípios do desenho centrado no domínio
que permitem obter uma visão conceptual correcta do “espaço” ocupado pelo domínio da
aplicação DSD dentro do domínio do sistema Fénix;
Capítulo 7 – Implementação. Descreve o processo de implementação do novo desenho da
aplicação DSD;
Capítulo 8 – Conclusão. Sumaria os resultados obtidos e expõe as oportunidades de
trabalho futuro; e,
Capítulo 9 – Bibliografia.
5
2 2
Distribuição do Serviço Docente
Este capítulo faz a exposição da aplicação DSD. Começa-se por definir o contexto que originou
a aplicação, seguido da enumeração dos seus principais objectivos. É feita a explicação sobre o
significado e a lógica subjacentes aos diferentes componentes do modelo de domínio da aplicação. O
capítulo termina com a abordagem aos problemas e desafios apresentados pela aplicação.
2.1 Contexto
O sistema Fénix é desenvolvido através do Projecto Fénix [PF] e encontra-se em produção no
IST, sendo o seu principal objectivo suportar as actividades de campus académico. Os serviços
disponibilizados pelo sistema encontram-se centralizados no portal Fénix e podem ser acedidos por
docentes, alunos e funcionários.
A aplicação DSD encontra-se implementada no sistema Fénix. A aplicação foi desenvolvida
durante a realização do Trabalho Final de Curso (TFC) Fénix – Departamento [SK06]. Este TFC teve
como principal objectivo o desenvolvimento de uma aplicação, acessível através do portal Fénix, que
auxiliasse os departamentos do IST a realizar a tarefa de afectação de recursos humanos para o
ensino de disciplinas. Esta tarefa é usualmente referida como distribuição do serviço docente.
2.1.1 O Processo de Distribuição do Serviço Docente
O processo de distribuição do serviço docente corresponde à afectação de recursos humanos
para o ensino de disciplinas. No IST, esta tarefa é realizada ao nível dos departamentos.
Cada departamento engloba um conjunto de docentes, responsáveis por leccionar as disciplinas
do departamento. Os docentes têm um número de horas semanais associadas a actividades do IST.
Essas horas semanais estão divididas entre o ensino, cargos de gestão e outras situações de não
exercício (por exemplo, licenças sabáticas). Dentro de cada departamento existe um grupo reduzido
de docentes e funcionários com a responsabilidade de distribuir as horas necessárias ao ensino das
disciplinas pelos docentes do departamento, tendo em conta factores como:
A competência dos docentes. Os docentes devem leccionar as disciplinas da área pedagógica
com a qual estão associados;
6
A carga laboral dos docentes. Cada docente tem um número de horas semanais obrigatórias
de ensino que não deve ser excedido e que varia consoante a sua categoria; e,
Os recursos existentes. Quando ainda existem horas por preencher para o ensino de
disciplinas, mas já não existem recursos humanos disponíveis, é necessário requisitar a
contratação de mais docentes.
A figura 2.1 ilustra uma folha de cálculo, uma das ferramentas mais frequentemente usadas
pelos departamentos para a realização do processo de distribuição do serviço docente. De modo
geral, a utilização das folhas de cálculo para a realização desse processo é feita da seguinte forma:
Cria-se uma tabela em forma de matriz, sendo que numa dimensão situam-se todos os
docentes do departamento e na outra dimensão as disciplinas da responsabilidade desse
departamento;
Inserem-se os totais relativos ao número de alunos inscritos em cada disciplina, a
necessidade de horas de cada disciplina e a disponibilidade lectiva de cada docente;
Assinalam-se as intersecções entre docentes e disciplinas. O valor indicado numa intersecção
representa as horas dispendidas pelo docente a leccionar aulas daquela disciplina (na figura
2.1, as intersecções entre docentes e disciplinas são representadas através das células de
cor azul). Este passo é repetido até que todas as disciplinas tenham as suas necessidades
horárias cobertas pelos docentes; e,
No final do processo, a folha de cálculo é distribuída pelos docentes do departamento e
enviada para o Gabinete de Orientação Pedagógica (GOP) [GOP], que tem a
responsabilidade de organizar, gerir e elaborar os horários das aulas das diferentes
licenciaturas leccionadas no IST.
Figura 2.1. Exemplo de uma folha de cálculo usada para o processo de distribuição do serviço docente.
7
2.2 Objectivos
O principal objectivo da aplicação DSD consistiu no desenvolvimento de uma aplicação que
facilitasse todo o processo de distribuição do serviço docente. A substituição das folhas de cálculo (e
de outras ferramentas usadas pelos departamentos) por esta aplicação permitiria obter as seguintes
vantagens:
Transparência. A visualização do processo de distribuição por todos os docentes, através do
portal Fénix, aumenta a transparência do processo. A comunicação do resultado final do
processo deixa de ficar dependente do envio de ficheiros (ou outros métodos de troca de
informação) por parte do conjunto de pessoas que realiza distribuição. Qualquer docente com
acesso ao portal Fénix consegue visualizar os processos de distribuição do serviço docente
que foram publicados para os diferentes anos lectivos;
Coerência de dados. Nas situações em que se usam várias folhas de cálculo para realizar o
processo de distribuição é necessário manter informação em paralelo; o mesmo docente
podia estar a ser usado em diferentes folhas, sem que ninguém tenha conhecimento dessa
situação. Este tipo de situações aumenta a probabilidade da ocorrência de erros. Com a
aplicação DSD existe a garantia de que todos os dados estão centralizados e que todas as
pessoas trabalham com a mesma fonte de informação; e,
Distribuição de tarefas. A aplicação DSD permite delegar a responsabilidade do processo de
distribuição por várias pessoas. É possível responsabilizar uma pessoa por realizar o
processo de distribuição para um determinado agrupamento de docentes e disciplinas de um
departamento. Desta forma, cada pessoa realiza a sua parte do processo de forma
independente e, no final, agrupa-se o trabalho feito por cada pessoa para completar-se o
processo de distribuição ao nível do departamento.
A obtenção destas vantagens é garantida pelo cumprimento de um conjunto de objectivos de
negócio:
Divisão de trabalho. De modo geral, a responsabilidade do processo de distribuição é
dividida por várias pessoas dentro de um departamento. Cada pessoa faz a distribuição para
a área científica ou secção a que está associada. No final os vários processos são agrupados,
para formar-se uma única distribuição ao nível do departamento;
Manutenção do histórico. Deve existir a possibilidade de, em qualquer instante,
salvaguardar-se toda a informação contida na distribuição. A partir desse ponto, recomeça-se
o processo sobre um novo conjunto de dados, sem prejuízo para a informação que
anteriormente estava em vigor. Essa informação transita para o histórico e pode ser
recuperada ou consultada em qualquer momento;
Refinamento do processo. Com a visualização do histórico mantido, podem ser estudadas
várias hipóteses para o mesmo processo de distribuição. Assim, à medida que ficam
8
disponíveis novas informações (como, por exemplo, os docentes recém contratados por um
departamento ou o número de alunos inscrito nas cadeiras) para aplicação DSD, é possível
refinar o processo de distribuição com a construção de cenários cada vez mais realistas;
Divisão de docentes e disciplinas. Dentro dos departamentos do IST existe uma divisão de
docentes por secção ou área científica/pedagógica e uma divisão de disciplinas por grupo de
competência. Como o processo de distribuição é, geralmente, feito para uma secção de
docentes e um ou mais grupos de competência de disciplinas, é importante que esta estrutura
dos departamentos esteja presente na aplicação DSD. Desta forma, ao realizar-se o processo
de distribuição, é possível trabalhar apenas com um subconjunto de disciplinas e docentes,
em vez de se trabalhar com todos os docentes e disciplinas do departamento;
Atribuição de créditos a docentes. Cada docente tem um número de horas semanais
obrigatórias de ensino que varia consoante a sua categoria. Para além das horas dispendidas
no ensino, os docentes podem ter cargos de gestão (como, por exemplo, a presidência de um
departamento) ou situações de não exercício (como, por exemplo, uma licença sabática).
Estas actividades extra lectivas fornecem créditos aos docentes. Os créditos reduzem as
horas semanais obrigatórias que um docente tem de leccionar. Assim, durante o processo de
distribuição tem de se ter em conta os créditos não lectivos dos docentes;
Criação de novos docentes. O processo de distribuição é feito com os recursos existentes
ao nível do departamento. Quando ainda existem horas por preencher para o ensino de
disciplinas e já não existem recursos humanos disponíveis, torna-se necessário requisitar a
contratação de mais docentes. Contudo, o processo de distribuição não pode parar. Para
resolver esta situação, tem de haver a possibilidade de criar docentes virtuais, específicos
para o processo de distribuição. O único propósito destes docentes é preencher as horas
vagas de ensino. As suas identidades reais são desconhecidas. Mais tarde, serão
substituídos por docentes reais (bolseiros, monitores ou professores convidados), contratados
pelo departamento;
Criação de novas disciplinas. À semelhança do que acontece com os docentes, deve haver
a possibilidade de criarem-se disciplinas não existentes, desta feita com o objectivo de indicar
a ocorrência de uma disciplina ainda não disponível para a aplicação DSD. Para o processo
de distribuição não parar, a criação de disciplinas virtuais permitirá continuar com o trabalho
até que a informação real sobre a nova disciplina fique disponível para a aplicação DSD;
Estimação da necessidade horária das disciplinas. Deve ser feita uma previsão do número
de horas semanais necessárias para o ensino de cada disciplina. Este número está
dependente de outros dois valores: 1) O número de alunos inscritos na disciplina; e, 2) O
número máximo de alunos por cada aula. A partir destas estimativas torna-se possível saber o
total de horas de ensino que os recursos existentes no departamento necessitam de cobrir; e,
Estimação da atribuição de docentes a disciplinas. Após definir-se a necessidade horária
de cada disciplina, deve atribuir-se aos docentes da distribuição todas as horas de ensino
9
existentes. Se o total de horas de ensino for superior ao total de horas da disponibilidade
lectiva dos docentes, devem ser criados novos docentes para completar as horas de ensino
em excesso.
Na próxima secção será explicado como estes objectivos de negócio estão ligados à origem das
entidades presentes no modelo de domínio da aplicação DSD.
2.3 Modelo de Domínio
Todo o software está relacionado com alguma área de interesse do seu utilizador final. Esta
área, juntamente com as entidades que a constituem, forma o domínio do software. O modelo de
domínio [FRF⁺02] de uma aplicação pode ser entendido como uma abstracção do seu domínio, onde
estão retratados os diferentes conceitos do domínio e as relações existentes entre si. A visualização
destes conceitos permite obter uma perspectiva estrutural da aplicação. Um modelo de domínio pode
ser representado através de um diagrama de classes [FS99].
A figura 2.2 apresenta o modelo de domínio da aplicação DSD sob a forma de um diagrama de
classes. Este diagrama retrata o modelo de domínio no final do TFC Fénix – Departamento. Os
diferentes padrões de cores das classes permitem distinguir as entidades directamente relacionadas
entre si. A semântica dos principais grupos de classes será explicada de seguida. A explicação
detalhada sobre o propósito de todas as entidades presentes no diagrama encontra-se em [SK06].
Figura 2.2. Modelo de domínio da aplicação DSD.
10
2.3.1 Distribuição do Serviço Docente
A classe TeacherServiceDistribution representa o processo de distribuição do serviço
docente. Contém ligações para a pessoa (Person) que criou a distribuição e os períodos de execução
(ExecutionPeriod) e o departamento para os quais se realiza a distribuição.
O controlo de acesso ao processo de distribuição é feito através das ligações entre
TeacherServiceDistribution e PersonGroup. Cada PersonGroup define um grupo de pessoas que
apresenta um privilégio sobre a distribuição, como, por exemplo, a criação de fases. A pessoa que
criou a distribuição é a única que, por omissão, tem um controlo total sobre o processo. Ela tem a
hipótese de dar e remover privilégios a outras pessoas, permitindo assim a divisão do processo de
distribuição por várias pessoas do departamento.
Uma TeacherServiceDistribution tem uma ou mais fases (ValuationPhase), sendo que, em
qualquer instante do tempo, apenas uma corresponde à fase corrente, ou seja, a fase sobre a qual o
processo de distribuição está a ser realizado.
Figura 2.3. Entidade TeacherServiceDistribution.
2.3.2 Fase
A classe ValuationPhase representa uma fase da distribuição. As fases foram criadas com dois
objectivos:
Manter um histórico do processo de distribuição. Quando se cria uma nova fase, está-se
a criar uma nova “zona de trabalho”. Todos os conteúdos alterados dentro dessa fase nunca
irão reflectir-se sobre os conteúdos das restantes fases da distribuição. Assim, a criação de
novas fases permite manter um histórico e uma salvaguarda do planeamento feito pelos
utilizadores da aplicação DSD nas fases anteriores; e,
Refinar o processo de distribuição. À medida que fica disponível mais informação, é
possível refinar o processo de distribuição com a construção de cenários cada vez mais
realistas (figura 2.4). Por exemplo, numa fase inicial pode ainda não existir a informação sobre
os novos docentes contratados pelo departamento e o número de alunos inscritos nas
disciplinas. Após essa informação ficar disponível, pode-se criar uma nova fase e comparar os
dados previstos na fase anterior com os dados reais já presentes na nova fase.
11
Figura 2.4. Visão das várias fases de um processo de distribuição do serviço docente.
As fases têm uma ordem cronológica. Uma nova distribuição é criada com uma única fase,
designada de fase inicial. A criação de uma nova fase originará uma fase posterior à fase inicial.
Devido a esta ordem cronológica, a fase inicial será a única que não apresenta uma fase anterior.
Para não se perder todo o trabalho anteriormente feito, existe a possibilidade de copiar para “dentro”
de uma fase a informação contida por uma das fases anteriores do processo de distribuição.
Uma distribuição tem sempre, pelo menos, uma fase e, de entre todas as fases da distribuição,
apenas uma tem o estado de fase corrente. Assim, em qualquer altura do tempo, existe apenas uma
fase sobre a qual o processo de distribuição do serviço docente está a ser realizado. Como se pode
observar na figura 2.5, uma fase contém um ou mais agrupamentos. A semântica dos agrupamentos
será explicada na próxima secção.
Figura 2.5. Entidade ValuationPhase.
2.3.3 Agrupamentos
A classe ValuationGrouping representa um agrupamento de docentes e disciplinas. Estes
agrupamentos são criados com o objectivo de representar as divisões existentes nos departamentos
ao nível de: 1) Secções; 2) Áreas cientificas/pedagógicas; e, 3) Grupos de competência. Desta forma,
ao realizar-se o processo de distribuição, é possível trabalhar apenas com o conjunto de disciplinas e
docentes definido num agrupamento, em vez de se trabalhar com todos os docentes e disciplinas do
12
departamento (figura 2.6). A existência dos agrupamentos também permite que se faça uma divisão
de docentes e disciplinas por campus. Por exemplo, no IST existem departamentos com
responsabilidades académicas em dois campi distintos: Alameda e Taguspark. A criação de um
agrupamento por campus permitirá efectuar o processo de distribuição sem ter em consideração
docentes de disciplinas que se encontrem ligados a outro campus.
Figura 2.6. Visão de um agrupamento de docentes e disciplinas.
Os agrupamentos estão sob a forma de árvore. Existe um agrupamento, o agrupamento raiz,
que contém todos os docentes e disciplinas do departamento. A partir do agrupamento raiz é possível
criar sub-agrupamentos (agrupamentos filho), formados por elementos contidos no
super-agrupamento (agrupamento pai). Logicamente, o agrupamento raiz é o único que não
apresenta a relação pai.
A criação de uma estrutura em árvore pretende retratar as divisões existentes nos
departamentos ao nível de secções e áreas científicas/pedagógicas. Por este motivo, quando é criada
uma nova fase, também são automaticamente criados os agrupamentos que reflectem a estrutura do
departamento associado à distribuição. A partir da informação existente no sistema Fénix, são criados
os agrupamentos que dividem os docentes por secção ou área científica e as disciplinas por área
científica ou grupo de competência. Após este passo, os utilizadores da aplicação têm a liberdade
para ajustar a árvore dos agrupamentos criada, através da criação/eliminação de agrupamentos e a
adição/remoção de elementos aos agrupamentos.
O conjunto de docentes contidos pelo agrupamento é representado por objectos da classe
ValuationTeacher e o conjunto de disciplinas por objectos da classe ValuationCompetenceCourse.
Figura 2.7. Entidade ValuationGrouping.
13
2.3.4 Docentes
A classe ValuationTeacher representa os docentes de um agrupamento. Estes docentes são
usados para cobrir as horas de ensino necessárias para todas as disciplinas presentes no processo
de distribuição.
ValuationTeacher também foi criada com o objectivo de permitir a atribuição de créditos a
docentes. Uma distribuição do serviço docente é feita com um ano lectivo (ou semestre) de
antecedência. Em muitos casos, a informação sobre os créditos só fica disponível para a aplicação
DSD no próprio período em que eles estão a ser usados. Assim, também se torna necessário atribuir
créditos aos docentes quando se sabe, de antemão, que eles terão outras responsabilidades não
lectivas.
Figura 2.8. Visão dos docentes de um agrupamento.
ValuationTeacher permite criar uma abstracção entre os docente reais e os docentes a
contratar, isto é, os docentes de identidade desconhecida que são usados para preencher as horas
vagas de ensino quando não existem mais recursos humanos disponíveis no departamento. Pela
figura 2.9 observa-se que ValuationTeacher pode ou não ter uma ligação com Teacher. Se a
ligação existir, então ValuationTeacher é tratado como um docente real. Caso contrário, trata-se de
um docente virtual (a contratar).
Independentemente do tipo de docente, existe sempre uma ligação entre ValuationTeacher e a
respectiva categoria (Category). Quando ValuationTeacher é um docente a contratar, é necessário
associar uma categoria a esse docente. Quando ValuationTeacher é um docente real, a sua
categoria podia ser obtida através da classe Teacher. Mas a categoria de um docente evolui com o
decorrer da sua carreira. Seguindo a ligação de Teacher com Category, quando o processo de
distribuição fosse consultado no futuro, seria visualizada a categoria do docente nesse momento e
não na altura em que se realizou a distribuição. Se for seguida a ligação de ValuationTeacher com
Category, já existe a garantia de que a categoria observada para um docente é igual à apresentada
na altura do processo de distribuição. Assim, consegue-se manter o estado da distribuição imutável e
coerente ao longo dos anos.
14
Figura 2.9. Entidade ValuationTeacher.
2.3.5 Disciplinas
Para suportar criação de novas disciplinas, surgiu a necessidade de introdução das classes
ValuationCompetenceCourse e ValuationCurricularCourse. Assim, adoptou-se uma estratégia
similar à adoptada no caso dos docentes. Neste caso, estas duas entidades possibilitam a criação de
uma abstracção em relação ao tipo de disciplina, real ou virtual (criada pelos utilizadores da
aplicação), com a qual as outras entidades do modelo estão a interagir.
Figura 2.10. Visão das disciplinas de um agrupamento.
As disciplinas reais são suportadas através de três classes do domínio do sistema Fénix:
CompetenceCourse. Representa uma disciplina competência, ou seja, uma disciplina que se
foca sobre uma determinada competência e é da responsabilidade de um departamento;
CurricularCourse. Representa uma disciplina curricular, ou seja, a presença de uma
disciplina competência dentro de um plano curricular de uma licenciatura; e,
ExecutionCourse. Representa a execução de uma disciplina, ou seja, a execução de uma ou
mais CurricularCourse num determinado período de execução.
As disciplinas criadas pelos utilizadores da aplicação são suportadas por outras duas entidades
do domínio do sistema Fénix:
CurricularYear. Representa o ano curricular de uma disciplina; e,
15
DegreeCurricularPlan. Representa o plano curricular em que uma disciplina se encontra
inserida.
Figura 2.11. Entidades ValuationCompetenceCourse e ValuationCurricularCourse.
2.3.6 Estimativa de disciplinas
A classe CourseValuation permite estimar o número de alunos e horas lectivas que uma
disciplina terá para um dado período de execução (figura 2.12).
Figura 2.12. Visão das estimativas de disciplinas.
As características desta estimativa são especializadas nas subclasses de CourseValuation:
CurricularCourseValuation. Representa uma estimativa para uma disciplina de uma
determinada licenciatura;
CurricularCourseValuationGroup. Representa uma estimativa para uma disciplina que está
associada a um grupo de licenciaturas; e,
CompetenceCourseValuation. Representa uma estimativa de uma disciplina a nível global,
ou seja, para todas as licenciaturas nas quais a disciplina irá ser leccionada.
A classe ValuationValueType serve para indicar o modo como cada um dos diferentes valores
da estimativa foi obtido. Cada valor pode ser obtido por uma das seguintes formas:
16
Manualmente (através do input introduzido pelos utilizadores);
Através do valor ocorrido para a disciplina no ano lectivo anterior;
Através do valor ocorrido para a disciplina no ano lectivo actual; e,
Calculado com base em outros valores (por exemplo, o número de aulas teóricas de uma
disciplina pode ser obtido através da divisão do número total de alunos pelo número máximo
de alunos por cada aula teórica).
Figura 2.13. Entidade CourseValuation.
2.3.7 Atribuição de docentes a estimativas de disciplinas
A classe ProfessorshipValuation foi criada com o objectivo de representar a afectação de
docentes a disciplinas.
Figura 2.14. Visão da atribuição de docentes a disciplinas.
Além de representar as associações entre docentes e disciplinas, ProfessorshipValuation
também permite distinguir o número de horas dispendidas por um docente por cada tipo de aula
(teórica, prática, etc.) que lecciona.
Figura 2.15. Entidade ProfessorshipValuation.
17
2.4 Problemas e Desafios
A principal limitação da aplicação DSD está relacionada com a qualidade do seu desenho. O
desenho, no seu estado actual, apresenta os seguintes problemas:
Fraca ligação entre o desenho e o domínio. Alguns componentes do desenho não se
enquadram de um modo natural e intuitivo com os demais componentes e com o próprio
domínio da aplicação. Por exemplo, dificilmente se consegue fazer a distinção entre as
entidades CurricularCourseValuation e ValuationCurricularCourse, e
CompetenceCourseValuation e ValuationCompetenceCourse. A semelhança entre as
designações das classes impossibilita que se saiba, de forma intuitiva, o conceito do domínio
que cada uma representa; torna-se necessário olhar para a implementação das classes para
se conseguir ter uma ideia dos conceitos do domínio que representam;
Sobreposição de conceitos. Existem noções do domínio que se encontram sobrepostas
dentro da mesma classe do modelo. Por exemplo, ValuationTeacher representa conceitos
diferentes (docente real e docente a contratar) consoante os valores apresentados pelos seus
atributos. Cada conceito do domínio deve estar decomposto numa unidade individual, para
que se consiga identificar facilmente qual o conceito do domínio expresso por cada classe do
modelo;
Falta de clareza conceptual. Algumas classes do modelo realizam operações que se
apresentam de uma forma pouco natural dentro da classe. Por exemplo, ValuationPhase
mantém a lógica necessária para a atribuição de docentes a disciplinas com base nos valores
do ano lectivo anterior, algo que se afasta totalmente do conceito que a classe pretende
representar. Quando uma operação é inserida dentro de uma classe de forma “forçada”, a
classe perde a sua clareza conceptual, tornando-se assim mais difícil de perceber qual o
conceito do domínio que pretende expressar. Este tipo de operações deve transitar para
dentro de novas entidades no modelo da aplicação DSD, com o objectivo de garantir-se a sua
clareza conceptual; e,
Falta de flexibilidade. A flexibilidade de um modelo define a sua capacidade para ser usado
num domínio diferente daquele para o qual foi originalmente construído. A evolução do
domínio associado à aplicação DSD revelou a falta de flexibilidade do seu modelo. Ao longo
do desenvolvimento da aplicação foi assumido que o tipo de uma aula seria teórico, prático,
teórico-prático ou laboratorial. Estes eram todos os tipos de aula possíveis de representar no
sistema Fénix, aquando do desenvolvimento da aplicação. Com a nova estrutura curricular de
Bolonha surgiram novos tipos de aula (como, por exemplo, seminários), que dificilmente se
conseguem representar com o modelo actual da aplicação. O modelo deve ser reestruturado
de maneira a que se obtenha uma solução que permita representar os tipos de aula de um
modo flexível e, ao mesmo tempo, facilmente extensível.
18
A correcção destes problemas requer que sejam feitas reestruturações ao nível do modelo de
domínio da aplicação. Alguns componentes deverão ser eliminados, outros terão de ser criados.
Relações entre componentes também serão modificadas. Assim, torna-se necessário reproduzir a
descrição de como os diferentes componentes da aplicação operaram em conjunto, ou seja, torna-se
necessário redesenhar o software.
Com a implementação do novo desenho da aplicação também surge a oportunidade para se
ultrapassarem os seguintes desafios:
Adaptação à nova estrutura curricular de Bolonha. Com a introdução do processo de
Bolonha na realidade escolar do IST ocorreram diversas alterações no modelo de domínio do
sistema Fénix, com particular incidência sobre a organização dos departamentos e disciplinas.
Uma das alterações foi, por exemplo, a associação de unidades científicas a todas as
disciplinas dos novos cursos de Bolonha. Como o desenvolvimento da aplicação DSD
coincidiu com a fase de transição, é possível que o modelo de domínio da aplicação não
esteja totalmente enquadrado com o novo domínio de Bolonha. Assim, torna-se necessário
garantir o alinhamento do modelo de domínio da aplicação com a nova organização de
departamentos e disciplinas de Bolonha; e,
Levantamento de requisitos mais extensivo. O levantamento de requisitos feito ao longo
do desenvolvimento da aplicação foi, maioritariamente, realizado com clientes ligados ao
mesmo departamento. Seria importante obter mais feedback dos restantes departamentos,
para que as funcionalidades presentes na aplicação fossem do agrado de todos os
departamentos do IST.
No próximo capítulo será feita uma exposição sobre as principais propriedades do desenho
centrado no domínio e as vantagens que este introduz para o processo de desenvolvimento de
software.
19
3 3
Desenho Centrado no Domínio
O capítulo começa por caracterizar o desenho centrado no domínio, com referência às
vantagens que este introduz para o processo de desenvolvimento de software. De seguida,
estabelece-se a ligação do desenho centrado no domínio com a noção de padrão. O capítulo termina
com a definição dos cenários nos quais se realizará a aplicação do desenho centrado no domínio.
Das diversas actividades do processo de desenvolvimento de software, o desenho corresponde
à actividade durante a qual ocorre a passagem do espaço do problema para o espaço da solução.
Quando o espaço do problema é de complexidade bastante elevada, a criação de software que
represente uma mais-valia para o negócio do seu utilizador final pode tornar-se numa tarefa
demasiado exigente. A equipa responsável pelo desenvolvimento pode ser incapaz de gerir o volume
e a complexidade de informação associados à tarefa. O desenho centrado no domínio é a ferramenta
adequada a usar para diminuir este tipo de sobrecarga. O desenho centrado no domínio pode ser
encarado como um conjunto de princípios e linhas de orientação, desenvolvidos com o objectivo de
acelerar e facilitar o processo da passagem do espaço do problema para o espaço da solução em
domínios de elevada complexidade.
Existe a noção de que a maior parte da complexidade inerente ao desenvolvimento de software
está associada a factores tecnológicos. “Qual a base de dados a ser usada, qual a linguagem de
programação que será a mais adequada…”. Contudo, esta noção não é a mais correcta. Em muitas
situações, a maior parte da complexidade reside ao nível do domínio e é sobre este nível que se deve
focar a maior parte das atenções. Na fase de desenho, quando não se lida correctamente com a
complexidade do domínio, deixa de ser relevante se a posterior estrutura tecnológica foi bem
concebida. Isto porque qualquer alteração que ocorra ao nível conceptual irá reflectir-se
obrigatoriamente ao nível do domínio. O desenho centrado no domínio contempla um conjunto de
técnicas, conceitos e linhas de orientação, explicados ao longo dos seguintes capítulos, que devem
estar presentes durante a actividade de desenho de software.
3.1 Pressupostos
O desenho centrado no domínio, apesar de não estar directamente ligado com nenhuma
metodologia de desenvolvimento de software, assume que um conjunto de práticas decorre durante o
20
ciclo de vida do projecto. As seguintes práticas apresentam-se como pressupostos para a aplicação
dos princípios do desenho centrado no domínio:
O processo de desenvolvimento de software é iterativo. O desenho centrado no domínio
não pode ser aplicado sobre uma sequência encadeada (e irreversível) de etapas. É
necessário a existência de um ciclo de desenvolvimento durante o qual se possa redesenhar
e testar novamente soluções, para que, em cada iteração, se consiga extrair um modelo mais
focado nos conceitos do domínio; e,
Existência de uma relação próxima entre a equipa de modelação do domínio e a equipa de desenvolvimento. Para o desenho centrado no domínio, o esforço que foi dispendido na
construção do modelo de domínio deve reflectir-se no produto final. Para tal, é necessária
uma estreita colaboração entre quem desenha o modelo e quem implementa o software.
Como o desenvolvimento é iterativo, esta colaboração tem de perdurar durante todo o ciclo de
vida do projecto.
3.2 Relevância do Modelo de Domínio
Todos os programas de software estão relacionados com alguma actividade ou área de
interesse do seu utilizador final. A área associada a um programa, as entidades que a constituem e
as relações existentes entre elas formam o domínio do programa. O modelo de domínio pode ser
entendido como uma abstracção do domínio, construída com o intuito de resolver problemas
associados a esse domínio. Um modelo bem definido estrutura, de forma simples e clara, toda a sua
informação em torno do respectivo domínio.
No desenho centrado no domínio, a importância do modelo de domínio pode ser medida através
de três factores fundamentais [Eva03]:
Ligação entre desenho e implementação. O modelo, o processo de desenho e a
implementação devem estar interligados. É esta ligação que torna o modelo relevante e
garante que todo o esforço que foi dispendido na construção do modelo é reflectido no
produto final. Esta ligação também é importante durante a actividade de manutenção, uma
vez que o código e restantes artefactos podem ser interpretados com base no modelo;
Comunicação. O modelo deve ser o suporte para o uso de uma linguagem comum, usada
por todos os membros da equipa. Devido à ligação existente entre o modelo e a
implementação, os membros da equipa responsáveis pela implementação podem comunicar
com os membros responsáveis pelo desenho e modelação através desta linguagem comum.
Desta forma, evita-se a necessidade da existência de algum tipo de mecanismo de “tradução”
entre os conceitos usados pelos membros das diferentes áreas da equipa de
desenvolvimento; e,
Partilha de conhecimento. O modelo pode ser visto como um acordo feito por todos os
membros da equipa, onde se escolhe uma forma de pensar sobre o domínio, à medida que se
21
definem conceitos e as relações entre eles. A linguagem comum resultante do modelo permite
uma partilha eficaz de conhecimento entre todos os elementos da equipa.
As próximas secções irão descrever com mais detalhe o significado de cada um destes factores,
o valor que produzem para um projecto de desenvolvimento de software e o modo como se
relacionam entre si. A utilização de um modelo que respeite estes factores forma uma importante
base de suporte para o desenvolvimento com sucesso de software.
3.2.1 Ligação entre Desenho e Implementação
A forma de um modelo e o propósito da sua utilização podem ser muito variados. O desenho
centrado no domínio requer que o modelo seja a entidade de suporte de todo o desenho e não
apenas um artefacto a ser usado para análise nas fases iniciais de desenvolvimento. Se o desenho,
ou uma parte dele, não tem correspondência com o modelo de domínio, então esse modelo é de
valor reduzido. Ao mesmo tempo, mapeamentos complexos existentes entre o modelo e o desenho
“ofuscam” a percepção que se tem do modelo e dificultam a gestão de alterações no desenho.
A ligação do modelo com o desenho não pode ser feita à custa de uma análise fraca ou desenho
desadequado. A análise deve capturar os conceitos fundamentais do domínio, de forma
compreensível e ao mesmo tempo expressiva. Seguidamente, o desenho deve especificar o conjunto
de componentes que irão ser construídos com as ferramentas de programação em uso no projecto e
que irão resolver de forma eficaz os desafios propostos para a aplicação. Esta abordagem exige um
modelo que contemple correctamente a análise e desenho. Quando o modelo não parece ser prático
para ser implementado ou não expressa fielmente os conceitos do domínio, então ainda não estamos
na posse do modelo certo.
Esta abordagem permite tornar o processo de modelação e desenho num ciclo iterativo.
Inicialmente, desenha-se uma parte do software de forma a elaborar um modelo de domínio óbvio e
simples. Este modelo é revisto de forma a reflectir conceitos mais profundos do domínio. À medida
que o modelo enriquece, a linguagem comum usada por todos os elementos da equipa torna-se mais
robusta.
Para ligar eficazmente o modelo e a fase de implementação, tem de existir uma correspondência
entre eles. Esta correspondência pode ser obtida através de um paradigma de modelação, que
permite a criação de analogias entre conceitos existentes no modelo e no código fonte. A
programação orientada por objectos é baseada num paradigma de modelação. Para o programador,
os objectos existem em memória e existem associações entre eles. Os objectos pertencem a classes
e o seu comportamento é caracterizado pela troca de mensagens. A grande vantagem do desenho
por objectos reside no facto do código conseguir exprimir os conceitos do modelo.
Os elementos da equipa responsáveis pelo processo de codificação devem sentir-se
responsáveis pelo modelo de domínio ou entender como o modelo irá reflectir-se na aplicação. Se tal
não acontecer, então o modelo ficará desligado do software produzido. Neste caso, a ligação entre o
22
modelo e a implementação não é obtida, uma vez que todo o esforço que foi dispendido na
elaboração do modelo não fica reflectido no produto final.
3.2.2 Comunicação
Um modelo corresponde ao conjunto de conceitos, termos e relações entre eles, definidos pelos
elementos da equipa, e que reflectem o conteúdo do domínio. Estes conceitos e relações fornecem a
semântica necessária para criar uma linguagem em torno do domínio. A via de comunicação usada
para a linguagem não pode restringir-se unicamente a diagramas, como acontece, por exemplo, com
o UML. Para ser usada de uma forma eficaz e universal, a linguagem tem de disseminar-se por várias
via de comunicação, tanto como documentos escritos, diagramas, código ou até conversas casuais
entre membros da equipa.
É frequente haver uma ruptura da linguagem usada dentro de um projecto. Os elementos
responsáveis pela modelação do domínio podem usar termos específicos da área, que, naturalmente,
diferem das expressões usadas pelos elementos responsáveis pela implementação do software.
Estas barreiras linguísticas obrigam à “tradução” de termos quando elementos de diferentes áreas
comunicam entre si. Este processo de tradução pode corromper o conteúdo inicial de uma
mensagem, impedindo uma partilha clara de conhecimento e ideias o que, inevitavelmente, irá se
reflectir na qualidade do produto final. Dos vários “dialectos” que circulam pelo projecto nenhum pode
ser usado como uma linguagem comum, uma vez que nenhum deles satisfaz os propósitos de todos
os elementos das diferentes áreas.
O modelo de domínio pode consistir na estrutura de suporte para a linguagem comum, ligando a
comunicação entre os elementos da equipa com o desenvolvimento do software. A linguagem comum [Eva03] estrutura-se à volta do modelo de domínio e deve ser o instrumento de comunicação
standard dentro do projecto. A linguagem comum será omnipresente no trabalho quotidiano da
equipa, sendo usada por todos os elementos da equipa durante todas as actividades O vocabulário
desta linguagem incluirá os nomes das classes e as operações relevantes, os termos de alto nível
impostos pelo modelo e os nomes dos padrões de desenho aplicados ao modelo de domínio. A
linguagem deverá ser usada pelos elementos da equipa ligados à implementação, para descrever
segmentos de código e suas funcionalidades, assim como por elementos ligados ao processo de
desenho, para comunicar conceitos e relações associados ao domínio. Quanto mais abrangente for o
uso da linguagem, mais rápida será a passagem de conhecimento entre todos os elementos da
equipa.
3.2.3 Partilha do conhecimento
Os elementos da equipa responsáveis pela modelação do domínio elaboram, transformam e
testam vários modelos até o sucesso ser obtido. Com o sucesso surge um conjunto de conceitos e
relações que, no todo, fazem sentido e representam o domínio. A elaboração de um modelo de
23
domínio, que represente toda a sua informação em torno da resolução do problema, tem início na
fase de modelação. Para que a fase de modelação seja concluída com sucesso, existem várias
tarefas que devem ser realizadas:
Criação de uma linguagem comum baseada no modelo. A linguagem comum deve ser
usada por todos os elementos da equipa, possibilitando uma partilha eficaz de conhecimento;
Desenvolvimento de um modelo rico em conhecimento. O modelo não deve corresponder
a um mero diagrama de objectos e conceitos. As partes constituintes do modelo devem
reflectir, de modo correcto e preciso, o comportamento e as regras que são necessários para
a resolução de problemas complexos;
Separar conhecimento acessório do conhecimento essencial. À medida que se
adicionam conceitos importantes ao modelo, este torna-se mais complexo. Assim, também é
importante eliminar conceitos que não se apresentem como sendo úteis ou centrais, de forma
a controlar a complexidade do modelo; e,
Sessões de discussão e partilha de conhecimento. A discussão de ideias, com recurso a
esboços, protótipos e outros tipos de artefactos, produz muitos resultados passíveis de serem
testados. Os resultados das sessões de debate e as experiências feitas em torno dos
conceitos do modelo, auxiliados pelo uso da linguagem comum e por um processo iterativo de
implementação, tornam possível a descoberta de um modelo rico em conhecimento. Este tipo
de acções permite transformar o conhecimento de uma equipa em modelos que constituem
uma mais valia para a resolução de problemas.
À medida que o modelo é melhorado, ele torna-se numa ferramenta de organização de toda a
informação que surge com o decorrer do projecto. Como ele está intimamente ligado com a equipa de
desenvolvimento, a percepção que estes possuem sobre o modelo e o domínio vai sendo
aprofundada, possibilitando o aparecimento de novos conceitos e relações que traduzem o problema
de um modo mais facilmente entendido por todos. Um modelo nunca está perfeito e, em muitos
casos, devidamente concluído. Um modelo pode sempre evoluir de forma a representar o domínio de
um modo mais natural e intuitivo.
3.3 Linguagens Específicas do Domínio
As linguagens de programação orientadas por objectos são a solução escolhida para a maioria
dos projectos de desenvolvimento de software. Contudo, este tipo de linguagens não foi pensado
para um domínio específico.
A relevância do modelo de domínio para o desenho centrado no domínio faz com que o modelo
seja a entidade de referência durante a fase de implementação. Para ligar eficazmente o modelo e a
implementação, terá de existir uma correspondência entre eles. O paradigma da programação
orientada por objectos nem sempre consiste na melhor solução para criar uma ligação entre os
24
conceitos existentes no modelo e no código fonte. Em alguns casos, torna-se mais vantajoso utilizar
uma linguagem baseada no domínio do problema. Assim, o código resultante da fase de
implementação pode ficar expresso na linguagem comum usada ao nível do domínio. Após o
desenvolvimento de uma linguagem baseada no domínio do problema, obtém-se uma linguagem
específica do domínio.
Uma linguagem específica do domínio [Fow04] consiste numa linguagem desenvolvida para a
resolução de problemas associados a um domínio específico. Este tipo de linguagens contrasta com
as linguagens de programação mais frequentemente usadas, como Java ou C#, na medida em que
estas são linguagens de propósito generalista, ou seja, não são orientadas para um domínio
específico. A linguagem específica do domínio foca-se em expressar de forma completa e correcta o
domínio do problema para o qual foi desenvolvida.
A utilização de uma linguagem específica do domínio tem as seguintes vantagens:
Permite que o código se expresse na linguagem comum usada ao nível do domínio do
problema. Consequentemente, qualquer pessoa com conhecimentos sobre o domínio
consegue perceber, modificar e até desenvolver um programa escrito nesta linguagem;
Código auto explicativo e sem necessidade de comentários; e,
Possibilita a validação semântica ao nível do domínio. Qualquer expressão sintacticamente
correcta pode ser validada semanticamente, com base no domínio do problema.
Como desvantagens, as linguagens específicas do domínio apresentam os seguintes aspectos:
Os custos associados ao desenho, implementação e manutenção de uma linguagem; e,
Dificuldade em definir o âmbito da linguagem. Por um lado, a linguagem deve ser
suficientemente específica para conseguir adaptar-se correctamente ao seu domínio. Por
outro lado, seria vantajoso se a linguagem tivesse generalidade suficiente para poder ser
usada em mais do que um contexto.
3.3.1 Tipos de Linguagens Específicas do Domínio
As linguagens específicas do domínio podem ser divididas em dois tipos distintos, linguagens
externas e linguagens internas [Fow05], consoante a forma como são usadas pelas aplicações:
Linguagens externas. São escritas numa linguagem distinta da usada pela aplicação.
Teoricamente, a sintaxe e o léxico deste tipo de linguagens não são limitados, o que
facilmente permite obter diversas formas para expressar um domínio. Contudo, requerem a
construção de um interpretador/compilador que faça a conversão da linguagem para um
formato executável pela aplicação (normalmente, as linguagens externas são convertidas na
linguagem original da aplicação). O XML [W3C06] é um exemplo de uma linguagem externa.
De um modo geral, o XML é usado para registar configurações de uma aplicação. A aplicação
25
acede ao ficheiro de configuração em tempo de execução, interpreta o seu conteúdo e usa-o
para determinar o seu fluxo de execução; e,
Linguagens internas. São escritas na mesma linguagem que é usada pela aplicação. Como
uma linguagem interna é desenvolvida a partir da linguagem base da aplicação, evita-se a
necessidade de construção de um interpretador/compilador, tal como é necessário para as
linguagens externas. Para ser possível desenvolver uma linguagem interna a partir de uma
linguagem base, esta tem de ter um elevado poder de expressividade, de forma a poder-se
adaptar ao domínio pretendido. O Lisp é um exemplo deste tipo de linguagens. A sua sintaxe
minimalista, juntamente com o uso de closures e macros1, permite definir, dentro da
linguagem Lisp, uma linguagem específica para um determinado domínio.
3.3.2 Exemplo de Linguagem Específica do Domínio
A seguinte situação exemplifica um possível caso de aplicabilidade de uma linguagem específica
do domínio. Considere-se um sistema que necessita de criar objectos em memória a partir de
descrições existentes num ficheiro de dados (figura 3.1). Este sistema é usado por uma empresa para
registar a informação relacionada com os seus fornecedores. Cada linha do ficheiro refere-se a um
fornecedor e a dimensão dos seus atributos varia consoante a sua categoria. A categoria do
fornecedor é indicada pelos quatro primeiros caracteres de cada linha:
#2345678901234567 CAT1SUPP12.003.50 CAT212 SUPP24.00
Figura 3.1. Exemplo do ficheiro de dados.
Neste sistema, o conhecimento da estrutura do ficheiro de dados está situado ao nível do código
fonte da aplicação, misturado com realização da tarefa de parsing2 aos conteúdos do ficheiro. Dada a
complexidade da estrutura do ficheiro de dados, seria importante traduzir essa estrutura para algum
formato que pudesse ser facilmente interpretável e editável. A solução ideal seria a criação de um
outro ficheiro, de configuração, onde estivesse definida explicitamente a estrutura do ficheiro de
dados. Esta estrutura seria “carregada” pelo sistema e usada para realizar o parsing ao ficheiro de
dados. O XML, muito utilizado em ficheiros de configuração, seria uma opção a considerar. Utilizando
esta linguagem, o ficheiro de configuração ficaria com o formatado mostrado na figura 3.2.
1 A exposição dos conceitos de closure e macro pode ser consultada em [Pau96]. 2 A noção de parsing empregue engloba as actividades de análise lexical e sintáctica [ALSU06].
26
<Configuration> <Supplier category = "CAT1"> <Field name = "Name" start = "5" end = "9"/> <Field name = "Credits" start = "10" end = "13"/> <Field name = "Debits" start = "14" end = "17"/> </Supplier> <Supplier category = "CAT2"> <Field name = "ID" start = "5" end = "8"/> <Field name = "Name" start = "9" end = "13"/> <Field name = "Debits" start = "14" end = "17"/> </Supplier> </Configuration>
Figura 3.2. Exemplo do ficheiro de configuração.
Para este caso, o XML é uma linguagem específica do domínio. Mesmo assim, podíamos optar
por uma linguagem com uma sintaxe mais legível e intuitiva para o domínio em questão (figura 3.3).
Supplier CAT1 5..9 : Name 10..13 : Credits 14..17 : Debits Supplier CAT2 5..8 : ID 9..13 : Name 14..17 : Debits
Figura 3.3. Exemplo de linguagem específica do domínio.
Com este último exemplo, foi obtida uma linguagem simples e muito expressiva no domínio para
o qual foi desenvolvida. Esta linguagem é facilmente usada para descrever a estrutura do ficheiro de
dados, mas dificilmente será usada fora desse domínio. Estas características demonstram que
estamos na presença de uma linguagem específica do domínio.
3.4 Padrões e o Desenho Centrado no Domínio
Durante esta dissertação, optou-se por adoptar o termo de princípio para fazer referência às
linhas de orientação fornecidas pelo desenho centrado no domínio. Esta noção de princípio tem uma
ligação forte com o termo padrão, frequentemente empregue durante a actividade de desenho de
software. Um padrão foi originalmente definido como “uma regra de três partes, que expressa a
relação entre um certo contexto, um problema e uma solução” [Ale79]. Este termo foi usado para
definir a noção de linguagem de padrões [Ale77], que consiste numa colecção de padrões organizada
de forma a que exista um contexto global que sirva de ligação entre a aplicação individual de cada
padrão. A ligação entre os diferentes padrões, como parte de um processo mais global, é o que
distingue a linguagem de padrões de um simples catálogo de padrões individuais. À semelhança da
27
linguagem de padrões, o desenho centrado no domínio também faz este tipo de ligação (como se
pode observar, por exemplo, na figura 4.1). A ligação é feita através de uma linha de orientação
global que tenta guiar as decisões de desenho no sentido de se obter um modelo mais focado nos
conceitos do domínio.
A um nível individual, os princípios do desenho centrado no domínio assemelham-se a padrões
de desenho. Um padrão de desenho [GHJV95] pode ser entendido como a descrição de uma
estrutura de componentes, que se apresenta como a solução para um problema genérico de desenho
ocorrido num determinado contexto. À semelhança dos padrões de desenho, os princípios do
desenho centrado no domínio possuem as seguintes características:
Descrição, uma vez que descrevem linhas de orientação para a construção de um modelo
centrado no domínio;
Problema, pois enquadram a descrição com um problema conhecido de desenho;
Solução, na medida em que descrevem a solução para o problema apresentado; e,
Contexto, pois possuem um contexto particular de aplicabilidade.
Contudo, estes princípios distanciam-se dos padrões de desenho pelo facto de focarem-se mais
sobre a semântica das entidades presentes no modelo de domínio, isto é, a maior motivação destes
princípios consiste em obter um modelo no qual os conceitos de domínio estejam expressos de forma
natural e intuitiva. Os padrões de desenho tem um foco mais técnico e não fazem a análise da
relação entre os objectos do modelo e os conceitos do domínio; tentam “apenas” descrever soluções
para problemas genéricos de desenho. Esta diferença de motivações constata-se pelo facto de
alguns princípios do desenho centrado no domínio usarem os padrões de desenho como “o meio
para atingir o fim” de obter um modelo mais próximo dos conceitos de domínio.
3.5 Aplicação do Desenho Centrado no Domínio
Os princípios do desenho centrado no domínio serão abordados nos próximos capítulos,
divididos pelos seguintes contextos:
Construção do modelo de domínio. Um modelo de domínio obtido através do desenho
centrado no domínio está assente sobre um conjunto de “blocos” (entidades, valores,
agregações, etc.) que permitem manter a implementação de software alinhada com o modelo;
Refactorização. Este processo consiste em alterar um sistema de software para que a sua
estrutura interna seja melhorada, sem modificar o seu comportamento externo. Trata-se de
um processo contínuo e pode ocorrer sempre que seja possível extrair um modelo mais
simples e focado nos conceitos do domínio; e,
28
Desenho estratégico. Orientação das decisões de desenho no sentido de reduzir-se a
interdependência entre as partes do sistema, com o objectivo de conseguir-se transmitir
facilmente, através do modelo de domínio, uma visão conceptual do core do sistema.
A descrição dos princípios do desenho centrado no domínio será estruturada da seguinte forma:
Motivação. Descrição de um problema de desenho e do contexto em que se enquadra. A
descrição fará referência a uma situação que ilustre a necessidade solucionar o problema
apresentado;
Solução; Apresentação da solução para o problema. Esta apresentação salientará as
vantagens introduzidas pela solução e o valor acrescentado na ligação do modelo com o
domínio; e,
Aplicação. Transformação do modelo de domínio da aplicação DSD de acordo com a solução
apresentada. Não será feita a transformação do modelo se: 1) A solução já fizer parte do
modelo; ou, 2) A solução for demasiado específica para ser aplicada no contexto do modelo.
Como consequência, para o primeiro caso será identificada a forma como a solução se
encontra presente no modelo. No segundo caso, será feita a descrição de um cenário
alternativo onde a solução seja aplicável.
No próximo capítulo serão abordados os princípios do desenho centrado no domínio para a
construção do modelo de domínio.
29
4 4
Construção do Modelo de Domínio
Neste capítulo definem-se os princípios sobre os quais está assente a construção de um modelo
baseado no desenho centrado no domínio. Estes fundamentos são aplicados sobre o modelo de
domínio da aplicação DSD.
Para manter a implementação de software alinhada com o modelo de domínio é necessário
aplicar as melhores práticas de desenho e modelação. Quando estas práticas não são aplicadas,
torna-se difícil obter um modelo onde os conceitos do domínio estejam expressos de forma natural e
intuitiva. Para tornar o desenho centrado no domínio resistente a este tipo de ocorrências, é
necessário ter-se um profundo conhecimento dos princípios que suportam a construção de um
modelo de domínio.
Tal como foi referido no final do capítulo anterior, a aplicação dos princípios será feita sobre o
modelo da aplicação DSD. Apesar destes princípios estarem direccionados para a construção de um
novo modelo e o modelo da aplicação DSD já se encontrar definido, será feito o exercício de
identificar os princípios dentro do modelo de domínio da aplicação e de incorporá-los, caso ainda não
estejam presentes no modelo.
Figura 4.1. Fundamentos para a construção de um modelo através do desenho centrado no domínio.
30
A figura 4.1 mostra que um modelo de domínio é construído a partir de vários “blocos”, com
diferentes propósitos:
A arquitectura em camadas permite isolar os conceitos do domínio dos restantes
componentes tecnológicos;
Os conceitos do domínio são expressos através de módulos, serviços, entidades e valores; e,
A gestão do ciclo de vida dos objectos do modelo, ou seja, a criação, o acesso e a
manutenção da integridade dos objectos, é feita a partir de fábricas, repositórios e
agregações.
Através da utilização destes “blocos”, é possível construir um modelo onde os conceitos do
domínio fiquem directamente relacionados com os objectos do modelo. Nas próximas secções deste
capítulo será feita uma abordagem individual a cada um destes “blocos”, durante a qual analisar-se-á
a motivação e a utilidade subjacente a cada “bloco” e o modo como se enquadram com a aplicação
DSD.
4.1 Arquitectura em camadas
4.1.1 Motivação
Os programas de software executam tarefas de naturezas distintas. Aceitam o input dos
utilizadores, acedem a base de dados, comunicam com máquina remotas, etc. A parte do software
especializada em resolver problemas do domínio geralmente consiste apenas numa pequena porção
da totalidade do software, apesar de ser de importância vital. É necessário separar os objectos do
domínio de outras entidades existentes no sistema, de forma a evitar confusões entre conceitos do
domínio e outros meramente tecnológicos. Se tal não acontecer, torna-se extremamente difícil fazer a
separação entre o domínio e as restantes funcionalidades do sistema. Uma simples alteração ao nível
da interface do sistema pode originar imensas alterações em todos os restantes componentes do
software.
A criação de programas que executem vários tipos de tarefas obriga a uma separação de
interesses, o que possibilita a concentração em partes isoladas do desenho. Por este motivo,
surgiram várias técnicas de isolamento do domínio.
4.1.2 Solução
Existem várias formas de fazer a separação de interesses de um sistema de software, sendo
que a mais convencional consiste na adopção de uma arquitectura em camadas [Nil06]. O princípio
essencial desta arquitectura assenta no facto de cada elemento existente numa camada depender
somente de elementos pertencentes à mesma camada ou existentes na camada inferior. Cada
31
camada especializa-se num aspecto particular do sistema de software. Esta especialização permite
um desenho mais focado de cada um dos diferentes aspectos, tornando mais simples a interpretação
do sistema como um todo. As camadas mais frequentemente representadas são as seguintes:
Camada de Apresentação. Responsável por mostrar informação ao utilizador e por gerir toda
a interacção com ele;
Camada de Aplicação. Define as tarefas que supostamente devem ser executadas pelo
software. Esta camada não contém regras de negócio, apenas coordena a execução de
tarefas, socorrendo-se dos objectos de domínio para a resolução de problemas;
Camada de Domínio. Responsável por representar os conceitos e as regras do negócio; e,
Camada de Infra-estrutura. Fornece suporte à actividade das camadas de nível superior,
como, por exemplo, através da persistência dos objectos de domínio.
Desta forma, o isolamento do domínio é atingido através da partição de um programa em
camadas. Todo o código relacionado com o domínio fica concentrado numa camada e isolado do
código responsável pela manutenção da interface, aplicação ou infra-estrutura. Os objectos de
domínio, livres de todo o tipo de operações executadas nas outras camadas, podem focar-se em
somente expressar o modelo de domínio. Ficam assim criadas as condições para que o modelo
evolua no sentido de capturar e expressar todo o conhecimento de domínio.
4.1.3 Aplicação
A aplicação DSD já apresenta uma arquitectura em camadas. Independentemente do seu
desenho, o isolamento da camada de domínio da aplicação teria de ser sempre realizado, em virtude
do contexto no qual se insere. A aplicação DSD faz parte do sistema Fénix, sendo que este já possui
uma arquitectura em camadas bem definida. Logo, a arquitectura do sistema Fénix serviu de “guião”
para a arquitectura da aplicação DSD.
Assim sendo, a arquitectura da aplicação DSD (figura 4.2) está estruturada da seguinte forma:
Camada de Apresentação. Camada superior da arquitectura. Faz o tratamento da interface a
disponibilizar ao utilizador e encaminha os seus pedidos para a camada de aplicação;
Camada de Aplicação. Camada intermédia da arquitectura global. Socorre-se da camada de
domínio para invocar os conceitos e as regras do negócio;
Camada de Domínio. Representa os conceitos e as regras do domínio. É esta camada que
permite isolar os objectos do domínio de outras entidades existentes no sistema; e,
Camada de Infra-estrutura. Camada inferior da arquitectura. É responsável por armazenar
toda a informação do domínio de forma persistente.
32
Figura 4.2. Arquitectura em camadas da aplicação DSD.
De seguida será feita uma abordagem mais detalhada ao modo como o isolamento do domínio é
garantido pela camada de domínio. A análise mais detalhada à arquitectura global da aplicação, com
referência às tecnologias envolvidas em cada camada, pode ser consultada na secção 7.2.
A estrutura da camada de domínio do sistema Fénix encontra-se descrita através da Domain
Modeling Language (DML) [CS06]. A DML consiste numa linguagem desenvolvida com o objectivo de
simplificar a especificação de classes de domínio em aplicações Java (como é o caso do sistema
Fénix). A DML permite representar aspectos estruturais do domínio (atributos de classes e relações
entre classes). Existe um compilador de DML que transforma a descrição da estrutura do domínio em
código Java, ficando toda a lógica de acesso aos atributos das classes e relações entre classes
automaticamente construída. Posteriormente, a parte comportamental do domínio é definida, ao nível
de cada classe, através de código.
A DML foi desenvolvida com um propósito bem definido, facilitar a especificação da estrutura do
domínio em aplicações Java, e é muito expressiva no domínio para o qual foi desenvolvida; trata-se,
por isso, de uma linguagem específica do domínio.
A figura 4.3 dá uma visão da separação existente entre a estrutura e o comportamento do
domínio. A transformação da descrição do domínio em código Java, através da acção do compilador
de DML, tem como resultado a definição da estrutura do domínio. Esta estrutura serve de base para
especificação do comportamento do domínio, definido pela equipa de desenvolvimento.
33
Figura 4.3. Visão da separação entre a estrutura e o comportamento do domínio.
O sistema Fénix é uma aplicação web. Neste tipo de ambientes, em que existe a execução
simultânea de vários processos, é necessário controlar o modo como cada processo acede aos
recursos do sistema; mais especificamente, é necessário gerir os acessos simultâneos a objectos do
domínio armazenados em memória (e persistidos na camada de infra-estrutura). No sistema Fénix,
esta gestão é feita através da biblioteca Java Versioned Software Transactional Memory (JVSTM)
[Cac05]. A JVSTM consiste numa implementação de um modelo de Software Transactional Memory
(STM) [ST95]. Uma STM corresponde a um mecanismo de controlo de concorrência (semelhante a
uma transacção1), que controla o acesso à memória partilhada em ambientes de computação
concorrente, (como é o caso do portal Fénix e das aplicações web). A JVSTM consegue fazer esse
controlo através do uso de Versioned Boxes2. O código necessário para a criação das Versioned
Boxes também é gerado automaticamente pelo compilador de DML.
Assim, através do uso destas tecnologias, a construção do modelo de domínio do sistema Fénix
fica automatizada em termos de: 1) Definição da estrutura do domínio (atributos de classes e relações
entre classes); 2) Garantia do isolamento3 e atomicidade4 das operações; e, 3) Gestão dos acessos à
camada de infra-estrutura. Tendo estes aspectos como garantidos, os novos desenvolvimentos feitos
sobre a camada do domínio tornam-se mais céleres e simples.
1 Execução atómica de um conjunto de instruções. 2 A explicação sobre como as Versioned Boxes formam a base de uma STM encontra-se em [CS05]. 3 Garantia de que as alterações feitas por um processo só ficam visíveis para outros processos após o seu final. 4 Garantia de que todas ou nenhuma das instruções de um processo são executadas com sucesso.
34
4.2 A expressão do modelo
4.2.1 Motivação
Considere-se a construção de um modelo de domínio para a representação de automóveis. Um
automóvel é um sistema complexo, formado por muitas peças que apresentam as mais diversas
funções. Tendo em conta este domínio, facilmente se constata que existem conceitos de diferentes
naturezas. Alguns conceitos estão associados apenas com aspectos descritivos do domínio, como
por exemplo a cor de um automóvel. A cor corresponde a uma característica e não tem qualquer
outro significado dentro do domínio senão detalhar uma propriedade dos automóveis. Outros
conceitos correspondem a entidades que devem ser univocamente identificadas dentro do modelo,
como é o caso dos motores. É necessário distinguir um motor dos demais, mesmo que existam
outros que apresentem exactamente as mesmas características, uma vez que cada automóvel possui
seu motor. Também existem conceitos que unicamente representam acções relacionadas com o
domínio, como por exemplo a acção de trocar um pneu.
Assim, durante a construção de um modelo torna-se importante identificar a natureza dos
diferentes conceitos do domínio e fazer o mapeamento destes conceitos com objectos do modelo que
respeitem as suas características.
4.2.2 Solução
4.2.2.1 Entidade e Valor
Alguns objectos devem ter uma identidade que os permite distinguir dos restantes objectos do
modelo. Tal como foi anteriormente descrito, é necessário distinguir um motor dos demais, uma vez
que cada automóvel possui seu motor. Para este tipo de objectos tem de ser possível efectuar a
distinção em relação a outros objectos que apresentem exactamente os mesmos atributos. Para ser
possível efectuar esta distinção, é necessário associar uma identidade única a este tipo de objectos.
Um objecto que é definido univocamente pela sua identidade é designado de entidade [Eva03]. As
entidades têm características próprias dentro do modelo. As responsabilidades e associações que
uma entidade possui devem ser baseadas na sua identificação e não nos valores dos seus atributos.
Existem outros tipos de objectos, com características próprias, que também têm um papel
relevante no modelo. Contudo, ao contrário das entidades, este tipo de objectos não tem uma
identidade única e o seu principal propósito consiste em representar aspectos descritivos do domínio.
Um valor [Eva03] é criado para representar os elementos do desenho que apenas se preocupam
com “o que são” e não com “quem são”. Por exemplo, de um modo geral, uma cor ou um número
correspondem a um valor. Não interessa saber qual o “vermelho” ou o “4” com o qual estamos a lidar,
apenas interessa o seu valor. Assim, quando existe uma preocupação apenas com os atributos de
um objecto, este deve ser classificado como valor. Como os valores não tem uma identidade única,
35
podem existir várias cópias do mesmo valor dentro de um sistema. Por exemplo, podem existir várias
cópias do objecto que representa o “vermelho”.
A separação entre entidade e valor (figura 4.4) pode ser obtida através do padrão de desenho
Extract Class [FBB⁺99]. Este padrão é aplicável quando estamos na presença de classes com
atributos que “desviam-se” do conceito que representam. Neste caso, os atributos não pertencentes à
classe devem ser agrupados numa nova classe e deve ser criada uma relação de associação entre
os dois elementos.
Figura 4.4. Separação entre valor (Morada) e entidade (Cliente), através do padrão Extract Class.
No exemplo da figura 4.4, a classe MoradaCliente mistura atributos de dois conceitos distintos:
morada e cliente. A separação de atributos e conceitos permitirá obter um modelo mais coerente com
o domínio. O conceito de cliente deve ter uma identidade associada; é necessário efectuar a distinção
de clientes, entre os que apresentam o mesmo nome e morada. Assim, a noção de cliente será
representado por uma entidade: Cliente. Por sua vez, os atributos relacionados com o conceito de
morada servem para dar informação mais detalhada sobre o cliente; estes atributos são agrupados
num valor: Morada.
4.2.2.2 Serviço
Existem operações do domínio que não pertencem, de um modo natural, a uma entidade ou
valor. Frequentemente, tenta-se solucionar este problema inserindo estas operações dentro de um
objecto do modelo. Visitando novamente o exemplo do modelo para a representação de automóveis,
constata-se que a acção de trocar um pneu não se enquadra de um modo natural na entidade
Automóvel ou Pneu, devido ao número de objectos do modelo necessários para realizar a operação.
Quando uma operação é inserida dentro de um objecto de forma “forçada”, este perde a sua
clareza conceptual, tornando-se assim mais difícil perceber qual o conceito do domínio expresso no
objecto. A solução para este tipo de problemas passa pela criação de um serviço. Um serviço
[Eva03] é definido como uma operação, oferecida como uma interface presente no modelo, que não
encapsula estado, ao contrário das entidades ou valores. Um serviço deve receber o seu nome com
base na actividade que vai desempenhar. Os seus parâmetros e resultado devem ser objectos do
36
domínio. Um serviço está correctamente presente dentro de um modelo se respeitar três
características fundamentais:
A sua operação relaciona-se com um conceito do domínio que não faz parte natural de uma
entidade ou valor;
A sua interface é definida com base em outros elementos do modelo; e,
A sua execução não mantém qualquer tipo de estado, ou seja, a execução de um serviço
depende exclusivamente da informação que está guardada em outros objectos do domínio.
4.2.2.3 Módulo
A semântica dos diferentes objectos do modelo leva ao seu agrupamento em módulos. Quando
se colocam objectos dentro do mesmo módulo, significa que esses objectos devem ser analisados
em conjunto. Os módulos caracterizam-se pela sua elevada coesão interna e reduzida
interdependência. A reduzida interdependência entre módulos possibilita a análise do conteúdo de
um módulo com o mínimo de referências a outras entidades externas.
Os módulos permitem obter duas perspectivas sobre o modelo: 1) Pode olhar-se para o interior
de um módulo e analisar o seu conteúdo, sem a necessidade de considerar o resto do modelo; ou, 2)
Pode observar-se as relações existentes entre módulos, de forma a analisar o modelo como um todo,
sem a necessidade de ir-se ao detalhe de cada objecto. A figura 4.5 ilustra as duas perspectivas
oferecidas pelos módulos.
Figura 4.5. Perspectiva do interior de um módulo e das relações entre módulos.
4.2.3 Aplicação
4.2.3.1 Entidade e Valor
O modelo de domínio da aplicação DSD encontra-se retratado na figura 2.2. A quase totalidade
das classes representadas correspondem a entidades, ou seja, definem objectos com uma identidade
única no sistema. Estes objectos são entidades porque existe a necessidade de distingui-los de todos
os outros objectos do mesmo tipo. Por exemplo, tem de existir uma identidade associada aos
objectos que representam os docentes da distribuição (ValuationTeacher), para que seja possível
distinguir dois docentes que apresentem o mesmo nome.
37
Além deste motivo, os objectos são entidades devido à forma como a camada de domínio está
construída. Como já foi explicado na secção 4.1.3, o código base de quase todas as classes do
domínio é automaticamente gerado pelo compilador DML. Isto implica que todos os acessos feitos à
camada de infra-estrutura sejam controlados pelo JVSTM. O uso desta solução tem outra implicação
relevante: associa uma identidade aos objectos do domínio. Todos os objectos têm o atributo
idInternal, que permite identificar ao nível da base de dados os objectos persistidos na tabela da
classe. Adicionalmente, cada tabela da base de dados tem um identificador (idClass), que varia
consoante a classe de domínio associada à tabela. Assim, o par <idClass, idInternal> cria um
identificador que permite distinguir um objecto do domínio de todos os outros, ou seja, corresponde à
identidade que permite classificar os objectos de domínio como entidades.
Existe uma parte reduzida de objectos do domínio que não tem as características apresentadas
pelos os objectos descritos no parágrafo anterior. Estes objectos não têm uma identidade definida e
são usados principalmente devido ao estado que encapsulam. Neste caso não existe a preocupação
de distinguir dois objectos que apresentem o mesmo estado. Por isso, esta minoria de objectos
corresponde aos valores. No sistema Fénix os valores não ficam persistidos numa tabela específica
para os objectos da classe. Em vez disso, os valores são armazenados como atributos das entidades.
No domínio da aplicação DSD existiam duas classes de objectos que correspondem a valores:
PersonGroup. Representa um conjunto dinâmico de pessoas. É usado ao nível dos
agrupamentos (ValuationGrouping) e da distribuição (TeacherServiceDistribution) para
representar os grupos de pessoas com permissões sobre o processo de distribuição do
serviço docente; e,
ValuationValueType. Representa os tipos possíveis de uma estimativa. É usado para definir
o tipo de estimativa com o qual se calculou a necessidade horária de uma disciplina
(CourseValuation).
4.2.3.2 Serviço
A classe ValuationPhase é a mais “longa” do domínio da aplicação DSD (no sentido de que é a
classe que apresenta mais linhas de código na sua implementação). Esta classe não representa o
conceito de domínio mais complexo, mas mantém a lógica de duas operações complexas:
Atribuição de docentes a disciplinas com base nos valores do ano lectivo anterior. Uma
das formas possíveis de atribuir horas de ensino aos docentes de uma distribuição é através
da cópia das horas de ensino apresentadas no ano lectivo anterior. Para cada docente da
distribuição (ValuationTeacher) é necessário: 1) Obter o docente (Teacher) correspondente;
2) Obter as disciplinas de execução (ExecutionCourse) leccionadas pelo Teacher no ano
anterior; 2) Verificar se a disciplina curricular (CurricularCourse) da ExecutionCourse
corresponde a alguma disciplina curricular da distribuição (CurricularCourseValuation); e,
3) Criar as relações entre ValuationTeacher e CurricularCourseValuation
(ProfessorshipValuation), consoante os vários tipos de aula leccionados pelo docente; e,
38
Cópia de uma fase. Esta acção requer que sejam copiados todos os objectos “contidos”
numa fase: o agrupamentos (ValuationGrouping), os respectivos docentes
(ValautionTeacher) e disciplinas (CourseValuation) e as atribuições de docentes a
disciplinas (ProfessorshipValuation). Estes passos não correspondem a uma simples
sequência (iterativa) de cópias, uma vez que é necessário garantir a consistência da rede de
objectos que está a ser copiada. Por exemplo, imagine-se que se está a copiar uma fase
referente a um ano lectivo passado. Então, torna-se necessário validar se os
ValuationTeacher correspondem a docentes ainda no activo e que as CourseValuation
correspondem a disciplinas que vão ocorrer no ano lectivo presente.
Estas duas operações “transcendem” a classe ValuationPhase, na medida em que a sua lógica
se foca toda sobre uma série de outras entidades do domínio (do interior e do exterior do módulo
DSD). As operações não pertencem a ValuationPhase nem a qualquer outra classe; pertencem ao
domínio da aplicação DSD e, por isso, deve estar presente no modelo sob a forma de serviços.
Assim, criaram-se dois serviços, CopyValuationPhaseService e CopyLastYearRealDataService,
para, respectivamente, a cópia de fases e atribuição de docentes a disciplinas com base nos valores
do ano lectivo anterior.
A criação destes serviços permitiu isolar as operações do domínio que não pertenciam, de um
modo natural, à classe ValuationPhase. Como consequência, conseguiu-se melhorar a clareza
conceptual apresenta pela classe.
4.2.3.3 Módulo
O domínio da aplicação DSD constitui uma pequena parte de um conjunto de dimensão muito
maior, que corresponde ao domínio do sistema Fénix [PF07]. O domínio deste sistema é composto
por mais de 1200 classes, sendo que destas apenas 22 correspondem a classes directamente
relacionadas com a aplicação. Através destes números, percebe-se facilmente a ordem de grandeza
do domínio Fénix e a necessidade de agrupar os elementos do domínio em módulos. Se o
agrupamento em módulos dos elementos do domínio não fosse realizado, a análise do modelo como
um todo seria uma tarefa de complexidade extremamente elevada. Assim, faz todo o sentido que os
objectos do domínio da aplicação DSD constituam um módulo dentro do domínio do sistema Fénix.
39
Figura 4.6. Módulo DSD e suas relações com outros módulos do sistema Fénix5.
A figura 4.6 ilustra o módulo da aplicação DSD dentro do modelo do sistema Fénix. Uma
vantagem introduzida pela criação deste módulo reside no facto de permitir analisar o domínio DSD
de forma isolada do resto do domínio Fénix. A análise das relações do módulo DSD com os outros
módulos do sistema também facilita a tarefa de análise do modelo da aplicação DSD como um todo,
uma vez que se evita a necessidade de ter de analisar individualmente cada classe.
Através da figura constata-se que o módulo DSD tem relações com outras entidades externas, o
que é natural e necessário, caso contrário o módulo estaria “desconectado” do restante domínio do
sistema Fénix. O módulo DSD relaciona-se com outras entidades distribuídas por cinco módulos:
5 Note-se que os módulos do sistema Fénix agrupam mais elementos do que os representados na figura 4.6. Com o objectivo de simplificar a figura, só se introduziram as entidades que têm uma relação directa com o módulo DSD.
40
Pessoa, para identificar as pessoas com acesso e responsabilidades sobre uma distribuição
do serviço docente;
Docência, usado para obter informação lectiva sobre os docentes;
Disciplina, onde está situada a informação sobre as disciplinas, nas suas diversas vertentes;
Departamento, onde se localiza a informação sobre as áreas científicas dos docentes, assim
como o grupo de disciplinas da responsabilidade do departamento; e,
Calendário Académico, para situar no tempo as distribuições do serviço docente.
O módulo DSD apresenta as características desejáveis para um módulo: coesão interna e
reduzida interdependência. A elevada coesão interna assegura que é possível “viajar” facilmente de
uma entidade até outra sem a necessidade de recorrer a entidades exteriores ao módulo. A reduzida
interdependência possibilita a análise do módulo com o mínimo de referências para outras entidades
externas.
4.3 Ciclo de vida de um objecto do domínio
4.3.1 Motivação
Imagine-se um modelo de domínio onde está representada a entidade Pessoa e esta tem uma
relação com o valor Morada. Surge agora a necessidade de eliminar uma instância6 de Pessoa. Será
que ao eliminá-la deve-se também eliminar o objecto de Morada correspondente? Em princípio não,
uma vez que esse valor pode estar a ser partilhado com outros objectos de Pessoa. Mas caso não
esteja a ser, ficará um valor “desligado” da entidade correspondente, o que, em último caso, resulta
em “lixo” armazenado numa base de dados.
Este tipo de reflexão pretende mostrar a complexidade associada à tarefa de manutenção de
integridade dos objectos do modelo. No cenário exposto fez-se a referência a um modelo com apenas
duas classes de objectos, mas caso este número fosse muito superior, facilmente se percebe que a
complexidade da tarefa aumentaria de forma proporcional.
Logo, se uns objectos apresentam um ciclo de vida simples, com poucas interacções desde o
momento da sua criação até à sua eliminação, outros apresentam um ciclo de vida complexo,
caracterizado pela interdependência com outros objectos. A gestão deste tipo de objectos apresenta
os seguintes desafios:
Manter a integridade durante o ciclo de vida do objecto; e,
Evitar que o modelo fique saturado com a complexidade resultante da gestão dos ciclos de
vida dos objectos. 6 Concretização de um objecto do domínio.
41
4.3.2 Solução
Existem três conceitos que podem ser usados para superar estes desafios:
Agregações. Permitem definir barreiras no modelo, evitando a existência de “redes” de
objectos;
Fábricas. Permitem criar objectos complexos e agregações, mantendo desta forma a sua
estrutura interna encapsulada; e,
Repositórios. Fornecem meios para procurar e obter objectos persistentes, encapsulando toda
a infra-estrutura envolvida no processo.
4.3.2.1 Agregação
Uma agregação [Eva03] pode ser vista como uma abstracção, criada com o objectivo de
encapsular o acesso a objectos e assim facilitar a tarefa da manutenção da sua integridade. A
agregação é formada por um conjunto de objectos, tratados como uma só unidade, e caracteriza-se
por ter uma raiz e fronteira. A fronteira define os objectos que pertencem à agregação. Por sua vez, a
raiz corresponde a uma entidade, dentro da agregação, que controla os acessos a todos os objectos
do seu interior e é a única com a qual os objectos exteriores podem comunicar. A raiz deve ter uma
identidade global, ou seja, acessível a todos os objectos do modelo. Outras entidades, que não a raíz,
devem ter uma identidade local, usada somente dentro do contexto da agregação. Os objectos
interiores à agregação podem comunicar entre si sem restrições.
Figura 4.7. Exemplo de uma agregação.
Através da figura 4.7 verifica-se que uma agregação deve corresponder a um agrupamento de
entidades e valores, com uma fronteira bem definida. A entidade raíz é a única que possui ligações
para o exterior e controla os acessos a todos os objectos do interior da agregação.
42
4.3.2.2 Fábrica
A tarefa de criação de objectos é da responsabilidade da camada de domínio. Contudo, esta
tarefa não deve ser exclusiva a cada objecto do domínio. Por vezes, é necessário a existência de
mecanismos mais abstractos para a criação de objectos, que estejam “desligados” dos próprios
objectos. Um elemento cuja responsabilidade consiste na criação de objectos é designado de fábrica
[Eva03]. Tal como a interface de um objecto encapsula a sua implementação, permitindo saber o que
faz o objecto sem revelar como o faz, uma fábrica encapsula a lógica necessária para a criação de
objectos complexos ou agregações. Esta noção de fábrica está directamente relacionada com o
padrão Abstract Factory [GHJV95], uma vez que este também tem o intuito de disponibilizar uma
interface para a criação de “famílias” de objectos dependentes.
Figura 4.8. Interacção de um cliente com uma fábrica.
Na figura 4.8 podemos observar uma fábrica em acção. A fábrica recebe um pedido de um
cliente, constrói o novo objecto de acordo com as características do pedido e devolve-o ao cliente.
Em primeira análise, pode pensar-se que o trabalho realizado pela fábrica é desnecessário e que
bastava ao cliente invocar um método construtor7 do produto para obter o novo objecto desejado.
Seguindo este cenário e caso o produto fosse um objecto complexo, como por exemplo uma
agregação, então toda a complexidade da lógica de construção deste objecto, e dos objectos
dependentes, ficaria ao nível do método construtor de produto.
Assim, além de representar um conceito do domínio, este objecto teria de se “preocupar” em
manter a lógica de criação de outros objectos do modelo. Esta sobrecarga desvirtuaria a entidade
conceptual do objecto. Esta dificuldade é ultrapassada com a utilização de uma fábrica, onde fique
encapsulada toda a lógica necessária para a criação de objectos do domínio.
4.3.2.3 Repositório
Vários dos objectos persistidos ao nível da camada de infra-estrutura devem estar disponíveis
para acesso e pesquisa (através dos seus atributos), como por exemplo a raíz de uma agregação.
Contudo, existem outros objectos que estando disponíveis para acesso a um nível global violam o
7 Método invocado para a criação de novas instâncias de uma classe.
43
encapsulamento dos objectos do domínio e das agregações. Os repositórios [Eva03] permitem
contornar este problema. Eles fornecem mecanismos para procurar e obter objectos persistentes,
encapsulando toda a infra-estrutura envolvida no processo (por exemplo, acesso a uma base de
dados através de Query Objects [FRF⁺02]). Um repositório representa todos os objectos de um
determinado tipo como uma colecção conceptual. Sobre esta colecção é possível realizar uma série
de operações, como adição ou remoção de elementos, obtenção de um elemento de acordo com
critérios de pesquisa, ou cálculo do número de elementos que satisfazem determinadas condições.
Desta forma, os repositórios constituem um mecanismo que permite separar o domínio da respectiva
infra-estrutura tecnológica que lhe dá suporte, simplificando a tarefa de gestão do ciclo de vida dos
objectos.
Figura 4.9. Interacção de um cliente com um repositório.
A figura 4.9 apresenta um repositório em acção. O repositório recebe um pedido de um cliente,
obtém o objecto de acordo com as características do pedido e devolve-o ao cliente. O acesso directo
do cliente ao objecto desejado teria de ser feito à custa da sua clareza conceptual, pois este teria que
manter a lógica de acesso ao objecto pretendido. Caso o objecto pretendido pudesse ser obtido de
várias formas distintas (pesquisa numa base de dados, ligação remota numa rede, etc.), então a
sobrecarga conceptual a suportar pelo cliente seria ainda mais significativa. Esta dificuldade é
ultrapassada com a utilização de um repositório, onde está encapsulada toda a infra-estrutura
envolvida no processo de pesquisa e obtenção de objectos do domínio.
4.3.3 Aplicação
4.3.3.1 Agregação
Uma agregação consiste numa colecção de objectos que são tratados como uma unidade, no
que diz respeito à gestão do ciclo de vida dos objectos. Esta gestão é feita pela raiz da agregação.
A definição de agregações deve ser pensada na fase de construção de um modelo. Uma vez
que o modelo de domínio da aplicação DSD já está construído, o que pode fazer-se, para já, é tentar
44
identificar-se as agregações existentes no modelo. A figura 4.10 mostra a tentativa de identificação de
agregações dentro do contexto8 DSD.
Figura 4.10. Identificação de agregações no contexto DSD.
O conceito do domínio que, de uma forma mais natural, devia corresponder a uma agregação
seria o agrupamento de docentes e disciplinas (representado por ValuationGrouping). Este conceito
representa uma colecção de objectos, mais concretamente de docentes e disciplinas, que se
encontra dependente da existência de um outro objecto: o próprio agrupamento. Assim, idealmente,
ValuationGrouping seria a raiz da agregação, onde estariam contidos todos os objectos que
representam os docentes e disciplinas.
Mas, como se pode observar na figura 4.10, existem ligações que violam a fronteira da possível
agregação. O facto de não se identificarem agregações é um indício de que existem dependências
em excesso dentro do contexto DSD, o que, por sua vez, é um alerta para a dificuldade da tarefa de
manutenção da integridade dentro do contexto.
A solução mais óbvia seria simplesmente eliminar-se as ligações assinaladas na figura 4.10,
com o intuito de obter agregações. Mas tal não pode ser feito. É necessário uma motivação mais
forte, da qual resultem alterações ao nível da estrutura do modelo. Durante o próximo capítulo, no
qual serão discutidas as alterações a realizar à estrutura interna da aplicação, tentar-se-á identificar a
agregação como resultado das alterações feitas. Se tal for possível, é sinal de que se conseguiu
reduzir as dependências existentes no interior do contexto e facilitar a tarefa de manutenção da
integridade dos respectivos objectos.
8 A noção de contexto encontra-se explicada no capítulo 6.
45
4.3.3.2 Fábrica
Na aplicação DSD, a criação de um nova fase (ValuationPhase) requer a criação de uma série
de outros objectos (ValuationTeacher, ValuationCompetenceCourse, etc.), necessários para a
construção dos agrupamentos de docentes e disciplinas (ValuationGrouping) da fase. Este fluxo de
criação é despoletado pelo método construtor de ValuationPhase e cria uma rede complexa de
objectos do domínio (figura 4.11).
Figura 4.11. Diagrama de sequência do processo de criação de uma distribuição do serviço docente.
Quando se cria uma nova fase, é necessário criar a árvore de agrupamentos e
sub-agrupamentos de docentes e disciplinas (ValuationGrouping) que retratam as divisões
existentes nos departamentos ao nível de secções, áreas científicas e grupos de competência. Como
se pode observar na figura 4.11, a lógica necessária para realizar essa tarefa é despoletada pelo
método createValuationGroupingsTree da classe ValuationPhase e “estende-se” por várias
classes do domínio. Com esta solução, toda a complexidade envolvida na construção de
agrupamentos está dependente de ValuationPhase.
Assim, além de representar um conceito do domínio (a fase de uma distribuição),
ValuationPhase tem de se “preocupar” em manter a lógica de criação de uma rede complexa de
outros objectos do domínio. Seria vantajoso usar-se o conceito de fábrica para encapsular numa
entidade toda a lógica necessária para a criação de agrupamentos e sub-agrupamentos de
disciplinas. Esta motivação revela-se suficiente para criar uma nova fábrica –
ValuationGroupingFactory – responsável pela criação de novos agrupamentos.
Uma fábrica pode ser considerada como uma especialização de serviço. Ambos realizam
operações do domínio que não se enquadram, de um modo natural, em nenhuma das classes do
46
modelo; mas as operações realizadas pelas fábricas são mais específicas: relacionam-se apenas
com a criação de objectos do domínio.
4.3.3.3 Repositório
A noção de repositório está presente no domínio DSD (e no domínio Fénix) através do objecto
rootDomainObject. Todos os objectos do domínio Fénix (que devam ter um acesso global) têm uma
associação com rootDomainObject. Para cada classe de objectos com o qual está associado,
rootDomainObject providencia os meios (gerados a partir da DML e com recurso à JVSTM) para
obter uma colecção de todos os objectos da classe e para pesquisar por uma entidade específica
através da sua identidade. rootDomainObject cria uma abstracção para o modo como se obtêm
referências para os objectos do domínio; é, por isso, um repositório.
Este repositório apresenta uma limitação: é pouco flexível na pesquisa de objectos. Para cada
tipo de objecto apenas é possível realizar duas operações: 1) Obter uma referência para uma
colecção de todos os objectos desse tipo; e, 2) Pesquisar por um objecto específico através da sua
identidade. O repositório deveria ser flexível ao ponto de, por exemplo, efectuar a pesquisa objectos
através dos valores dos seus atributos. Esta limitação foi ultrapassada com a definição de métodos
estáticos9 de pesquisa, nas próprias classes do domínio. A figura 4.12 exemplifica a pesquisa de
objectos do domínio de acordo com este cenário.
Figura 4.12. Diagrama de colaboração para a pesquisa de objectos do domínio.
Esta solução tem a vantagem de simplificar o acesso a objectos do domínio: se o objecto X
desejar uma instância de Teacher, então sabe que pode obtê-la a partir de um método da classe
Teacher. Mas, do ponto de vista do desenho centrado no domínio, esta característica apresenta-se
como uma desvantagem; a classe Teacher, além de encapsular um conceito do domínio, define a
lógica associada à pesquisa e obtenção dos seus objectos.
9 Método que se encontra situado ao nível de uma classe.
47
4.4 Conclusão
Neste capítulo definiram-se os fundamentos sobre os quais está assente a construção de um
modelo baseado no desenho centrado no domínio. Estes conceitos foram aplicados sobre o modelo
de domínio da aplicação DSD, produzindo os seguintes resultados:
Foram identificadas as diferentes camadas da aplicação, como parte da arquitectura em
camadas do sistema Fénix. Explicou-se como o isolamento dos conceitos e regras do domínio
é garantido pela camada de domínio;
Fez-se a distinção entre entidades e valores no domínio da aplicação. Concluiu-se que os
objectos que têm uma identidade única são classificados de entidades e os restantes de
valores;
Criaram-se serviços, CopyValuationPhaseService e CopyLastYearRealDataService, para
isolar as operações do domínio que não pertenciam, de um modo natural, a uma entidade ou
valor. Como consequência, conseguiu-se melhorar a clareza conceptual apresenta pelas
classes do modelo;
Identificou-se o módulo da aplicação – módulo DSD – e as suas relações com outras
entidades (distribuídas por cinco outros módulos: Pessoa, Docência, Disciplina, Departamento
e Calendário Académico);
Realizou-se a tentativa de identificação de agregações. Constatou-se que não existiam
agregações no modelo e concluiu-se que isso era sinal de que a tarefa de manutenção da
integridade dentro do modelo se estendia por todas as classes;
Criou-se uma fábrica – ValuationGroupingFactory – com o intuito de encapsular toda a
lógica necessária para a criação da estrutura de objectos associada aos agrupamentos de
docentes e disciplinas; e,
Identificou-se o repositório global do modelo de domínio da aplicação (e do sistema Fénix) e o
modo como é realizada a procura e obtenção de objectos do domínio.
48
Figura 4.13. Situação do modelo de domínio da aplicação DSD após a introdução dos princípios do desenho centrado no domínio para a construção do modelo.
A figura 4.13 mostra a situação do modelo de domínio da aplicação DSD após as modificações
introduzidas. Este novo modelo vai de encontro aos princípios do desenho centrado no domínio para
com a construção de modelos.
No próximo capítulo serão abordados os princípios do desenho centrado no domínio para o
processo de refactorização, com o objectivo de extrair um modelo mais simples e focado nos
conceitos do domínio.
49
5 5
Refactorização
Neste capítulo definem-se os princípios do desenho centrado no domínio para o processo de
refactorização. Estes princípios são aplicados sobre o modelo de domínio da aplicação DSD.
5.1 O Processo de Refactorização
A refactorização consiste “no processo de alterar um sistema de software para que a sua
estrutura interna seja melhorada, sem modificar o seu comportamento externo” [FBB⁺99]. Quando se
efectua uma refactorização está-se a melhorar o desenho de software que já foi escrito. O processo
de refactorização é contínuo e pode ocorrer desde o início do desenvolvimento de um projecto. Para
tal, existe um conjunto princípios que devem ser iterativamente aplicados, para que, em cada
iteração, seja possível extrair um modelo mais simples e claro e mais focado nos conceitos do
domínio. A figura 5.1 mostra o mapa de navegação para o processo de refactorização.
Figura 5.1. Mapa de navegação para o processo de refactorização.
50
5.1.1 Motivação
As principais motivações para o processo de refactorização são:
Simplificar o desenho da aplicação. Uma das principais motivações para a refactorização
consiste em procurar melhorar a forma como o modelo expressa o seu domínio. Quando
existe dificuldade em justificar a existência de um objecto no modelo ou quando um conceito
do domínio parece estar expresso em mais do que um objecto, é um sinal de que a
complexidade do modelo de domínio é maior do que a realmente necessária. A solução para
este problema passa pela revisão do modelo, com o intuito de tentar-se simplificar o modo
como o modelo expressa o domínio;
Facilitar a integração de novas funcionalidades. A adição de novas funcionalidades numa
aplicação obriga à revisão do seu modelo, de forma a encontrar-se uma solução que permita
acomodar os novos requisitos de uma forma flexível e ao mesmo tempo em harmonia com o
resto do modelo. Caso não se considere o impacto que as novas funcionalidades terão no
desenho e nos limitemos a transformar as funcionalidades em código, existe o perigo de
criarem-se mapeamentos complexos entre o modelo e o código e ofusca-se a clareza deste,
através, por exemplo, da duplicação de código; e,
Melhorar a legibilidade do código. Esta melhoria é feita através da identificação de
fragmentos de código “típicos” que dificultam a sua legibilidade, como a existência de
métodos demasiado longos ou código duplicado. Ao melhorar a forma como o código se
encontra escrito também se facilita a sua futura manutenção.
5.1.2 Níveis de Refactorização
De um modo geral, as refactorizações podem ser realizadas a dois níveis distintos:
Ao nível do código. A maior parte das refactorizações ao nível do código tem como principal
objectivo melhorar a sua legibilidade. Este tipo de refactorização é importante, uma vez que o
código é o principal artefacto usado na fase de implementação do processo de
desenvolvimento de software. Geralmente, a responsabilidade desta actividade é dividida por
várias pessoas, o que torna importante que qualquer pessoa consiga perceber o código
escrito por outros, sem a necessidade de realizar um grande esforço mental. Contudo,
refactorizações ao nível do código têm um impacto reduzido no desenho do software. Estas
refactorizações são guiadas pelo uso de padrões de refactorização1 [FBB⁺99, Ker04]; e,
Ao nível do desenho. As refactorizações que têm mais impacto são aquelas que originam o
redesenho de partes de um modelo de domínio. Estas alterações são mais dispendiosas do
que uma simples alteração “cosmética” ao nível do código, uma vez que obrigam a pensar
1 Padrões motivados pela simplificação da estrutura interna dos componentes de software.
51
numa nova estrutura para os objectos alterados. Contudo, este esforço extra permite obter
uma melhor ligação conceptual entre o domínio e os objectos do modelo o que,
consequentemente, simplificará a expressão do modelo através do código. Os padrões de
refactorização e os padrões de desenho podem ser usados para realizar refactorizações ao
nível do desenho.
Ao longo das próximas secções deste capítulo serão descritas várias técnicas de refactorização
associadas ao desenho centrado no domínio. Tentar-se-á aplicar estas técnicas sobre a aplicação
DSD, como forma de se obter um modelo de domínio mais simples, claro e focado nos conceitos do
domínio.
5.2 Interface reveladora de intenção
5.2.1 Motivação
Num modelo de domínio, uma classe é caracterizada através do seu nome, juntamente com os
nomes dos seus atributos e dos métodos que disponibiliza. O conjunto destes nomes define a
interface do objecto, ou seja, define a forma como ele se apresenta e comunica com as outras
entidades do domínio.
Imagine-se que a entidade Carro disponibiliza o método Acelerar. Tendo em conta esta
interface, parece que não existem dúvidas sobre os conceitos de domínio associados: Carro
representa o conceito de um automóvel e a operação Acelerar provocará um aumento da sua
velocidade. Imagine-se agora que o método, em vez de Acelerar, se designava de PregoAFundo
Neste cenário, torna-se mais difícil de entender o conceito de domínio que está ligado a esta
operação. A sua interface deixa de ser suficiente para saber-se o que é realizado pela operação.
Torna-se assim necessário olhar para o código de implementação para averiguar-se o que de facto
realiza a operação.
Se for necessário considerar a implementação de um objecto para o conseguir usar, então o
valor do conceito de domínio encapsulado no objecto foi perdido. Esta necessidade também acarreta
o risco de criarem-se diferentes interpretações para as operações realizadas pelo objecto; Após a
análise do detalhe de implementação, uma pessoa pode usar PregoAFundo convencida de que irá
aumentar a velocidade do Carro, ao mesmo tempo que outra pessoa usa a mesma operação com a
ideia de que irá diminuir a sua velocidade.
5.2.2 Solução
As classes e seus métodos e atributos devem ser nomeados de forma a descrever
correctamente os seus propósitos, sem referência aos meios através dos quais realizam as suas
actividades. Um objecto que pertença a uma classe que respeite estas características contém uma
52
interface reveladora de intenção [Eva03]. Estas características evitam a necessidade de
perceber-se a estrutura interna de um objecto, para conseguirem usá-lo. Os nomes presentes nas
interfaces dos objectos devem pertencer à linguagem comum, para que o respectivo conceito de
domínio seja facilmente inferido por qualquer pessoa.
Existem diversos padrões de refactorização que podem ser aplicados para a obtenção de
interfaces reveladoras de intenção, como é o caso do Rename Method [FBB⁺99]. De acordo com este
padrão, deve renomear-se qualquer método cujo nome não revele correctamente a sua intenção.
Esta linha de raciocínio também pode ser generalizada para o nome de classes dos seus atributos.
A figura 5.2 exemplifica a transformação de uma classe para a obtenção de uma interface
reveladora de intenção.
Figura 5.2. Exemplo de interface reveladora de intenção.
Através da figura 5.2 é possível observar-se a transformação da interface de uma classe com o
intuito desta transmitir correctamente o conhecimento de domínio. Inicialmente, Liquido tinha uma
interface confusa. O que é feito pela operação Unir? Qual o significado dos atributos v, d, t e p?
Após a transformação, já é perceptível o significado associado a cada uma das propriedades.
5.2.3 Aplicação
Esta refactorização foi aplicada em grande escala na aplicação DSD, especialmente com o
propósito de renomear as classes do seu domínio.
A classe TeacherServiceDistribution não apresenta o nome adequado, uma vez que não
corresponde ao conceito de distribuição do serviço docente. Inicialmente, pensou-se que uma
distribuição correspondia ao processo de criação de fases e estimação de valores sobre disciplinas e
docentes. Esta noção estava incorrecta. Na verdade, uma distribuição corresponde à matriz de
estimativas sobre disciplinas e docentes (que no modelo era representada por ValuationGrouping),
tal como está esquematizado na figura 2.1. Esta matriz global pode, depois, ser dividida em
subconjuntos de docentes e disciplinas, usados ao nível das fases e do próprio processo de
distribuição. Assim, de forma a corrigir a ligação dos conceitos de domínio com as entidades do
modelo, renomearam-se as seguintes entidades:
TeacherServiceDistribution, para TSDProcess;
53
ValuationPhase, para TSDProcessPhase;
CopyValuationPhaseService, para CopyTSDProcessPhaseService;
ValuationGrouping, para TeacherServiceDistribution; e,
ValuationGroupingFactory, para TeacherServiceDistributionFactory.
Além destas alterações, também foi necessário renomear as classes que continham o
prefixo/sufixo Valuation (estimativa). No fundo, a pretensão inicial deste termo era simbolizar que as
entidades estavam associadas a um processo de estimação. Por exemplo, a partir da designação
ValuationTeacher devia inferir-se que a classe representava um docente usado para efeitos de
estimação. Não obstante, o mais coerente com a linguagem comum criada em torno do domínio da
aplicação seria usar-se um termo com conotação para o processo de distribuição do serviço docente.
Por isso, optou-se por alterar o prefixo/sufixo Valuation para o prefixo TSD (acrónimo de
TeacherServiceDistribution).
Para esse efeito, renomearam-se as seguintes classes2:
ValuationTeacher, para TSDTeacher;
ProfessorshipValuation, para TSDProfessorship;
CourseValuation, para TSDCourse;
CurricularCourseValuation, para TSDCurricularCourse;
CompetenceCourseValuation, para TSDCompetenceCourse;
CurricularCourseValuationGroup, para TSDCurricularCourseGroup; e,
ValuationValueType, para TSDValueType.
Este conjunto de alterações teve um impacto grande ao nível do código. Foi necessário alterar o
nome a todos os serviços, métodos, atributos e variáveis que fizessem referência aos antigos nomes
das classes. Como todos os elementos do módulo DSD acabaram por ser renomeados, a maior parte
das linhas de código da aplicação necessitaram de algum tipo de correcção. Apesar de ser uma
tarefa morosa, o esforço dispendido na sua realização foi compensado com a obtenção de interfaces
reveladoras de intenção, o que, por sua vez, permitiu aproximar mais o desenho da aplicação DSD do
domínio correspondente.
A partir deste ponto, usar-se-ão as novas designações das classes do modelo de domínio da
aplicação DSD.
2 As renomeações de ValuationCompetenceCourse e ValuationCurricularCourse não são realizadas pois: 1) Iriam colidir com as renomeações de CompetenceCourseValuation e CurricularCourseValuation; e, 2) Estas entidades são eliminadas do modelo, de acordo com o descrito na secção 5.5.3.
54
5.3 Função sem efeitos secundários
5.3.1 Motivação
De modo geral, as classes contêm a definição de um ou mais métodos, que não são mais do
que uma sequência de instruções criada com o intuito de realizar uma tarefa específica.
Habitualmente, estas operações têm um de dois propósitos: ler ou modificar informação do domínio.
Um método de leitura pode realizar o simples acesso a um atributo de um objecto ou retornar o
resultado da computação de um algoritmo complexo. Em qualquer dos casos, após a sua execução,
todos os objectos do domínio permanecem inalterados, ou seja, mantêm o seu estado.
A execução de um método que modifica informação do domínio já provoca a alteração do
estado de um ou mais objectos. Estas alterações de estado são consequência da execução da
operação. Por isso, diz-se que uma operação desta natureza tem efeitos secundários.
Quando um método delega a realização da sua tarefa em outros métodos, na altura da sua
invocação é necessário que se esteja ciente de todos os efeitos secundários que ele poderá causar.
Caso um método OperacaoA invoque outro método, OperacaoB, e este por sua vez invoque
OperacaoC, torna-se difícil seguir o “rasto” de execução iniciado por OperacaoA. Quando o “rasto” de
execução de um método é demasiado complexo, existe o perigo de alguém invocá-lo sem estar
ciente de todos os efeitos secundários que ele irá causar.
5.3.2 Solução
Para evitar estes problemas, a lógica associada aos objectos de domínio, sempre que possível,
deve ser colocada em métodos sem efeitos secundário. Um método que não produza efeitos
secundários designa-se de função. A execução de uma função sem efeitos secundários [Eva03]
garante que não será feita qualquer alteração ao estado de um objecto. A definição de uma função
sem efeitos secundários, que se apresente através de uma interface reveladora de intenção, permite
usar um método sem ter a necessidade de considerar a forma como ele se encontra implementado.
Naturalmente, nem todos os métodos podem ser de leitura. Dentro de um programa têm de
haver operações que produzam alterações no estado dos objectos. Contudo, deve haver algum
cuidado na forma como estas operações são definidas. Uma possível norma a seguir, introduzida em
[Mey88], diz que todos métodos que produzam alterações de estado devem ser compostos por
instruções simples e não devem retornar informação do domínio.
O padrão Separate Query from Modifier [FBB⁺99] é motivado pela obtenção de funções sem
efeitos secundários. De acordo com o padrão, as operações que retornam informação do domínio
não devem alterar o estado de nenhum objecto. A figura 5.3 ilustra a aplicação deste padrão.
55
Figura 5.3. Exemplo de uma função sem efeitos secundários.
Nesta figura pode observar-se a aplicação do padrão Separate Query from Modifier sobre a
operação misturar. Inicialmente, a operação provocava uma alteração de estado num objecto do
domínio (liquidoA) e, no final, usava-o como valor de retorno. Com a aplicação do padrão
conseguiu-se eliminar os efeitos secundários da operação. Em vez de alterar o estado de um objecto,
a operação passa a criar e a retornar um novo objecto, o que permite manter o estado de liquidoA
inalterado.
5.3.3 Aplicação
Com a criação do serviço CopyTSDProcessPhaseService removeu-se um efeito secundário.
Antes da existência do serviço, a cópia de uma fase era feita através do método
copyDataFromTSDProcessPhase da classe TSDProcessPhase. Este método, em vez de retornar um
novo objecto, alterava o estado do objecto sobre o qual era feita a invocação do método (à
semelhança do exemplificado na figura 5.3). Os efeitos secundários produzidos pelo método só eram
descobertos através da análise do detalhe da sua implementação. Assim, existia o perigo de alguém
usar o método sem estar ciente dos efeitos secundários que produzia. Com a criação do serviço
CopyTSDProcessPhaseService eliminou-se este risco. O serviço retorna uma nova fase como
resultado da sua execução, não provocando a alteração de estado a objectos do domínio. Por estes
motivos, o serviço CopyTSDProcessPhaseService corresponde a uma função sem efeitos
secundários.
56
5.4 Testes de software
5.4.1 Motivação
Após qualquer refactorização, existe sempre a necessidade de assegurar que o software
continua a funcionar correctamente. Esta validação pode ser feita executando novamente a
funcionalidade do software que foi alterada com a refactorização. Seguindo esta metodologia, este
teste manual tem de ser repetido sempre que se realizar uma alteração ao nível do código.
Geralmente, a escrita de código ocupa uma fracção reduzida do tempo total da fase de
implementação de um projecto. O que tipicamente acontece é despender-se uma quantidade
significativa desse tempo a fazer-se a depuração3 do software. Em vez de se passar uma grande
quantidade de tempo à procura de erros no código, seria vantajoso encontrar uma alternativa que
permitisse usar esse tempo para realizar outro tipo de actividades, como, por exemplo, pensar em
formas de melhorar o desenho do software.
Para evitar a sobrecarga dos testes manuais e para optimizar o tempo dispendido na
implementação e no teste de um produto de software, deve adoptar-se um método que permita testar
automaticamente qualquer alteração feita ao nível do código.
5.4.2 Solução
A resolução deste problema passa pela automatização de testes de software. Um teste define
o resultado esperado da execução de uma operação. A definição deste tipo de testes torna explicita a
existência de efeitos secundários indesejados e erros, o que facilita a sua gestão.
Os testes de software devem ser executados frequentemente, algo que não sucede na maioria
dos projectos. Os testes não garantem a ausência de erros, mas asseguram que erros anteriormente
corrigidos não voltam a reaparecer. Para facilitar a tarefa de execução dos testes existem diversas
ferramentas que suportam a sua automatização, como é o caso do JUnit [GB].
O JUnit é uma object-oriented framework4 de testes unitários5. O JUnit usa o padrão de desenho
Composite [GHJV95] para permitir a criação de hierarquias de testes. A figura 5.4 mostra a
composição de uma estrutura de testes.
3 Processo de procura e eliminação de erros apresentados por um componente de software. 4 Estrutura de suporte ao desenvolvimento de software. 5 Teste para validar se fragmentos de código produzem o resultado esperado.
57
Figura 5.4. Composição de uma estrutura de testes, de acordo com o padrão Composite.
No JUnit, os testes são implementados como subclasses de TestCase. Assim, TestDomain será
a nossa classe de testes. Dentro desta classe, os testes são definidos em métodos sem parâmetros.
As condições de teste são verificadas através da operação assert. Após a realização de um método
de teste existem três resultados possíveis:
Ok, indicação de que o teste correu como esperado;
Falha, simboliza a detecção de uma falha durante a execução do teste (devido a uma
operação assert que avaliou uma condição de teste como falsa); e,
Erro, indica a ocorrência de um erro fatal durante a execução do teste.
Ainda existe a possibilidade de redefinir os métodos:
setUp, caso haja o intuito de obter recursos antes da execução dos testes; e,
tearDown, caso haja o intuito de libertar recursos no final da execução dos testes.
A figura 5.5 mostra um exemplo do código de implementação de uma classe de testes.
58
public class TestDomain extends TestCase { private Teacher _teacher;
protected void setUp() { _teacher = new Teacher("nomeDefault"); }
public void testTeacherSetName() { String expected = "nomeEsperado";
// lógica do teste _teacher.setName(expected); String result = _teacher.getName();
// verificação de resultados assertEquals(expected, result); }
}
Figura 5.5. Exemplo do código de implementação de uma classe de testes.
[FBB⁺99] explica com maior detalhe como preparar e executar testes através da framework
JUnit. Adicionalmente, nos projectos em que a informação do domínio seja armazenada numa base
de dados, existe a possibilidade do uso da framework DbUnit [DF]. O DbUnit é uma extensão do JUnit
que permite para validar o conteúdo esperado numa base de dados após a execução de um teste.
As ferramentas de teste de software (e a metodologia Extreme Programming (XP) [BA04]) estão
intimamente ligadas à origem do desenvolvimento guiado por testes [Ast03]. De acordo com esta
técnica, o desenvolvimento de software passa em primeiro lugar pela especificação de casos de teste
e, em seguida, pela escrita do código necessário para cumprir as situações de teste.
5.4.3 Aplicação
A especificação de testes unitários sobre o domínio faz parte da metodologia de trabalho no
projecto Fénix. Mas os testes não são desenvolvidos só com o intuito de identificar erros. A principal
motivação para a escrita de testes consiste em validar o cumprimento das regras do domínio.
No sistema Fénix, como o código que define a estrutura do domínio (atributos de classes e
relações entre classes) e os acessos à camada de infra-estrutura é automaticamente gerado a partir
da descrição do domínio (feita em DML), é raro ocorrerem erros ao nível das operações relacionadas
com estrutura do domínio. A maioria dos erros ocorre em operações relacionadas com
comportamento do domínio, uma vez que já são definidas “manualmente”. Assim, a escrita de testes
é feita, principalmente, para assegurar que as regras do domínio são cumpridas.
A framework de testes usada no projecto Fénix é o JUnit. Assim, as alterações feitas ao modelo
de domínio da aplicação DSD foram acompanhadas pela especificação e realização de testes, como
59
forma de validar que as regras do domínio continuam a ser cumpridas. Estes foram os principais
comportamentos testados:
Cronologia das fases. O conjunto de fases de uma distribuição forma uma lista, ordenada
cronologicamente. Quando se cria uma nova fase, é necessário garantir que ela será
colocada como o último elemento da lista; e,
Consistência dos agrupamentos de docentes e disciplinas. Um agrupamento só ter
elementos que estejam contidos no seu agrupamento pai. Assim, quando se remove um
docente ou uma disciplina de um agrupamento, é necessário assegurar que esse elemento
também é removido de todos os seus agrupamentos filho.
Na figura 5.6 pode ver-se um exemplo do pseudo código da classe de teste criada para
assegurar a consistência dos agrupamentos.
public class TestTeacherServiceDistribution extends TestCase {
private TeacherServiceDistribution _parentTSD; private TeacherServiceDistribution _childTSD; private TSDTeacher _teacher;
// construção dos agrupamentos
protected void setUp() { _parentTSD = new TeacherServiceDistribution(); _childTSD = new TeacherServiceDistribution(); _teacher = new TSDTeacher(); _parentTSD.addTSDTeacher(_teacher); _childTSD.addTSDTeacher(_teacher); _parentTSD.addChild(_childTSD); _childTSD.setParent(_parentTSD); }
// método de teste
public void testRemoveTSDTeacher() { // lógica do teste _parentTSD.removeTSDTeacher(_teacher);
// verifica se _teacher também foi removido do sub-agrupamento assertEquals(_childTSD.hasTSDTeacher(_teacher), false); }
}
Figura 5.6. Exemplo de classe de testes.
Os testes também podem desempenhar outro papel relevante dentro do contexto do projecto
Fénix. Como a equipa de desenvolvimento do projecto contém a contribuição de alunos de
licenciatura e mestrado (por períodos de um ou dois anos), após a sua saída perde-se parte do
conhecimento sobre o trabalho que desenvolveram. Se outra pessoa tiver a necessidade de proceder
a alterações no trabalho devolvido pelos os alunos, existe o perigo de se introduzir algum
comportamento incorrecto no domínio. A existência de um conjunto de testes para essa parte do
60
domínio ajuda a assegurar que as alterações feitas mantêm o comportamento esperado da lógica de
domínio.
5.5 Decomposição de conceitos
5.5.1 Motivação
Imagine-se uma classe Pessoa com os atributos nome, dataNascimento e telefone. Se não há
duvida que os dois primeiros se referem a características da pessoa, já o atributo telefone parece
estar relacionado com informação que ultrapassa as fronteiras do conceito de pessoa. E se a pessoa
tiver mais do que um número de telefone?
Provavelmente, a melhor opção para impedir que Pessoa se desvie do conceito de domínio que
representa seria mover o atributo telefone para uma classe Contacto, que teria uma relação de
associação com Pessoa. Esta classe depois poderia ser estendida para armazenar outro tipo de
atributos, como email ou morada. Assim, Pessoa deixa de conter informação sobre aquilo que já se
desvia do seu conceito de domínio.
Uma classe do modelo deve corresponder a uma abstracção de um conceito do domínio. Num
extremo, os domínios de elevada complexidade podem originar a aglomeração de conceitos dentro
da mesma classe. No outro extremo, a divisão exagerada de conceitos por vários objectos dificulta a
percepção de como todos aqueles pequenos “pedaços” funcionam em conjunto. É importante que
exista um equilíbrio entre os elementos do modelo e os conceitos do domínio que representam.
5.5.2 Solução
Os elementos de domínio (entidades, valores, agregações e serviços) devem ser decompostos
em unidades coesas, com o intuito de obter-se uma divisão que espelhe de forma correcta e
consistente as fronteiras e relações existentes entre os conceitos do domínio.
A decomposição de conceitos pode ser obtida através dos padrões Extract Method e Extract
Subclass [FBB⁺99]. De acordo com o padrão Extract Method, quando existem fragmentos de código
que podem ser agrupados, então estes devem ser isolados dentro de um novo método. Caso estes
fragmentos estejam presentes em vários métodos, então a criação do novo método permite eliminar
situações de replicação de código. Por sua vez, o padrão Extract Subclass pode ser usado quando
estamos na presença de classes com atributos usados apenas por algumas instâncias. Neste caso,
deve ser criada uma subclasse que herda as características essenciais da classe e implementa as
suas próprias características específicas (figura 5.7).
61
Figura 5.7. Decomposição de conceitos através do padrão Extract Subclass.
Neste cenário, a classe Produto continha o atributo promoção, apenas usado por produtos em
promoção. Para saber se um produto estava ou não em promoção era necessário testar o valor
desse atributo. Deste modo, Produto representava dois conceitos do domínio, consoante o valor dos
seus atributos. Uma solução mais coerente com o domínio seria criar uma especialização de produto,
ProdutoPromocional, com as suas características próprias, como o valor de promoção. Assim,
obtém-se uma solução elegante para a separação entre os conceitos produto e produto promocional.
5.5.3 Aplicação
A decomposição de conceitos foi aplicada sobre várias classes do modelo de domínio da
aplicação DSD. O primeiro caso de decomposição de conceitos tratou-se de uma situação análoga à
apresentada na figura 5.7. TSDTeacher representa dois conceitos, o docente real e o docente a
contratar, consoante apresente ou não uma ligação com Teacher. Esta sobreposição de conceitos
replica pelos métodos da classe a necessidade de se averiguar qual o tipo de docente (figura 5.8).
If(getTeacher() == null){ // código para docente a contratar ... } else { // código para docente real ... }
Figura 5.8. Exemplo da lógica presente nos métodos de TSDTeacher, como consequência da classe
representar dois conceitos do domínio.
Se, no futuro, surgir um terceiro conceito de docente, então a lógica de distinção entre docentes
ficará ainda mais complexa. Este problema foi solucionado com a decomposição de conceitos.
Criaram-se dois novos tipos de docente, TSDRealTeacher e TSDVirtualTeacher, como resultado da
especialização de TSDTeacher (figura 5.9). Assim, as noções de docente real e virtual ficam isoladas
nos respectivos objectos do domínio.
62
Figura 5.9. Decomposição de TSDTeacher.
O segundo caso de decomposição de conceitos foi feito sobre ValuationCompetenceCourse e
ValuationCurricularCourse. Estas classes criam uma abstracção em relação ao tipo das
disciplinas (reais ou criadas pelos utilizadores) que estão nos agrupamentos. Tal como no caso de
TSDTeacher, a sobreposição de conceitos existentes nestas classes origina a replicação de código
pelos métodos das classes (como ilustrado na figura 5.8). À semelhança da motivação para a criação
de TSDVirtualTeacher, o conceito de uma disciplina “virtual” (criada pelos utilizadores) deveria
consistir numa especialização de TSDCourse. Por este motivo, eliminaram-se as classes
ValuationCompetenceCourse e ValuationCurricularCourse do modelo e definiu-se o conceito de
disciplina “virtual” numa nova subclasse de TSDCourse: TSDVirtualCourseGroup (figura 5.10).
Figura 5.10. Criação de TSDVirtualCourseGroup.
O terceiro caso de decomposição de conceitos foi feito sobre TSDCourse. Nesta classe
guardava-se a informação sobre estimativas feitas, para quatro tipos de aula: teóricas, práticas,
teórico-práticas e laboratoriais. Esta variedade de tipos de aula originou a multiplicação de métodos
semelhantes (figura 5.11).
public Integer getTotalNumberOfTheoreticalStudents(){ ... } public Integer getTotalNumberOfPraticalStudents(){ ... } public Integer getTotalNumberOfTheoPratStudents(){ ... } public Integer getTotalNumberOfLaboratorialStudents(){ ... }
Figura 5.11. Exemplo da multiplicação de métodos pelo tipo de aula existentes.
63
Para evitar esta multiplicação de código criou-se uma nova classe, TSDCurricularLoad, que
representa a carga curricular de um tipo de aula para a disciplina. Com a introdução desta classe e a
aplicação do padrão Parameterize Method [FBB⁺99] foi possível reduzir o número de métodos
existentes, através da criação de métodos parametrizados (figura 5.12).
public Integer getTotalNumberOfStudentsPerShiftType(ShiftType shiftType){ ... }
Figura 5.12. Aplicação do padrão Parameterize Method para a criação de métodos parametrizados.
Com esta alteração também se resolveu uma das limitações inicialmente detectadas na
aplicação: o facto de não permitir representar os novos tipos de aula de Bolonha. A solução adoptada
aumenta a flexibilidade apresentada pelo modelo, uma vez que para a criação de um novo tipo de
aula basta criar uma relação de TSDCourse com um novo tipo de TSDCurricularLoad (figura 5.13).
Figura 5.13. Decomposição de TSDCourse.
5.6 Classes independentes
5.6.1 Motivação
Dentro de um modelo de domínio, os objectos estão ligados entre si. Cada associação que um
objecto tem representa uma dependência. Imagine-se uma ClasseA com uma ligação com ClasseB.
Quando se faz a análise da semântica associada à ClasseA é necessário ter em consideração o
contexto que o rodeia, que neste caso consiste na relação com ClasseB. Se ClasseA também estiver
associado com uma ClasseC, é mais um elemento que tem de ser tido em conta no momento da
análise.
Um modelo pode tornar-se de difícil interpretação, à medida que o número de dependências
entre objectos aumenta. Com dependências em excesso, o esforço mental necessário para a
compreensão do modelo pode ser demasiado para ser atingido.
64
5.6.2 Solução
É importante que existam classes independentes [Eva03], isto é, classes que apresentam
pouca (ou nenhuma) dependência em relação a outras. Esta independência entre classes é a
característica que possibilita reduzir a sobrecarga de relações conceptuais num modelo. As classes
independentes podem ser estudadas e testadas independentemente, uma vez que se apresentam
com quase total autonomia em relação ao resto do modelo.
Um modelo deve ser analisado de forma a eliminar todas as dependências que não se provem
como essenciais, com o objectivo de identificar-se o maior número possível de classes
independentes. Contudo, a eliminação de dependências não deve ser levada ao extremo tal de limitar
todas as interfaces entre classes distintas. A redução de dependências deve permitir, ao mesmo
tempo, manter a riqueza e expressividade das interfaces entre classes.
A identificação de agregações é uma tarefa que ajuda a obter classes independentes, uma vez
que as agregações evitam a existência de “redes” de objectos. Quando se obtém uma agregação a
partir de um conjunto de objectos, existe a garantia de que os elementos dentro da fronteira apenas
se encontram ligados entre si. Este resultado permite eliminar a interdependência destes objectos
com o resto do sistema.
5.6.3 Aplicação
A classe com o maior número de dependências no modelo é TeacherServiceDistribution, o
que acaba por ser natural, uma vez que representa o conceito principal do domínio, a distribuição do
serviço docente, em torno do qual os outros conceitos se relacionam entre si. As classes mais
“periféricas” já apresentam um menor número de ligações. Com as transformações feitas no modelo
até este ponto, obtiveram-se algumas classes com muito poucas dependências, especialmente:
TSDCurricularLoad, apenas usada por TSDCourse; e,
TSDTeacher e suas subclasses, que, no global, apenas dependem de Category e Teacher.
Devido às características que estas classes apresentam, podem ser classificadas como classes
independentes.
As classes independentes foram obtidas através da aplicação de outros princípios do desenho
centrado no domínio, principalmente devido às transformações introduzidas pela decomposição de
conceitos. Estas transformações contribuiriam para a eliminação de relações “fracas” do modelo, o
que possibilitou o aparecimento das classes independentes.
65
5.7 Conclusão
Neste capítulo definiram-se os princípios do desenho centrado no domínio para o processo de
refactorização, que têm como principal objectivo extrair um modelo mais simples, claro e focado nos
conceitos do domínio. Estes princípios foram aplicados sobre o modelo de domínio da aplicação
DSD, produzindo os seguintes resultados:
Renomearam-se todas as classes do módulo da aplicação (o que, por sua vez, implicou a
renomeação da maior parte dos métodos e atributos), como forma de obter interfaces
reveladoras da intenção. Este conjunto de alterações permitiu fortalecer a ligação entro o
desenho da aplicação e o domínio correspondente;
Identificaram-se as funções sem efeitos secundários criadas. A definição de uma função sem
efeitos secundários, que se apresente através de uma interface reveladora de intenção, tem a
vantagem de permitir usar o método sem a necessidade de se considerar a forma como ele
se encontra implementado, uma vez que existe a garantia que não serão produzidos
quaisquer efeitos secundários;
Definiram-se testes de software para a aplicação. As alterações feitas sobre o modelo de
domínio da aplicação DSD foram acompanhadas pela definição e realização de testes, como
forma de validar que as regras do domínio continuam a ser cumpridas;
Utilizou-se a decomposição de conceitos para fazer a separação entre os conceitos de
docente/disciplina real e virtual (criado pelos utilizadores da aplicação) e extrair o conceito de
carga curricular do “interior” de disciplina. Com estas transformações conseguiu-se eliminar a
sobreposição de conceitos e aumentar a flexibilidade apresentada pelo modelo; e,
Identificaram-se as classes independentes existentes no modelo, como resultado do trabalho
desenvolvido até ao momento. A identificação de classes com estas características permitiu
concluir que não existem dependências excessivas no modelo.
A figura 5.14 mostra a situação do modelo de domínio da aplicação após as modificações
introduzidas.
66
Figura 5.14. Modelo de domínio da aplicação DSD após a introdução dos princípios do desenho centrado no domínio para o processo de refactorização.
Com as alterações introduzidas, o modelo de domínio da aplicação DSD vai de encontro aos
princípios do desenho centrado no domínio para com o processo de refactorização. Mas este
processo nunca pode ser dado como concluído. Um modelo pode sempre evoluir de forma a
representar o seu domínio de uma forma mais natural e intuitiva.
No próximo capítulo serão discutidos os princípios do desenho centrado no domínio associados
ao desenho estratégico.
67
6 6
Desenho Estratégico
Neste capítulo definem-se os princípios do desenho centrado no domínio associados ao
desenho estratégico. Ao contrário dos capítulos anteriores, a aplicação dos princípios apresentados
neste capítulo não será centrada sobre o “interior” do modelo de domínio da aplicação DSD. Isto
porque os princípios associados ao desenho estratégico são orientados para os sistemas como um
todo. A aplicação DSD é desenvolvida como parte de um sistema de maior dimensão: o sistema
Fénix. Como tal, através dos princípios apresentados neste capítulo, tentar-se-á caracterizar o
“espaço” ocupado pelo domínio da aplicação DSD dentro do domínio do sistema Fénix.
O desenho estratégico [Eva03] pretende orientar as decisões de desenho em sistemas
complexos, de grande dimensão e que geralmente apresentam interacções com outros sistemas
externos.
Os princípios associados ao desenho estratégico orientam as decisões de desenho no sentido
de reduzir-se a interdependência entre as partes do sistema, com o objectivo final de se conseguir
facilmente transmitir, através do modelo de domínio, uma visão conceptual do core do sistema. De
forma a serem atingidos estes objectivos, o desenho estratégico aborda três grandes temas:
Integridade do modelo. Pretende obter um modelo de domínio coerente, sem a definição de
conceitos e relações contraditórias;
Destilação. A palavra destilação define o processo de separar os componentes de uma
mistura de forma a extrair a essência numa estado que a torne mais útil. No desenho
centrado no domínio, a destilação define um conceito análogo: reduzir a atenção que se dá a
aspectos “periféricos” do domínio, para que se foquem as atenções sobre o seu essencial; e,
Estrutura de grande escala. Com a integridade do modelo e a destilação consegue-se focar
as atenções sobre o núcleo do domínio, ao mesmo tempo que se isolam conceitos e relações
de suporte. Por vezes, para se ter uma percepção do que o sistema faz como um todo, não
basta olhar para o core do domínio. Também é necessário ter em conta os conceitos e
relações de suporte que o rodeiam. A estrutura de grande escala é uma linguagem que
discute e dá a entender o papel desempenhado por cada parte, dentro do sistema como um
todo. Os seus princípios permitem tomar decisões de desenho que ajudam a perspectivar a
forma como o trabalho realizado em diferentes contextos se relaciona entre si.
68
A destilação e a estrutura de grande escala focam-se sobre decisões de desenho que afectam
um sistema como um todo. Tendo em conta a posição da aplicação DSD, que faz parte (e, por isso,
se encontra dependente) de um sistema de maior dimensão, torna-se difícil aplicar os princípios
relacionados com estes temas. Assim, os princípios abordados ao longo das próximas secções deste
capítulo estão relacionados com o tema da integridade do modelo.
6.1 Integridade do modelo
A integridade é um dos principais requisitos para um modelo, no sentido em que este deve ser
composto por um conjunto consistente de conceitos e relações, sem a existência de regras
contraditórias.
Os projectos de grande dimensão aumentam as probabilidades de quebra da integridade do
modelo. Imagine-se o caso de um modelo, de grande dimensão, que contém a entidade Docente.
Alguém, com conhecimento pouco profundo sobre o domínio, necessita de criar uma entidade para
representar o conceito de “pessoa responsável pelo ensino” e, por isso, cria a entidade Professor.
Mas Docente já pretendia representar esse conceito. Assim, ficam definidas duas entidades
associadas ao mesmo conceito, o que resulta na quebra de consistência no modelo.
A tarefa de manutenção de integridade em modelos de grande dimensão é difícil de realizar. O
elevado número de entidades e relações existentes dificulta a identificação de conceitos
contraditórios. Este problema pode ser minimizado com a separação do domínio por vários modelos.
O core do sistema fica representado em um ou mais modelos unificados1. Os restantes componentes
ficam isolados em modelos distintos, de forma a não corromperem a visão conceptual dada pelos
outros conceitos.
Os princípios do desenho estratégico que estabelecem e comunicam os limites de um modelo
são apresentados na figura 6.1 e serão debatidos ao longo das próximas secções do capítulo.
Figura 6.1. Princípios para a manutenção da integridade do modelo.
1 Modelo consistente, no sentido de que não contém conceitos nem relações contraditórios.
69
6.1.1 Contexto
6.1.1.1 Motivação
Em projectos de grande dimensão, implementados por várias equipas de desenvolvimento, é
natural que existam vários modelos. Esta situação não é problemática quando os modelos se aplicam
em contextos completamente distintos, como no caso em que cada equipa desenvolve um
componente distinto de software. Agora, quando várias equipas trabalharam em partes comuns do
mesmo software podem surgir problemas.
A existência de vários modelos durante o desenvolvimento de um componente de software
requer a existência de comunicação constante e de uma boa organização entre as equipas afectas a
cada modelo. Mas, por vezes, a comunicação entre equipas pode tornar-se confusa, especialmente
quando se juntam noções de modelos distintos dentro do mesmo contexto. Quando tal acontece,
dificilmente se obterão os resultados previstos a partir da fusão do trabalho produzido por todas as
equipas. O não funcionamento do produto final de software é o culminar de uma série de erros feitos
ao nível do relacionamento entre as várias equipas.
6.1.1.2 Solução
Um contexto [Eva03] define o limite de aplicabilidade de um modelo. Todos os modelos devem
ter um contexto com as fronteiras bem definidas, em termos da organização da equipa, do domínio
envolvido e dos artefactos a ser produzidos (ao nível do código, tabelas de base de dados, etc.).
Dentro do contexto o modelo deve estar unificado e não deve haver preocupações com o que se
passa para lá da sua fronteira. Noutros contextos outros modelos aplicam-se, com outro conjunto de
conceitos e, possivelmente, até com outro “dialecto” da linguagem comum. Um contexto assegura a
integridade do seu modelo e evita a ocorrência de interferências com os acontecimentos ocorridos
fora da sua fronteira.
Um contexto assemelha-se a um módulo, na medida em que ambos expressam uma divisão do
domínio. Mas estes princípios têm âmbitos diferentes. Os módulos expressam a organização dos
elementos dentro de um modelo; não fazem qualquer tipo de compromisso em relação à equipa
responsável pela sua implementação e aos artefactos que dará origem. Para obter um contexto já é
necessário fazer essas avaliações, uma vez que se pretende eliminar as dependências entre o
trabalho realizado por várias equipas.
6.1.1.3 Aplicação
No sistema Fénix existe um modelo de domínio e uma equipa de desenvolvimento. Assim, em
primeira análise, a um nível global, existe um contexto. Mas o modelo do sistema Fénix é de grande
dimensão. Na prática, a maioria das tarefas são realizadas sobre uma zona específica do modelo e
com recurso a uma sub equipa composta por um ou dois elementos. Esta redução de âmbito é feita
com o intuito de se criar um contexto: criar uma zona de trabalho bem definida em termos da
organização da equipa, do domínio envolvido e dos artefactos a serem produzidos. Por estes
70
motivos, pode afirmar-se que o trabalho realizado sobre o domínio Fénix é feito através da criação de
vários contextos.
O módulo da aplicação DSD corresponde a um contexto: o contexto DSD. As suas fronteiras
estão bem definidas em termos de domínio envolvido (figura 6.2) e da organização da equipa.
Figura 6.2. Modelo de domínio do contexto DSD.
Através da figura 6.2, já é possível identificar TeacherServiceDistribution como a raiz de
uma agregação. As transformações realizadas no capítulo anterior resultaram na eliminação das
dependências que impossibilitavam a identificação da agregação, tal como explicado na secção
4.3.3.1.
Caso se considere que o domínio envolvente do contexto DSD é composto por outros contextos,
então o contexto DSD possui dependências para os seguintes contextos:
Pessoa, para obter informação pessoal sobre os docentes;
Disciplina, para obter informação curricular sobre as disciplinas;
Docência, usado para obter informação lectiva sobre os docentes;
Departamento, para localizar a informação sobre as áreas científicas de docentes e
disciplinas; e,
Calendário Académico, para situar no tempo as distribuições do serviço docente.
A forma como o contexto DSD se relaciona com os outros contextos e o modo como as
dependências entre contextos são comunicadas por toda a equipa serão analisados em mais detalhe
nas próximas secções.
71
6.1.2 Integração
6.1.2.1 Motivação
Quando várias pessoas trabalham dentro do mesmo contexto, a falta de comunicação (e
organização) dentro da equipa pode originar situações problemáticas:
Cada pessoa pode começar a desenvolver noções conceptuais próprias, ficando este
conhecimento isolado dos restantes elementos da equipa. À medida que a dimensão da
equipa aumenta, este problema pode agravar-se; e,
Diferentes pessoas podem ter diferentes noções conceptuais que, na realidade, representam
o mesmo conceito. Esta duplicação de conceitos é visível quando é necessário efectuar
alterações em duas entidades diferentes do modelo, sempre que surge uma alteração
relacionada com um conceito.
Quando este tipo de situações ocorre é um sinal de que o modelo está fragmentado.
6.1.2.2 Solução
Para evitar a ocorrência deste tipo de situações, deve ser instituído um processo de integração
em todos os contextos usados na implementação do projecto. A integração [Eva03] é um processo
realizado a dois níveis:
Ao nível do modelo, através da promoção de uma visão comum (partilhada por todas as
equipas) sobre o domínio e da extracção dos conceitos envolvidos para a linguagem comum;
e,
Ao nível da implementação, através da sistematização da fusão de código e realização de
testes, de forma a detectar fragmentações ao nível do modelo.
A integração dos conceitos de domínio facilita a posterior integração do código. Por sua vez, a
integração do código valida a consistência dos conceitos de domínio e expõe a fragmentação do
modelo. A integração deve ser executada frequentemente, para que os conceitos presentes na mente
de cada pessoa transitem para a linguagem comum.
6.1.2.3 Aplicação
Neste momento, o modelo de domínio do sistema Fénix está a ser documentado com o objectivo
de simplificar a transmissão de conhecimento entre todas pessoas envolvidas no processo de
desenvolvimento (a documentação do modelo está disponível em [PF07]). Assim, o primeiro passo do
processo de integração (promover uma visão comum sobre o domínio) foi atingido com a
documentação do contexto DSD. O segundo passo (validar a consistência dessa visão do domínio)
foi feito através da especificação de testes de software, como explicado na secção 5.4.3.
72
Com a integração do contexto DSD assegura-se que o seu domínio é do conhecimento de todos
e que o mesmo se encontra consistente dentro das fronteiras do contexto.
6.1.3 Mapa de Contextos
6.1.3.1 Motivação
Geralmente existem pontos de ligação entre contextos. Estes pontos de ligação definem os
contactos que existem entre contextos e, assim, permitem obter uma visão global do sistema.
Contudo, quando existem muitos contextos dentro do mesmo projecto, pode tornar-se difícil ter uma
visão global do modo como os eles se relacionam. Se as pessoas tiverem uma fraca noção das
fronteiras e dos seus pontos de ligação entre contextos, podem ocorrer situações em que os limites
dos contextos sejam violados.
6.1.3.2 Solução
De forma a evitar este problema, deve-se começar por identificar e definir os limites de cada
contexto, assim como os pontos de ligação entre eles. Para que o conhecimento sobre os pontos de
ligação entre contextos fique acessível a todos deve-se criar um mapa de contextos [Eva03].
Não existe um formato predefinido para o mapa de contextos. Ele pode apresentar-se sobre a
forma de um diagrama, um quadro, um documento escrito ou ser discutido numa reunião. O
importante é que o mapa de contexto seja acordado e do conhecimento de todos.
6.1.3.3 Aplicação
O contexto DSD apresenta pontos de ligação para cinco contextos: Pessoa, Disciplina,
Docência, Departamento e Calendário Académico. O quadro 6.1 mostra os pontos de ligação do
contexto DSD.
Contexto de origem
Entidade origem Contexto de destino
Entidade destino
DSD TSDRealTeacher Docência Teacher DSD TSDTeacher Docência Teacher DSD TSDCompetenceCourse Disciplina CompetenceCourse DSD TSDCurricularCourse Disciplina CurricularCourse DSD TSDVirtualCourseGroup Disciplina CurricularYear DSD TSDVirtualCourseGroup Disciplina DegreeCurricularPlan DSD TSDProcess Departamento Department DSD TSDProcess Calendário
Académico ExecutionPeriod
DSD PersonGroup Pessoa Person
Quadro 6.1. Mapa de contextos DSD.
73
Através do quadro pode observar-se as ligações do contexto DSD. Se o quadro fosse
completado com a informação sobre todas as ligações entre os contextos do sistema Fénix e fosse
depois divulgado para toda a equipa, então representaria o mapa de contextos do sistema Fénix.
6.1.4 Núcleo partilhado
6.1.4.1 Motivação
Imagine-se duas equipas a trabalhar sobre o mesmo contexto. As duas equipas estão
fisicamente separadas e comunicam entre si com pouca frequência. Esta falta de comunicação faz
com que o trabalho das equipas seja feito de forma descoordenada, com cada equipa a tomar
decisões unilaterais sobre o desenho do modelo. A divisão do contexto em dois contextos não se
apresenta como solução, devido às dependências entre os elementos do modelo. Se as equipas
continuarem a trabalhar assim até ao final do projecto, será necessário realizar um esforço extra para
fundir o trabalho desenvolvido por cada equipa.
6.1.4.2 Solução
Para resolver este tipo de problema, deve ser definido, por todas as equipas envolvidas no
trabalho, um subconjunto do modelo. Este subconjunto constitui o núcleo partilhado [Eva03]; forma
a base de trabalho que é partilhada pelas diferentes equipas. Cada equipa tem a liberdade para
estender o núcleo partilhado e criar o seu próprio contexto, no qual realizar o seu trabalho de uma
forma independente. Contudo, qualquer alteração ao núcleo partilhado terá de ser aprovada por todas
as equipas. O trabalho desenvolvido por cada equipa reflectir-se-á no modelo de acordo com o
processo de integração. O núcleo partilhado visa reduzir a duplicação de esforços e tornar a
integração entre dois subsistemas mais fácil de realizar.
Figura 6.3. Acção do contexto, mapa de contextos e núcleo partilhado.
74
A figura 6.3 dá uma visão do modo como as noções de contexto, mapa de contextos e núcleo
partilhado se relacionam entre si. Enquanto que o contexto define o limite de aplicabilidade de um
modelo, o mapa de contextos dá uma visão global de todos os contextos existentes no projecto e as
relações entre eles. O núcleo partilhado constitui a base comum de trabalho entre diferentes
contextos. O processo de integração é responsável pela preservação da unidade do modelo dentro
de cada contexto e promoção de uma visão comum sobre todos os contextos do projecto.
6.1.4.3 Aplicação
O núcleo partilhado permite formar uma base de trabalho comum para diferentes
pessoas/equipas que trabalham sobre o mesmo contexto. Nenhum desses cenários aconteceu
durante os desenvolvimentos feitos sobre a aplicação DSD (foram feitos só por uma pessoa). Por
este motivo, o núcleo partilhado não pode ser aplicado ao contexto DSD.
Caso a equipa associada ao contexto DSD fosse formada por dois elementos, já seria possível
criar um cenário de aplicação para o núcleo partilhado. Imagine-se que era necessário fazer
desenvolvimentos relacionados com a gestão de docentes (TSDTeacher) e de disciplinas
(TSDCourse). Nesse caso, fazia sentido definir-se um núcleo partilhado formado pela entidade central,
TeacherServiceDistribution, e criar dois novos (sub) contextos. Cada elemento da equipa
trabalharia no seu contexto e, no final, através do processo de integração, agrupavam o trabalho feito
novamente no contexto DSD. Esta táctica de divisão de tarefas a partir de uma base comum é
frequentemente usada em equipas de desenvolvimento de software.
6.1.5 Separação de interesses
6.1.5.1 Motivação
Por vezes, em sistemas de grande dimensão existem equipas que desenvolvem funcionalidades
que são independentes do resto do sistema. A integração dessas funcionalidades não introduz
nenhuma vantagem significativa para o projecto, uma vez que existe uma separação clara entre os
conceitos do sistema e os conceitos das funcionalidades.
6.1.5.2 Solução
Para estes casos, devem ser definido um contexto independente (sem pontos de ligação), que
permita a uma equipa encontrar soluções simples e independentes do caminho seguido por outras
equipas e respectivos contextos.
A separação de interesses [Eva03] tem a vantagem de permitir o desenvolvimento e teste de
novas soluções num contexto totalmente isolado. Contudo, torna-se uma tarefa complicada integrar
um modelo desenvolvido de forma independente com outros modelos.
75
6.1.5.3 Aplicação
A separação de interesses permite criar contextos isolados do trabalho realizado por outras
equipas e em outros contextos. Tendo em conta estas características, identificaram-se dois cenários
possíveis para o uso da separação de interesses:
Desenvolvimento e teste de novas soluções de forma isolada; e,
Isolamento de partes do domínio que se encontram em desuso.
O primeiro cenário não pode ser usado pela aplicação DSD. O contexto DSD tem um conjunto
de ligações para outros contextos, tal como foi apresentado através do mapa de contextos. Estas
ligações estabelecem dependências para o funcionamento da aplicação; TSDRealTeacher não
funciona sem Teacher. Devido a esta dependência, a separação de interesses não pode ser usada
para o desenvolvimento e teste da aplicação DSD num contexto isolado. Se o contexto DSD não
apresentasse dependências, já seria possível usar a separação de interesses para este primeiro
cenário.
No caso do segundo cenário, a separação de interesses poderia ser usada para isolar a parte do
domínio do sistema Fénix que se encontra em desuso. Existem entidades no modelo do sistema
Fénix que já não devem ser usadas, como por exemplo a antiga estrutura curricular das disciplinas
(antes de Bolonha). Estas entidades podiam ser agrupadas em contextos isolados (que depois seriam
apresentados a toda a equipa), de forma a criar-se uma visão global sobre as partes do domínio que
já não deviam ser usadas.
6.1.6 Conclusão
Os princípios associados ao desenho estratégico orientam as decisões de desenho, em
projectos de grandes dimensão, no sentido de reduzir-se a interdependência entre as partes do
sistema e com o objectivo de conseguir-se transmitir facilmente, através do modelo de domínio, uma
visão conceptual do core do sistema. A integridade do modelo é um dos temas abordados pelo
desenho estratégico, como forma de estabelecer e comunicar os limites de um modelo (e das suas
relações com outros modelos do sistema).
A aplicação dos princípios do desenho estratégico para a integridade do modelo produziu os
seguintes resultados:
Definiu-se o limite de aplicabilidade do modelo de domínio da aplicação DSD através da
criação do contexto DSD;
Produziu-se um mapa de contextos com o objectivo de comunicar uma visão global das
relações do contexto DSD com outros contextos;
76
Realizou-se a integração como forma de: 1) Promover uma visão comum sobre o contexto
DSD; e, 2) Preservar a unidade do modelo associado ao contexto. O primeiro objectivo foi
atingido através da documentação do modelo associado ao contexto DSD. O segundo
objectivo foi atingido com a especificação de testes de software para esse modelo;
Identificou-se a utilidade do núcleo partilhado para a construção de uma base comum de
trabalho entre diferentes contextos; e,
Identificaram-se situações em que a separação de interesses permitiria criar um contexto
para: 1) Desenvolver e testar novas soluções de forma isolada; e, 2) Isolar partes do domínio
que se encontram em desuso.
O próximo capítulo descreve o processo de implementação do novo desenho da aplicação DSD.
77
7 7
Implementação
Este capítulo descreve a metodologia seguida durante o processo de implementação do novo
desenho da aplicação DSD e as principais tecnologias presentes na solução.
7.1 Metodologia
A implementação da nova versão do desenho da aplicação foi feita de acordo com um processo
de desenvolvimento de software iterativo. Esta abordagem permitiu criar um ciclo de
desenvolvimento, durante o qual se redesenharam e testaram sucessivas soluções, com o objectivo
de, em cada iteração, extrair um modelo mais focado nos conceitos do domínio.
Figura 7.1. Ciclo de desenvolvimento da nova versão da aplicação DSD.
A figura 7.1 retrata o ciclo de desenvolvimento para a implementação da nova versão da
aplicação DSD. O ciclo engloba a realização das seguintes actividades:
Análise. Com esta actividade pretendeu-se avaliar as limitações da aplicação. Na primeira
iteração, tentou-se perceber quais os problemas apresentados pela versão inicial do desenho
da aplicação. Após o estudo do desenho, verificou-se que este apresentava vários problemas:
1) Fraca ligação entre o desenho e o domínio; 2) Sobreposição de conceitos; 3) Falta de
clareza conceptual; e, 4) Falta de flexibilidade. Assim, surgiu a principal necessidade: resolver
os problemas identificados no desenho da aplicação. A actividade de análise também serviu
para efectuar um levantamento de requisitos mais extensivo, junto dos departamentos de IST.
Nas restantes iterações desta actividade, avaliou-se a evolução do desenho da aplicação. À
78
medida que se implementavam novas soluções para o desenho, conseguia-se,
sucessivamente, resolver os problemas da versão inicial do desenho, até que, na iteração
final, se verificou que todas as necessidades já tinham sido satisfeitas.
Desenho. A correcção dos problemas presentes no desenho requereu que fossem feitas
reestruturações ao nível do modelo de domínio da aplicação. Alguns componentes do
desenho tiveram de ser eliminados e novos componentes foram criados. Relações entre
componentes também foram modificadas. Assim, foram testadas sucessivas soluções,
sempre com o objectivo de dar resposta às necessidades identificadas na actividade anterior.
O processo revisão do desenho da aplicação DSD foi guiado pelo desenho centrado no
domínio. Deste modo, as sucessivas soluções foram obtidas com recurso a um conjunto de
princípios de desenho, dentro dos contextos da construção do modelo de domínio e a
refactorização, tal como descrito ao longo dos capítulos 4 e 5. A criação de fábricas e serviços
permitiu isolar as operações do domínio que não pertenciam, de um modo natural, a uma
entidade ou valor. Como consequência, conseguiu-se melhorar a clareza conceptual das
classes do modelo. A ligação entre o desenho e o domínio foi fortalecida com recurso a
interfaces reveladoras de intenção e a decomposição de conceitos permitiu eliminar a
sobreposição de conceitos e aumentar a flexibilidade apresentadas pelo modelo;
Implementação. Esta actividade teve como objectivo a transformação do desenho em código
fonte. A actividade foi realizada com recurso às tecnologias usadas no Projecto Fénix. Após a
última iteração da actividade de implementação, a aplicação DSD ficou a funcionar sobre um
novo modelo de domínio, livre das limitações apresentadas pela versão inicial. A figura 5.14
mostra a versão final do modelo de domínio da aplicação; e,
Testes. A realização desta actividade permitiu validar o funcionamento da aplicação. A
implementação das sucessivas versões do desenho foi acompanhada pela definição e
realização de testes de software, como forma de validar o comportamento da aplicação e o
cumprimento das regras do domínio.
7.2 Arquitectura e Tecnologias da Solução
A arquitectura genérica da aplicação DSD (e do sistema Fénix) foi abordada na secção 4.1.3 e
encontra-se ilustrada na figura 4.2. Nesta secção será feita um overview das tecnologias usadas nas
várias camadas da arquitectura que suporta a nova versão da aplicação DSD. A análise mais
detalhada à arquitectura global da aplicação pode ser consultada em [SK06].
79
7.2.1 Camada de Infra-estrutura
O armazenamento e persistência da informação de domínio são garantidos por uma base de
dados relacional, gerida pelo MySQL [SQL]. A criação das novas tabelas de dados (necessárias para
a persistência dos objectos das novas classes do domínio) foi feita através da linguagem SQL. A
complexidade da transformação dos objectos do domínio do modelo de programação object-oriented
para o modelo relacional (e vice-versa) foi realizada através da utilização do OJB [OJB], uma
framework de mapeamento Objecto/Relacional. Desta forma, evita-se o acesso aos dados segundo o
modelo relacional, como aconteceria, por exemplo, através do uso directo da tecnologia JDBC
[JDBC].
7.2.2 Camada do Domínio
A definição da parte estrutural da camada de domínio da aplicação (atributos e relações entre
classes) foi feita através da linguagem DML. Posteriormente, usou-se um compilador de DML para
transformar a descrição da estrutura do domínio em código Java, ficando toda a lógica de acesso aos
atributos das classes e relações entre classes automaticamente construída. A parte comportamental
do domínio foi definida, ao nível de cada classe, através de código. Os acessos a objectos do
domínio armazenados em memória (e na camada de infra-estrutura) foram geridos pela biblioteca
JVSTM. A secção 4.1.3 explica, com maior detalhe, as tecnologias em acção na camada de domínio.
7.2.3 Camada de Aplicação
Esta camada é formada por um conjunto de serviços aplicacionais, que têm como principal
objectivo invocar a lógica de domínio necessária para dar resposta aos pedidos efectuados pela
camada superior, a camada de apresentação. Estes serviços são implementados através de classes
Java.
A gestão dos serviços é feita através de uma fábrica de serviços, que providencia os meios para
a execução e parametrização de serviços. Os serviços podem ser configurados, através do uso de
cadeias de filtros, de forma a garantir que um conjunto de requisitos é verificado antes e/ou depois da
sua execução.
A execução de um serviço cria um contexto transaccional, durante o qual se realizam operações
sobre os objectos do domínio. Qualquer acção que implique a alteração de um objecto do domínio
(incluindo a sua criação e eliminação) só pode ocorrer dentro do contexto de execução de um serviço
aplicacional. Os serviços devem invocar a lógica presente nos objectos de domínio de acordo com os
parâmetros recebidos e retornar o resultado obtido para a camada de apresentação. Seguindo esta
linha de orientação, aumenta-se a “espessura” da camada do domínio, ao mesmo tempo que a da
80
camada aplicacional é reduzida. A presença de serviços “finos” e de um domínio “espesso” simplifica
a construção e reutilização de serviços aplicacionais e enriquece a camada de domínio.
7.2.4 Camada de Apresentação
Esta camada faz o tratamento da interface a disponibilizar aos utilizadores. A gestão do
encaminhamento dos pedidos dos utilizadores para a camada de aplicação é feita pela framework
Struts [Str]. Esta ferramenta consegue validar a informação recebida dos utilizadores e definir o fluxo
de execução a ser seguido, como resposta ao processamento do evento de entrada. As páginas web
que apresentam os resultados aos utilizadores são construídas com recurso a JSP [JSP].
Adicionalmente, a construção de interfaces para a visualização, criação e edição de objectos do
domínio é facilitada pelo uso dos Fénix Renderers [Gil06].
No anexo A é feita a descrição de interacção com as principais interfaces gráficas da nova
versão da aplicação DSD.
O próximo capítulo apresenta as conclusões da dissertação.
81
8 8
Conclusão
Este capítulo apresenta os resultados obtidos e identifica as oportunidades de trabalho futuro.
8.1 Resultados
Os resultados obtidos com a dissertação foram os seguintes:
Redesenho da aplicação DSD. Foi feita a revisão do desenho da aplicação DSD, de acordo
com as linhas de orientação do desenho centrado no domínio, divididos pelos seguintes
contextos:
• Construção do modelo de domínio. Um modelo de domínio obtido através do desenho
centrado no domínio é assente sobre um conjunto de “blocos” (entidades, valores,
agregações, etc.) que permitem manter a implementação de software alinhada com o
modelo;
• Refactorização. Alteração de um sistema de software para que a sua estrutura interna
seja melhorada, sem modificar o seu comportamento externo. Trata-se de um processo
contínuo e pode ocorrer sempre que seja possível extrair um modelo mais simples e
focado nos conceitos do domínio; e,
• Desenho Estratégico. Orientação das decisões de desenho no sentido de reduzir-se a
interdependência entre as partes do sistema, com o objectivo do modelo de domínio
conseguir transmitir facilmente uma visão conceptual do core do sistema.
As figuras 2.2 e 5.14 mostram o “antes” e o “depois” do modelo de domínio da aplicação. As
alterações introduzidas permitiram obter as seguintes (principais) vantagens:
• A construção do modelo de domínio permitiu identificar o papel desempenhado por cada
entidade do modelo. A criação de fábricas e serviços permitiu isolar as operações do
domínio que não pertenciam, de um modo natural, a uma entidade ou valor. Como
consequência, conseguiu-se melhorar a clareza conceptual presente nas classes do
modelo;
• A refactorização permitiu alterar a estrutura interna do modelo e, assim, extrair um modelo
mais simples, claro e focado nos conceitos do domínio. A ligação entre o desenho e o
82
domínio foi fortalecida com recurso a interfaces reveladoras de intenção e a decomposição
de conceitos permitiu eliminar a sobreposição de conceitos e aumentar a flexibilidade
apresentadas pelo modelo; e,
• O desenho estratégico permitiu caracterizar o “espaço” ocupado pelo domínio da aplicação
DSD dentro do domínio do sistema Fénix.
Implementação do novo desenho da aplicação DSD. Foi implementado o novo desenho da
aplicação DSD, que fica assim alinhado com os princípios do desenho centrado no domínio. O
novo desenho permitiu ultrapassar os problemas apresentados pela versão inicial: 1) Fraca
ligação entre o desenho e o domínio; 2) Sobreposição de conceitos; 3) Falta de clareza
conceptual; e, 4) Falta de flexibilidade. A implementação do novo desenho da aplicação criou
a oportunidade para, também, se ultrapassarem alguns desafios: 1) A adaptação à nova
estrutura curricular de Bolonha; e, 2) O levantamento de requisitos junto de mais
departamentos do IST.
8.2 Trabalho Futuro
Foram identificadas as seguintes oportunidades de trabalho futuro:
Especificação de mais testes de software. A criação das novas entidades no domínio da
aplicação DSD foi acompanhada pela especificação de testes de software. Contudo, a
especificação dos testes devia ser estendida a todas as entidades no modelo, como forma de
assegurar que futuras alterações feitas no modelo mantêm o comportamento desejado da
aplicação; e,
Abordagem aos princípios do desenho estratégico no contexto do sistema Fénix. A
aplicação DSD é um sistema que faz parte de um contexto mais amplo: o sistema Fénix. Os
princípios associados ao desenho estratégico aplicam-se a um sistema como um todo. Seria
interessante analisar a aplicação dos princípios do desenho estratégico ao próprio sistema
Fénix, como forma de ver-se o “quadro completo” e não apenas o contexto da aplicação DSD.
83
9 9 10
Bibliografia
[Ale77] Alexander, Christopher: A Pattern Language: Towns, Buildings, Construction. Oxford
University Press, 1977.
[Ale79] Alexander, Christopher: A Timeless Way of Building. Oxford University Press, 1979.
[ALSU06] Aho, Alfred, Lam, Monica, Sethi, Ravi & Ullman, Jeffrey: Compilers: Principles,
Techniques, and Tools (2nd Edition). Addison Wesley, 2006.
[Ast03] Astels, David: Test-Driven Development: A Practical Guide. Prentice Hall, 2003.
[BA04] Beck, Kent & Andres, Cynthia: Extreme Programming Explained: Embrace Change, Second
Edition. Addison Wesley, 2004.
[Bol99] Declaração dos Ministros Europeus da Educação: The Bologna Declaration of 19 June 1999.
Bolonha, 1999.
[Cac05] Cachopo, João: JVSTM – Java Versioned Software Transactional Memory, 2005.
http://www.esw.inesc-id.pt/~jcachopo/jvstm/
[CBB⁺02] Clements, Paul, Bachmann, Felix, Bass, Len, Garlan, David, Ivers, James, Little, Reed,
Nord, Robert & Stafford, Judith: Documenting Software Architectures: Views and Beyond.
Addison Wesley, 2002.
[CS05] Cachopo, João & Rito Silva, António: Versioned Boxes as the Basis for Memory Transactions.
SCOOL05 Workshop, 2005.
[CS06] Cachopo, João & Rito Silva, António: Combining Software Transactional Memory with a
Domain Modeling Language to Simplify Web Application Development. ICWE, 2006.
[DF] DbUnit Framework. http://www.DbUnit .org/
84
[Eva03] Evans, Eric: Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison
Wesley, 2003.
[FBB⁺99] Fowler, Martin, Beck, Kent, Brant, John, Opdyke, William, & Roberts, Don: Refactoring:
Improving the Design of Existing Code. Addison Wesley, 1999.
[Fow04] Fowler, Martin: Domain Specific Languages, 2004.
http://www.martinfowler.com/bliki/DomainSpecificLanguage.html
[Fow05] Fowler, Martin: Language Workbenches: The Killer-App for Domain Specific Languages?,
2005. http://www.martinfowler.com/articles/languageWorkbench.html
[Fow97] Fowler, Martin: Analysis Patterns: Reusable Object Models. Addison Wesley, 1997.
[FRF⁺02] Fowler, Martin, Rice, David, Foemmel, Matthew, Hieatt, Edward, & Mee, Robert, Stafford,
Randy: Patterns of Enterprise Application Architecture. Addison Wesley, 2002.
[FS99] Fowler, Martin & Scott, Kendall: UML Distilled - A Brief Guide to the Standard Object Modeling
Language (2nd Edition). Addison Wesley, 1999.
[GB] Gamma, Erich, & Beck, Kent: JUnit, Open-Source Testing Framework. http://www.junit.org/
[GHJV95] Gamma, Erich, Helm, Richard, Johnson, Ralph, & Vlissides, John: Design Patterns:
Elements of Reusable Object-Oriented Software. Addison Wesley, 1995.
[Gil06] Gil, Cláudio: Fénix Renderers Framework, 2006.
https://fenix-ashes.ist.utl.pt/ClaudioGil/FenixRenderers
[GOP] Gabinete de Organização Pedagógica. http://gop.ist.utl.pt/
[IST] Instituto Superior Técnico. http://www.ist.utl.pt/
[JDBC] Java Database Connectivity. http://java.sun.com/products/jdbc/overview.html
[JSP] JavaServer Pages Technology. http://java.sun.com/products/jsp/index.jsp
[Ker04] Kerievsky, Joshua: Refactoring to Patterns. Addison Wesley, 2004.
[Mey88] Meyer, Bertrand: Object-Oriented Software Construction. Prentice Hall, 1988.
85
[Nil06] Nilsson, Jimmy: Applying Domain-Driven Design and Patterns. Addison Wesley, 2006.
[OJB] Apache Object Relational Bridge. http://db.apache.org/ojb/
[Pau96] Graham, Paul: ANSI Common LISP. Prentice Hall, 1996.
[PF] Projecto Fénix. https://fenix-ashes.ist.utl.pt/
[PF05] Projecto Fénix. Overview do sistema Fénix, 2005.
https://fenix-ashes.ist.utl.pt/FenixSystem
[PF07] Projecto Fénix. Documentação do modelo de domínio, 2007.
https://fenix-ashes.ist.utl.pt/DomainModel
[Pfl01] Pfleeger, Shari: Software Engineering: Theory and Practice (2nd Edition). Prentice Hall, 2001.
[Sco99] Scott, Michael: Programming Language Pragmatics. Morgan Kaufmann, 1999.
[SK06] Sitefane, João & Kassamali, Anil: Fénix – Departamento. Relatório de Trabalho Final de
Curso, Instituto Superior Técnico, Universidade Técnica de Lisboa, 2006.
[SQL] MySQL. http://www.mysql.com/
[Str] Apache Struts Framework. http://struts.apache.org/
[ST95] Shavit, Nir & Touitou, Dan: Software Transactional Memory. Proceedings of the 14th ACM
Symposium on Principles of Distributed Computing, pp. 204-213, 1995.
[W3C06] W3C: The XML 1.1 Specification, 2006. http://www.w3.org/TR/xml11
A Interfaces da Aplicação Distribuição do Serviço Docente
Este anexo descreve a interacção com as principais interfaces gráficas da nova versão da
aplicação DSD.
A aplicação encontra-se disponível a docentes e funcionários através do link Serviço Docente,
presente no portal Departamento (figura 10.1).
Figura 10.1. Acesso à aplicação Distribuição do Serviço Docente.
Seleccionada a opção Criar Distribuição do Serviço Docente, é possível criar um novo processo
de distribuição do serviço docente, para um determinado ano lectivo e/ou semestre (figura 10.2).
Figura 10.2. Criação de um novo processo de distribuição do serviço docente.
Após a criação do novo processo de distribuição, o utilizador é encaminhado para o ecrã
principal da aplicação. As funcionalidades disponíveis para o utilizador variam consoante as
permissões que lhe foram atribuídas (o criador do processo de distribuição é o único utilizador, por
omissão, com o controlo total sobre o processo).
Figura 10.3. Ecrã principal do processo de distribuição.
O controlo de acesso ao processo de distribuição e a divisão de tarefas são feitos através do link
Gerir Permissões. Seleccionando esta opção, acede-se à interface que permite configurar as
permissões sobre o processo de distribuição (para o controlo de acesso) e os agrupamentos de
docentes e disciplinas (para a divisão de tarefas).
Figura 10.4. Gestão de permissões.
O link Gerir Fases encaminha o utilizador para a página de gestão de fases. A criação de uma
nova fase permite salvaguardar toda a informação contida no processo de distribuição. A partir desse
ponto, recomeça-se o processo sobre um novo conjunto de dados, sem prejuízo para a informação
que anteriormente estava em vigor. Esta página também permite a recuperação e consulta da
informação de uma fase anterior.
Figura 10.5. Gestão de fases.
Seguindo o link Gerir Docentes e Disciplinas, torna-se possível definir o conjunto de docentes e
disciplinas que serão usados no decorrer do processo de distribuição.
Figura 10.6. Gestão de docentes e disciplinas.
A partir da interface ilustra na figura 10.6 é possível adicionar docentes/disciplinas ao processo
(figura 10.7) e criar docentes/disciplinas “virtuais” (figura 10.8).
Figura 10.7. Adição de docente.
Figura 10.8. Criação de docente “virtual”.
A gestão dos agrupamentos de docentes e disciplinas é feita através do link Gerir
Agrupamentos. Através desta página é possível realizar uma série de operações, como a
adição/remoção de elementos a agrupamentos e a criação/eliminação de agrupamentos (figura 10.8).
Figura 10.9. Gestão de agrupamentos.
Através do link Estimar Disciplinas faz-se uma previsão do número de horas semanais
necessárias para o ensino de cada disciplina. Este número está dependente de: 1) O número de
alunos inscritos na disciplina; e, 2) O número máximo de alunos por cada aula. A partir destas
estimativas torna-se possível saber o total de horas de ensino que os recursos existentes no
departamento necessitam de cobrir (figura 10.9).
Figura 10.10. Estimação da necessidade horária das disciplinas.
Após definir-se a necessidade horária de cada disciplina, deve atribuir-se aos docentes da
distribuição todas as horas de ensino existentes. O link Atribuir Docentes a Disciplinas serve para
esse efeito.
Figura 10.11. Estimação da atribuição de docentes a disciplinas.
À medida que se completa o processo de distribuição, pode visualizar-se o seu estado, de
acordo com diferentes perspectivas, através do link Ver Distribuição do Serviço Docente.
Figura 10.12. Visualização do processo de distribuição.
B Terminologia
A terminologia adoptada em Português para os termos relacionados com o desenho centrado no
domínio será enumerada de seguida.
Aggregate: Agregação;
Bounded context: Contexto;
Context map: Mapa de contextos;
Continuous integration: Integração;
Distillation: Destilação;
Domain-driven design: Desenho centrado no domínio;
Entity: Entidade;
Factory: Fábrica;
Intention-revealing interface: Interface reveladora de intenção;
Large-scale structure: Estrutura de grande escala;
Refactoring: refactorização;
Repository: Repositório;
Separate ways: Separação de interesses;
Service: Serviço;
Shared kernel: Núcleo partilhado;
Side-effect-free function: Função sem efeitos secundários;
Standalone class: Classe independente;
Strategic design: Desenho estratégico;
Ubiquitous language: Linguagem comum; e,
Value object: Valor.