quinta-feira, 7 de maio de 2020

Arquitetura de Software

Para entendermos a necessidade de se arquitetar um software, alguns conceitos devem ser apresentados, bem como os desafios com os quais um profissional desta área deve lidar.
Historicamente, os fracassos de projetos de softwares são significativos. De acordo com Hastie e Wojewoda (2015), o Chaos Report da Gartner de 2015 mostra que apenas 29% dos projetos foram bem sucedidos, 52% chegaram ao final ainda necessitando de ajustes e 19% falharam. Os fatores críticos de sucesso estão relacionados à natureza complexa e intangível do software.
O software é visto pelas áreas de negócios como algo flexível e adaptável, porém sabemos que um software não arquitetado pode dificultar sua manutenção, escalabilidade e reúso.
Desta forma, desenvolver soluções arquitetadas é uma prática que tornará nosso trabalho, a longo prazo, menos reativo e estressante.

Mas o que é arquitetura de software?

Uma arquitetura registra informações sobre como os elementos de software se relacionam uns com os outros, ocultando ou explicitando elementos do software que devem ou não existir em diferentes níveis de abstração.

Aqueles que possuem vivência na área de desenvolvimento de software sabem que, muitas vezes, uma mudança ou um novo requisito tem impacto estrutural e demanda grande esforço de desenvolvimento e, se realizado sem planejamento, desencadeia efeitos colaterais em todo o software.

Modelagem de aplicações de softwares

Como você já deve ter estudado, um aplicativo de software possui um ciclo de vida. Ao longo deste ciclo, muitas mudanças são realizadas e geram impactos no código escrito nas primeiras versões do software.
O software é afetado por um fenômeno de degradação que impacta sua confiabilidade, estrutura e sua consistência. Sua documentação fica desatualizada, dificultando sua manutenção e tornando-a onerosa.
Sabemos que um processo de desenvolvimento definido que favoreça a obtenção e a validação dos requisitos pode minimizar esses impactos, porém o fato de o software ser visto como algo flexível torna a definição de uma arquitetura um elemento fundamental para o desenvolvimento de software em larga escala.
Se você já desenvolveu algum software ou até mesmo uma planilha eletrônica com várias referências a fórmulas em diferentes arquivos, já percebeu que existe um limite para a capacidade humana para compreender, ao longo do tempo, aquilo que foi produzido, tornando esta uma atividade complexa.
O software possui uma natureza complexa crescente, seja pelo número de linhas de código ou pela sua intangibilidade. Logo, a criação de modelos torna-se indispensável para compreensão do que está sendo desenvolvido.
O uso de modelos apoia o entendimento e a definição da arquitetura do software, assim como a identificação das regiões críticas que podem sofrer degradação ao longo do tempo.
No processo de criação de modelos, muitos problemas podem ser antecipados e decisões são tomadas a fim de minimizar seu impacto ao longo do tempo.

IMPORTANTE
Blaha e Rumbaugh (2006, p. 17) definem modelo como uma abstração de algo que facilita seu entendimento antes de construí-lo. Abstração é um processo mental básico que permite lidar com a complexidade, omitindo detalhes não essenciais.

No processo de produção do software, modelos são criados para descrever a estrutura e o comportamento de um software para posterior implementação. Estas descrições de modelos guiam a construção e mantêm registros das decisões tomadas na sua concepção.
Para os criadores da Unified Modeling Language (UML), Booch, Rumbaugh e Jacobson, nenhum modelo único é suficiente. Qualquer sistema não trivial será mais bem investigado por meio de um conjunto de modelos quase independentes com vários pontos de vista.
Um ou mais modelos podem servir de inspiração para dar origem a uma arquitetura que sustente as necessidades do que está sendo modelado.
Cada área de conhecimento adota tipos específicos de modelos. Na engenharia de software contemporânea, segundo Booch, Rumbaugh e Jacobson (2006), adota-se uma perspectiva orientada a objetos, onde a UML é empregada para visualização, especificação, construção e documentação de artefatos que orientam o desenvolvimento do software.
Para entender a importância de controlar esta complexidade, vamos analisar no próximo tópico o trabalho de Brooks (1987), que faz uma classificação dos aspectos que estão sob nosso controle e aqueles que fogem dele, impactando o cronograma, o custo e a equipe de projeto do software.




Tarefas acidentais e essenciais

Independentemente do processo de desenvolvimento de software adotado, um conjunto de tarefas é organizado e realizado. Tais tarefas são classificadas por Brooks (1987) como tarefas acidentais e essenciais:
  • As tarefas acidentais estão relacionadas à implementação do software e as principais preocupações estão ligadas à sintaxe das linguagens, aos limites de hardware, aos ambientes e ferramentas de desenvolvimento e a demais aspectos técnicos. Estes aspectos são facilmente superados com treinamentos, leituras ou por meio de consulta a um profissional mais experiente.
  • As tarefas essenciais estão relacionadas ao processo mental de criação de um conjunto de conceitos que se interligam.
Tanto as tarefas acidentais quanto as essenciais criam barreiras para o desenvolvimento de software, porém grande parte das barreiras acidentais foi transposta na última década e as principais falhas de projetos estão relacionadas às atividades essenciais que criam barreiras que dificilmente são domináveis.
De forma análoga, e neste contexto, pode-se comparar o processo de desenvolvimento de software ao processo de criação de um texto, em que as tarefas acidentais estão relacionadas ao domínio de uma ferramenta de edição de textos, a sintaxe e a semântica da língua. Tais tarefas podem criar barreiras para a produção do texto, mas serão superadas com algum nível de estudo ou apoio de terceiros, porém não garantem que o texto escrito atenderá critérios de qualidade.
Logo, o domínio de tarefas acidentais não garante a qualidade do que está sendo produzido. A qualidade será definida pela forma peculiar de criação e organização das ideias atuando sobre a construção mental e essencial que será descritos de forma textual.

Aspectos essenciais na produção de software

Brooks (1987) elenca quatro aspectos essenciais que impactam na produção do software. São eles: complexidade, conformidade, flexibilidade e intangibilidade. Estes aspectos são descritos a seguir.

Complexidade

Entidades de software possuem uma natureza complexa. Assim, aumentar sua escala não é meramente repetir os mesmos elementos em tamanho maior. É necessário um aumento do número de elementos diferentes, amplificando a complexidade do todo de forma não linear.
Queremos dizer que existe uma grande diferença entre fazer um software com poucas linhas de código e desenvolver um software com um número maior de requisitos.
Para um software mais robusto, não basta aumentar as linhas de código. É necessário incluir elementos de software para facilitar o entendimento das linhas já produzidas, a manutenção, a inclusão de novas funcionalidades, o aumento da equipe, a padronização e a inclusão de interfaces, entre outras demandas exigidas por um software de maior escala.

Imagine um artesão trabalhando na produção de um vaso de barro. Você, de passagem em turismo pelo local, adorou aquele vaso. Em função disso, solicitou ao artesão que produzisse 1.000 unidades, pois presentearia seus familiares e venderia o restante dos vasos na sua cidade de origem.


REFLITA

O processo e as ferramentas de produção adotados pelo artesão seriam suficientes para atender sua encomenda? Bastaria apenas aumentar em quantidade a matéria-prima do artesão? Contratar mais artesões garantiria a beleza do vaso apreciada por você? O processo para produzir uma unidade é o mesmo para produzir 1.000 unidades?

Acredito que chegará facilmente à conclusão que novos elementos deverão ser inseridos no processo de produção do vaso. Talvez o uso de formas para garantir o padrão, a contratação de novos artesões, uma sequência ordenada de tarefas, a criação de modelos que serão submetidos a testes, entre outras ações.


AGORA, REFLITA: 

O que diferencia a produção de um software de 1.000 linhas de código com um de 15.000 linhas? Será só a quantidade de linhas?

Softwares com 1.000 linhas de código, no pior caso, podem ser refeitos gastando apenas mais alguns dias de trabalho; entretanto, reescrever um sistema mais complexo levaria meses ou anos. Portanto, cuidar da arquitetura no início reduz os problemas futuros.

Da complexidade, vem a dificuldade de entender e se comunicar com os membros da equipe de desenvolvimento, levando à deficiência do produto, que aumenta os custos e afeta o cronograma e a confiabilidade. Da complexidade da estrutura, surge também a dificuldade de entender o comportamento e ampliar os programas sem criar efeitos colaterais, tornando árduo o gerenciamento destes problemas.
Provavelmente, muitos dos programadores já passaram por situações em que não conseguiram ou demoraram para entender um código, seja ele gerado por terceiros ou até mesmo um código próprio.
Segundo Brooks (1987), a complexidade do código é crescente e existe um limite que o cérebro humano consegue gerenciar, impactando na quantidade de novas linhas de código que podem ser acrescentadas a um programa ao longo do tempo.

À medida que o software é implementado, ou seja, linhas de código são inseridas, sua complexidade cresce e afeta a produtividade ao longo do tempo.

Aspectos essenciais na produção de software

Conformidade e flexibilidade

Outras áreas do conhecimento também lidam com a complexidade crescente, mas como o software não está suscetível às leis naturais, é visto como algo flexível e de fácil adequação, ao menos se comparado à Física e outras ciências.
Brooks (1997) afirma que, em decorrência da sua complexidade, a versão inicial de um software muitas vezes não atende aos requisitos na sua plenitude, necessitando de constantes mudanças, de tal modo que todo software de sucesso acaba sendo modificado. Assim, um sistema de software deve ser concebido para mudar.
Caso você já atue na área de desenvolvimento de software, deve ter percebido que a mudança dos requisitos é algo constante. Isso não significa que as mudanças são correções de erros, mas podem decorrer de novas funcionalidades para atender às necessidades de negócios. Vale dizer que a TI deve impulsionar os negócios e não ser um gargalo para novas oportunidades. Logo, precisamos desenvolver softwares nos quais uma mudança não afete toda a estrutura já desenvolvida.
Nosso código deve “aceitar” mudanças com certa flexibilidade, comunicar claramente suas responsabilidades, facilitar a manutenção e proporcionar o reúso. Esse é o grande desafio!

Intangibilidade

Softwares são intangíveis, portanto, é difícil criar uma representação visual objetiva e comum para eles. Ao tentar diagramar uma estrutura de software, descobre-se que ela não é apenas um, mas sim vários diagramas superpostos uns aos outros, sem hierarquias ou relações diretas entre seus elementos, forçando cortes que eliminam conexões nas diferentes vistas do modelo.
Para Brooks (1987), esses cortes prejudicam não só o processo
de projeto do software, mas também a comunicação entre os
membros da equipe.
A UML é uma poderosa ferramenta capaz de tangibilizar as descrições de implementação do arquiteto de software.
Um arquiteto de software deve apoiar-se em descrições de modelos para comunicar suas decisões de implementação. Um diagrama UML, analogamente, pode ser comparado com uma planta hidráulica ou elétrica que um engenheiro civil ou eletricista utiliza para tangibilizar um modelo mental e comunicar seu projeto.
Portanto, a descrição de modelos de software apoiados em diagramas é uma ferramenta essencial para um arquiteto de software e um dos elementos que o difere do programador.
Antes de prosseguir, convém recordar o que é o paradigma orientado a objetos (OO) e alguns de seus conceitos mais importantes.


UML: um breve histórico

A UML surgiu da união de três metodologias de modelagem: o método do americano Grady Booch, o método OMT (Object Modeling Technique), do sueco Ivar Jacobson, e o método OOSE (Object-oriented Software Engineering) do americano James Rumbaugh. Estas eram, até meados da década de 1990, as três metodologias de modelagem orientada a objeto mais populares. A união dessas tecnologias contou com o apoio da Rational Software, que incentivou e financiou a união das três metodologias. O esforço inicial do projeto começou com a união do método de Booch com o de Jacobson, o que resultou no lançamento do método unificado no final de 1995. Logo em seguida, Rumbaugh juntou-se a Booch e Jacobson na Rational Software, e seu método OOSE começou a ser incorporado à nova metodologia. O trabalho de Booch, Jacobson e Rumbaugh, conhecidos popularmente como “os três amigos”, resultou no lançamento, em 1996, da primeira versão da UML propriamente dita.
Assim que a primeira versão foi lançada, diversas grandes empresas atuantes na área de software passaram a contribuir com o projeto, fornecendo sugestões para melhorar e ampliar a linguagem. Finalmente, a UML foi adotada pela OMG (Object Management Group), em 1997, como a linguagem padrão de modelagem.
Fonte: Guedes (2014, p. 15-16).

quarta-feira, 6 de maio de 2020

Diagramas (Parte 3)

Representação de um diagrama de componentes

O diagrama de componentes representa todos os softwares que serão utilizados no sistema. Ele especifica os relacionamentos e as dependências entre os componentes de software. O diagrama de componentes é parte da especificação da arquitetura do sistema. Por meio dele, é possível especificar os componentes de vários ambientes da arquitetura, tais como ambiente de desenvolvimento, ambiente de produção, ambiente de testes etc.
A UML fornece alguns tipos de estereótipos que podem ser utilizados em diagramas de componentes: <>, <>, <>, <>, <>, <>, <> etc.
O diagrama de componente é formado por componentes, interfaces e relacionamentos.
Um componente é qualquer arquivo que faça parte do desenvolvimento de um sistema. É um conjunto de interfaces. Os principais elementos utilizados como componentes em um diagrama de componentes são: código-fonte, bibliotecas, interfaces, base de dados, tabelas, arquivos e documentos complementares.

A interface é um conjunto de operações que executa os serviços de uma classe ou componente. O relacionamento entre um componente e uma interface dá-se por meio de uma realização (implementação da interface) ou de uma dependência (utilização da interface).

Representação de um diagrama de implantação

O diagrama de implantação (deployment) representa a arquitetura física (normalmente hardware) do sistema. Ele modela os recursos de infraestrutura, redes (servidores) e artefatos de sistema. É importante que os analistas entendam a composição dos elementos de hardware e dos ambientes de execução de software de um sistema.
O diagrama de implantação é um gráfico de nós, ou nodes. Nó é um elemento de hardware conectado por vias de comunicação. Ele representa um recurso de hardware, por exemplo, um servidor de aplicação, estações de trabalho, roteadores ou impressoras. Cada nó pode conter instâncias de nós ou de componentes.

Além de nós, o diagrama de implantação é constituído também por artefatos e componentes. Os componentes são os mesmos utilizados no diagrama de componentes e com as mesmas características.
De acordo com o OMG (2013), “um artefato definido pelo usuário representa um elemento concreto no mundo físico”. Artefatos podem ser programas executáveis, códigos de programas, tabelas, documentos de texto etc.

terça-feira, 5 de maio de 2020

Diagramas (parte 2)

Diagrama de sequência e diagrama de comunicação

Além do diagrama de caso de uso, o diagrama de sequência também é considerado um modelo de interação. Entretanto, eles apresentam informações diferentes. O diagrama de caso de uso apresenta a interação dos atores externos com o sistema, e o diagrama de sequência apresenta como ocorre o fluxo de mensagens entre os objetos ao longo do tempo sobre um determinado caso de uso.
Assim, diagrama de sequência é um diagrama que apresenta, numa ordem lógica, os fluxos de mensagens entre os objetos pertinentes ao respectivo caso de uso num determinado período de tempo. Isso significa que ele deve ser elaborado após o desenvolvimento do diagrama de caso de uso.
É necessário conhecer os símbolos utilizados para a elaboração de um diagrama de sequência. Ele é composto por objetos e fluxos de mensagens.

Os objetos são desenhados como um retângulo ao topo de uma linha vertical tracejada e projetada para baixo, que recebe o nome de linha de vida. Além deles, geralmente, uma instância de ator é desenhada como a primeira linha de vida do diagrama de sequência.
As mensagens são indicadas nessa linha. Ao indicar uma mensagem, uma base retangular vertical é criada sobre a linha de vida. Essa base é chamada de ativação e determina a execução de uma ação, num período de tempo da interação, entre os objetos.
Os fluxos de mensagens são identificados por um número, que indica a sequência delas. Eles podem ser do tipo de procedimento síncrono ou assíncrono.

O fluxo do tipo síncrono é desenhado com a seta do fluxo de forma sólida (preenchida) na cor preta e indica que o objeto remetente esperará um retorno da mensagem pelo objeto destinatário.
O fluxo do tipo assíncrono é desenhado com a seta do fluxo de forma não sólida e indica que as mensagens são enviadas, mas não se espera o retorno de forma imediata.

No diagrama de sequência também podem ser encontrados alguns casos especiais, como autodelegação e retorno automático de mensagem.
Autodelegação ou autochamada, de acordo com Furlan (1998), é uma técnica utilizada em algoritmos para mostrar que uma operação chama a si própria. Na prática, isso significa que a mensagem é enviada para o próprio objeto. A mensagem de autodelegação é sempre síncrona.

Uma outra forma de representar as mensagens é indicar o fluxo por uma linha tracejada, que significa um retorno automático da mensagem. Assim, a mensagem é enviada para um destinatário e, em seguida, obtém-se o retorno esperado.

Representação do diagrama de comunicação

O diagrama de comunicação (ou diagrama de colaboração, como era denominado até a versão UML 1.5), como o diagrama de sequência, apresenta um fluxo de mensagens, porém não em sequência. Além disso, a disposição dos objetos é estrutural. O diagrama de comunicação deve ser elaborado com o intuito de mostrar os relacionamentos entre os objetos. É um complemento do diagrama de sequência.
O processo de elaboração do diagrama de comunicação é realizado da mesma forma que o do diagrama de sequência. Assim, ele é elaborado com base nas ações lógicas descritas em determinados casos de uso especificados no diagrama de casos de uso.
Os símbolos utilizados no diagrama de comunicação são: objetos representados por retângulos e mensagens numeradas representadas por setas e linhas, para mostrar os relacionamentos entre os objetos. É importante ressaltar que essa linha representa uma mensagem ou várias entre os relacionamentos.

Os fluxos de mensagens utilizados são síncronos ou assíncronos, conforme já explicado. Entretanto, os assíncronos não são utilizados com muita frequência, já que o diagrama de comunicação não especifica as sequências deles.


Geralmente o diagrama de comunicação é elaborado para os casos de uso que apresentam muitos objetos, de forma a esclarecer melhor os relacionamentos entre eles.

Representação de um diagrama de estado

De acordo com Blaha e Rumbaugh (2006), o modelo de estados consiste em vários diagramas de estados, um para cada classe com comportamento temporal importante para uma aplicação. O diagrama de estados é um conceito padrão da ciência da computação, uma representação gráfica para máquinas de estado finito que relaciona eventos e estados. Os eventos representam os estímulos externos, e os estados, os valores dos objetos.
Um sistema responde com base em estímulos externos. Dependendo deles, ocorrem mudanças em seu comportamento. O diagrama de estado mostra como um objeto se comporta quando recebe eventos externos.
As máquinas de estado são muito utilizadas na computação em aplicações de inteligência artificial. Elas avaliam os aspectos dinâmicos de uma construção.

Um diagrama de estado é composto pelos seguintes elementos: estado, transição, estado inicial e estado final.

Estado

O símbolo de estado, denominado estado simples, é representado por um retângulo com bordas arredondadas contendo um nome de estado. Em outro símbolo, chamado de estado composto ou máquina de estado, o retângulo é maior, pois nele existirão outros estados.

Segundo Lima (2011), um estado simplesmente representa uma ação executada, uma condição satisfeita ou uma situação estática de espera em que um objeto se encontra durante sua existência ou durante o processo de execução de alguma atividade no sistema.

Os diagramas de estados são muito utilizados para a validação de modelagem de classes. Para cada classe, poderá haver um diagrama de estado, com o objetivo de analisar todos os estados possíveis de cada objeto.
Na segunda parte do símbolo de estado pode-se identificar uma atividade do. De acordo com Blaha e Rumbaugh (2006), uma atividade é o comportamento real que pode ser invocado por diversos efeitos. Efeito é uma referência a um comportamento executado em resposta a um evento. Assim, uma atividade do é uma atividade que continua ao longo de um período de tempo. Ela só pode ocorrer dentro de um estado e não pode estar conectada a uma transição.

Transição

A transição é representada por uma seta e indica o relacionamento entre estados. A transição indica a execução de uma ou mais ações específicas: quando estiver no primeiro estado e entrar no segundo ou quando um evento específico ocorrer e determinadas condições forem satisfeitas.
rótulo a ser descrito numa transição tem a seguinte sintaxe: Evento(Argumentos) [condição] / Ação, sendo que:
  • Evento: é uma ocorrência num período de tempo. Os eventos podem ser do tipo:
    • Evento de sinal: representado por <> e indicado acima de uma classe.
    • Evento de mudança: representado pela palavra-chave when e seguido por uma expressão booleana. Exemplo: when(valor_do_saque > saldo_na_conta_corrente).
    • Evento de tempo: representado pela palavra-chave after e seguida por uma expressão entre parênteses, indicando a duração de tempo. Exemplo: after(5 minutos). É utilizada juntamente com o evento de mudança.
  • Argumentos: parâmetros do evento (valores).
  • Condição: é uma expressão booleana representada entre colchetes. A transição somente se executará se a condição assumida pela expressão for verdadeira. A condição é denominada condição de guarda.
  • Ação: é uma ação executada durante a transição.
Assim como nos estados, é possível especificar atividades em transição. As atividades entry e exit indicam entrada e saída, respectivamente. Vale ressaltar que elas podem ser utilizadas em transições e também em estados.

Estado inicial e estado final

O estado inicial é representado por um círculo preenchido na cor preta (fechado) e indica que o objeto está inerte. O estado final é representado por um círculo aberto (branco) e, dentro deste, outro preenchido na cor preta (fechado). Ele indica o último estado de um objeto. Os estados inicial e final são considerados pseudoestados.

O diagrama de estados possui duas estruturas importantes que podem ser utilizadas na modelagem de estados: a primeira é chamada fork (bifurcação), que permite a subdivisão de um estado em dois ou mais, concorrentes. A segunda estrutura é chamada join (junção), que une dois ou mais estados num único.

Representação de um diagrama de atividades

O diagrama de atividades é um diagrama que mostra a sequência lógica de um sistema, como um algoritmo. Entretanto, nele, é possível manipular processos paralelos. O principal foco do diagrama de atividades são as operações.
Segundo o OMG (2014), um diagrama de atividades especifica a coordenação de execuções de comportamentos, usando um modelo de fluxo de controle e de dados. O fluxo de execução é modelado como nós de atividade conectados por extremidades. Um nó (nodo ou node) pode ser a execução de um comportamento subordinado, como um cálculo computacional, uma chamada para uma operação ou manipulação de conteúdos de objetos. Nós de atividade também incluem construções de fluxo de controle, como sincronização, decisão e controle de concorrência. Atividades podem invocar hierarquias de outras atividades, resolvidas em ações individuais.
De acordo com Furlan (1998), um diagrama de atividades é elaborado com os seguintes propósitos:
  • Capturar o funcionamento interno de um objeto.
  • Capturar o trabalho (ações) que será desempenhado quando uma operação for executada.
  • Mostrar como um processo de negócio funciona em termos de atores, fluxos de trabalho, organização e objetos.
  • Mostrar como uma instância de caso de uso pode ser realizada em termos de ações e mudanças de estado de objetos.
  • Mostrar como um conjunto de ações relacionadas pode ser executado e como afetará objetos ao redor.
Os símbolos utilizados em um diagrama de atividades são:
  • Atividade: representada por um retângulo com bordas arredondadas.
  • Transição: representada por um fluxo de uma atividade para outra.
  • Decisão/merge: representada por um losango, pode ter diversas saídas.
  • Bifurcação e junção (fork e join): representados por barras de sincronização.
  • Entrada: representada por um círculo preenchido na cor preta (fechado).
  • Saída: representada por um círculo aberto (branco) e, dentro deste, outro preenchido na cor preta (fechado).
  • Partições: são representadas por um grande retângulo, que pode ser vertical ou horizontal.
A utilização da bifurcação e da junção de atividades é muito importante no diagrama de atividades, pois mais de uma atividade podem ocorrer ao mesmo tempo nesses casos. Esse fato é o que o diferencia de um fluxograma.
A bifurcação (fork) é uma atividade subdividida em duas ou mais concorrentes, e a junção (join) são duas ou mais atividades que se juntam numa única.
O losango representa tanto uma decisão quanto um merge. Quanto há uma entrada e diversas saídas, ele representa uma decisão. Nesse caso, cada saída é representada por uma condição de guarda, entre colchetes. Quando há diversas entradas e uma única saída, ele representa um merge e é utilizado para agregar diversos fluxos de controle em um só.
O diagrama de atividades permite também o uso de partições (swimlanes). Elas indicam diferentes ações que podem ser executadas por objetos ou entidades diferentes e podem ser verticais ou horizontais. É uma forma lógica de organização das atividades. Por exemplo: a partição Cliente indica as atividades relacionadas ao cliente, e a partição Conta indica as relacionadas à conta. Entretanto, as atividades não são paralelas e distintas, mas integradas entre as partições, com o objetivo de demonstrar os relacionamentos entre elas.

segunda-feira, 4 de maio de 2020

Diagramas

Encapsulamento

Segundo Lima (2011), encapsulamento ou ocultação de informações é uma técnica que consiste em separar aspectos externos dos internos da implementação de um objeto, isto é, determinados detalhes ficam ocultos aos demais objetos e dizem respeito apenas ao próprio objeto.
A técnica consiste no ocultamento das informações, ou seja, qualquer aplicação poderá utilizar uma determinada classe, mas não terá acesso à forma como foi definida. Os atributos e as operações encapsulados somente serão visíveis pelo próprio objeto.
Vale ressaltar que, nessa técnica, os objetos da subclasse herdam todos os atributos e operações da superclasse. Isso significa que o encapsulamento estabelece uma dependência com a relação de herança.

Ligações, associações e multiplicidade

De acordo com Blaha e Rumbaugh (2006),ligações e associações são o meio de estabelecer relacionamentos entre objetos e classes. Uma ligação é uma conexão física ou conceitual entre objetos e associação é uma descrição de um grupo de ligações com estrutura e semântica comuns.

Assim, os objetos e as classes relacionam-se por meio de uma notação específica da UML.

Além disso, há uma notação da UML chamada de multiplicidade. É uma simbologia utilizada em ligações e associações. Para Blaha e Rumbaugh (2006), “multiplicidade especifica o número de instâncias de uma classe que podem se relacionar a uma única instância de uma classe associada”.

Blaha e Rumbaugh (2006) advertem em sua obra que, apesar de a literatura utilizar esse significado, a multiplicidade é um subconjunto (possivelmente infinito) de inteiros não negativos.
Além da simbologia apresentada no exemplo, a multiplicidade permite outras possibilidades de simbologias, tais como: “1..” – um ou mais; “5..7” – cinco a sete inclusive; “0..1” – zero ou um etc. A indicação de notação de multiplicidade é considerada opcional. Portanto, se você não indicá-la, não haverá problemas, mas é recomendável usá-la.

Agregação e composição

“A agregação é uma forma especial de associação utilizada para mostrar que um tipo de objeto é composto, pelo menos em parte, de outro em uma relação de todo/parte”, afirma Furlan (1998). Assim, agregação é uma associação em que um objeto é parte do outro, ainda que a parte possa existir sem o todo.

De acordo com Medeiros (2004), para sabermos se um relacionamento é de agregação, basta perguntarmos se, em primeiro lugar, cabe a estrutura todo-parte. Em seguida, perguntamos se o objeto constituinte “vive” sem o objeto agregado. Se a resposta for sim para ambas as perguntas, teremos uma agregação.
Outro caso especial de associação, semelhante à agregação, é a composição, que é também uma forma de relacionamento todo/parte. A composição é constituída por partes (componentes) que formam o todo (composto), de maneira que o todo não existe sem as suas partes.
Para identificar uma composição, utilizaremos as mesmas perguntas utilizadas para identificar uma agregação sugeridas por Medeiros (2004). A diferença é que, se a resposta à segunda pergunta for não, você terá uma composição.

Diagrama de classe

Um diagrama de classe é representado por um conjunto de classes relacionadas entre si. É um dos diagramas mais importantes da modelagem orientada a objetos.

Diagrama de caso de uso

O diagrama de caso de uso descreve as funcionalidades do sistema, demonstrando as interações externas. Segundo o OMG (2013), um caso de uso é a especificação de um conjunto de ações executado tipicamente por um sistema que entrega um resultado observável que é de valor para um ou mais atores ou outros interessados no sistema.

Em relação ao caso de uso, é necessário identificar as funcionalidades do sistema em relação às interações com os atores. As funções indicadas nos casos de uso são ações que estes desempenham no sistema. Geralmente, utiliza-se um verbo no infinitivo acompanhado de um substantivo. Por exemplo: abrir conta, efetuar saque, atualizar histórico, realizar pagamento etc. poderiam ser casos de uso de um sistema bancário.
O ator deve interagir com o sistema por meio de relacionamentos. A comunicação ocorre por meio de linhas com ou sem setas; esta última indica um relacionamento bidirecional ou de duas direções. Vale ressaltar que as linhas utilizadas para indicar relacionamentos em diagramas de caso de uso não são fluxo de dados.
Os diagramas de caso de uso devem ser elaborados após análise e estudo aprofundados sobre o funcionamento do sistema a ser desenvolvido. Na próxima seção, esse assunto é tratado com mais detalhes.
Blaha e Rumbaugh (2006) relacionam os seguintes princípios para a construção de diagramas de casos de uso:
  • Em primeiro lugar, determine os limites do sistema.
  • Tenha certeza de que os atores estão focalizados. Cada um deles deve ter um propósito único e coerente.
  • Cada caso de uso deve fornecer valor aos usuários.
  • Relacione casos de uso e atores. Cada caso de uso deve ter pelo menos um ator, e cada ator deve participar de pelo menos um caso de uso. Um caso de uso pode envolver vários atores, e um ator pode participar de vários casos de uso.
  • Lembre-se de que os casos de uso são informais. É importante não exagerar no formalismo ao especificá-los.
  • Os casos de uso podem ser estruturados. Para muitas aplicações, os casos de uso individuais são completamente distintos. Para grandes sistemas, eles podem ser construídos de fragmentos menores usando relações.

 Modelagem de interações

Para elaborar um diagrama de caso de uso, é necessário um estudo detalhado sobre cada parte do funcionamento do sistema. O analista deve criar uma documentação própria para especificar cada um dos detalhes. Como sugestão, podem-se criar tabelas ou formulários em que as identificações estarão documentadas.

domingo, 3 de maio de 2020

Modelagem de Classes

Objetos e Classes

Antes de iniciar a prática da modelagem orientada a objetos, é importante conhecer alguns conceitos que são aplicados nos diagramas UML.
Para Blaha e Rumbaugh (2006), objeto é um conceito, uma abstração ou algo com identidade que possui significado para uma aplicação. Portanto, objetos são coisas do mundo real, como pessoas, animais, carros etc.
Todos os objetos possuem identidade, conforme vimos. Um cliente é diferente de outro cliente, pois cada um possui as suas características próprias (atributos), por exemplo, o poder aquisitivo, o sexo, a altura etc. Dessa forma, a modelagem OO modela objetos do mundo real. Modelar objetos significa estudá-los e observá-los com o objetivo de representá-los dentro de um contexto.
Quando você observa o que é e o que faz um objeto em uma aplicação, você está usando a abstração. Os objetos podem ser agrupados pelos seus atributos e pelas suas operações. Por meio desses agrupamentos, podemos classificá-los. Esse procedimento é chamado classificação, no qual os objetos com a mesma estrutura de dados (atributos e operações) são agrupados em uma classe.

“Uma classe descreve um grupo de objetos com as mesmas propriedades (atributos), comportamentos (operações), tipos de relacionamentos e semântica” (BLAHA; RUMBAUGH, 2006).
Uma classe, na notação UML, é representada por um retângulo subdividido em três partes: nome da classe, atributos e operações.

Um objeto é uma instância de uma classe.

Atributos e operações

Um atributo é uma propriedade de uma classe. Os atributos são compostos por nome, tipo de dado, visibilidade e valor inicial ou padrão, cujas especificações são:
  • O nome do atributo geralmente indica o seu conteúdo.
  • O tipo de dado indica a organização dos conteúdos dos atributos. Por exemplo: o número da conta corrente é formado por números. Assim, o atributo número da conta corrente é do tipo “número”. Os tipos de dados genéricos podem ser texto, número, lógico, data etc. Esses tipos genéricos deverão ser substituídos pelos nomes dos tipos de dados da respectiva linguagem de programação utilizada para o desenvolvimento da aplicação.
  • A visibilidade de um atributo é definida como:
    • Pública (public): representada por um sinal de adição (+). Indica que o atributo é acessível por outras classes.
    • Privada (private): representada por um sinal de subtração (-). Indica que o atributo é acessível somente pela própria classe.
    • Protegida (protected): representada por um sinal de sustenido (#). Indica que o atributo é acessível somente pela própria classe e pelas subclasses.
    • Pacote (package): representada por um til (~). Indica que o atributo é acessível pelas classes do pacote que o contém.
  • O valor inicial ou padrão é um valor indicado para identificar o conteúdo inicial do atributo.
 As operações são funções (ações) ou comportamentos que podem ser aplicados a objetos ou por objetos em uma classe.

Todos os objetos de uma classe compartilham as mesmas operações, e a mesma operação pode se aplicar a muitas classes diferentes. Vale aqui lembrar o conceito de polimorfismo, que significa que a mesma operação pode se comportar de forma diferente para diferentes classes.

Um método ou função é a implementação de uma operação para uma classe. Isso significa que, quando o programador codifica uma operação em arquivos de códigos numa linguagem de programação, ele transformou uma operação em um método. Assim, a operação é definida pelo analista, e o método ou função, pelo programador.
As características de uma operação são: nome, lista de argumentos (parâmetros), visibilidade e tipo de retorno, conforme as especificações:
  • Nome e visibilidade correspondem às mesmas definições dos atributos.
  • Lista de argumentos (parâmetros) e valor de retorno dependem da linguagem de programação utilizada.

Generalização e herança

O conceito de generalização é definido por Blaha e Rumbaugh (2006) como sendo o relacionamento entre uma classe (superclasse) e uma ou mais variações dela (subclasses). A generalização organiza as classes por suas semelhanças e diferenças.

Os relacionamentos entre a superclasse e as subclasses devem ser indicados por setas com uma ponta “aberta”.

Herança é a capacidade de uma ou mais subclasses herdarem os atributos e as operações da superclasse por meio do relacionamento de generalização.

sábado, 2 de maio de 2020

UML

A partir de 1994, Grady Booch e James Rumbaugh criaram o Método Unificado, versão 0.8, por intermédio da Rational Corporation. Em 1995, Ivar Jacobson juntou-se à equipe com o seu método OOSE. Em 1996, a Rational encaminhou à OMG (Object Management Group) uma proposta para uma notação padrão de modelagem orientada a objetos, que, por unanimidade, foi aceita pela entidade. Nesse mesmo ano, foi criada a ferramenta UML – Unified Modeling Language, versão 0.9, que agrega os conhecimentos dos três autores.
A UML - Unified Modeling Language (Linguagem de Modelagem Unificada) foi criada em 1996 por Jacobson, Booch e Rumbaugh. Em 1997, a Rational lançou a UML versão 1.0. No mesmo ano, com a participação de novos colaboradores, foi lançada a versão 1.1 revisada, e, em meados de 1998, a versão 1.2. A partir desta, novas revisões foram editadas, conforme consta no site oficial da OMG (Object Management Group).

A UML não é um método, não é uma linguagem de programação e não é uma especificação para ferramentas de modelagem. Ela é uma linguagem de modelagem.

O OMG (2014) conceitua UML como “linguagem para especificação, construção, visualização e documentação de artefatos de um sistema de software intensivo”. Nesse caso, artefatos significam testes, projetos, protótipos, requisitos, códigos etc.
A UML utiliza uma notação padrão, comum a todos os ambientes e empresas. Os modelos são documentados e publicados com alcance mundial. Sua notação e sua semântica permitem que as necessidades dos usuários sejam atendidas com qualidade.
Para utilizar a UML de forma eficiente e produtiva, são necessárias ferramentas que auxiliam na modelagem.

Algumas das principais ferramentas disponíveis no mercado para modelagem UML incluem:
  • Enterprise Architect (Sparx Systems)
  • MS Visio (Microsoft)
  • System Architect (Choose Technologies)
  • Poseidon (Gentleware)
  • Together (Borland)
  • Rational Software Architect (IBM)
  • Astah (Change Vision Inc.)
  • PowerDesign (Sybase)
Certamente há outras ferramentas, cada uma delas com suas especificações e características individuais. Assim, torna-se necessário escolher aquela que atenda às reais necessidades de cada projeto.
De acordo com Page-Jones (2001), os sete objetivos que Booch, Jacobson e Rumbaugh estabeleceram para si próprios ao desenvolverem a UML são:
  1. Prover aos usuários uma linguagem de modelagem visual expressiva e pronta para uso, de forma que eles possam desenvolver e intercambiar modelos significativos;
  2. Prover mecanismos de extensibilidade e especialização para ampliar os conceitos centrais;
  3. Ser independente de linguagens de programação e processos de desenvolvimento particulares;
  4. Prover uma base formal para entendimento da linguagem de modelagem;
  5. Estimular o crescimento do mercado de ferramentas orientadas a objetos;
  6. Suportar conceitos de desenvolvimento de nível mais alto, tais como colaborações, estruturas, modelos e componentes;
  7. Integrar as melhores práticas.
Page-Jones ainda acrescenta quatro objetivos que estão implícitos no trabalho dos criadores da UML e foram atingidos com êxito:
  1. Existência de uma UML mais simples dentro de uma UML abrangente e geral.
  2. Utilização em diversas perspectivas de modelagem.
  3. Existência de correspondência com o código suficiente para permitir reengenharia.
Utilização assistida por computador e também de forma manual.

A UML utiliza diagramas para representar um software durante todo o ciclo de vida de um sistema. Junto com a notação gráfica, a UML também especifica os significados, isto é, a semântica dos modelos. Assim, a UML não é uma metodologia de desenvolvimento, o que significa que ela não diz o que se deve fazer primeiro e em seguida como projetar seu sistema, mas auxilia a visualizar o desenho e a comunicação entre objetos do sistema sendo modelado.

sexta-feira, 1 de maio de 2020

Certificação CTFL ou CBTS

Após algumas comparações. Achei a certificação CTFL a mais vantajosa. Por ter validade indeterminada, reconhecimento internacional, material gratuito e pagamento em real.
Interessante que a CBTS cobra em dólar, mas não tem reconhecimento internacional.
Abaixo uma breve comparação entre a CTFL e a CBTS:

CTFL: Órgão certificador (BSTQB / ISTQB); Validade (Indeterminada); Território de aceitação (Internacional); Material (Apostila e glossário); Custo do Material (Gratuito); Simulado oficial (Sim); Simulados variados na internet (Sim); Língua da prova (Português ou Inglês); Moeda de pagamento (Real).

CBTS: Órgão certificador (ALATS); Validade (03 anos); Território de aceitação (Nacional); Material (Livro); Custo do Material (Pago); Simulado oficial (Não); Simulados variados na internet (Sim); Língua da prova (Português); Moeda de pagamento (Dólar).