Baixe o app para aproveitar ainda mais
Prévia do material em texto
Um Mecanismo para Identificação da Congeneridade em Sistemas Orientados a Objeto Leandro Oliveira, Carlos Michel Betemps Centro Universitário Lasalle – Unilasalle CEP 92010-000 - Canoas – RS – Brasil leandro.ol@gmail.com, betemps@unilasalle.edu.br Abstract. The connascence, applied to the context of software development, is the indication that an element has some type of relationship with another element. Relationship means interdependence; witch indicates that elements of the same type need to be evaluated in case of an alteration or creation of other elements and devices of software development. In case of Object Oriented drawing, the connascence is an indication of the application of good practical drawing. The connascence among software elements is wide, however, as it's a initial idea and not very common in software development environments, this work considers an alternative for its visualization in the Class Model of the UML. Resumo. A congeneridade, aplicada ao contexto de desenvolvimento de software, é a indicação de que um elemento tem algum tipo de relacionamento com outro elemento. Por relacionamento, entende-se interdependência, que indica que elementos congêneres precisam ser avaliados no caso de uma alteração ou na criação de outros elementos e artefatos de desenvolvimento de software. No caso de desenho orientado a objeto, a congeneridade é a uma indicação da aplicação de boas práticas de desenho. A congeneridade entre elementos de software é ampla, porém, por se tratar de uma idéia inicial e pouco comum nos ambientes de desenvolvimento de software, este trabalho propõe uma alternativa para sua visualização em modelos de classes UML. 1. Propriedades da orientação a objeto O encapsulamento e a congeneridade não são propriedades de codificação de programas exclusivos do paradigma orientado a objetos. Elas também podem ser avaliadas em sistemas estruturados, porém, devido à concepção de novas complexidades dentro da orientação a objetos, elas têm suas respectivas importâncias significativamente elevadas. A compreensão e manutenção do software orientado a objetos estão totalmente baseados nos níveis de encapsulamento e em seu grau de congeneridade. Um bom software orientado a objetos depende destas duas variáveis. É impossível falar de congeneridade sem comentar alguns detalhes da propriedade do encapsulamento. A evolução das arquiteturas de programação implicou no vínculo de níveis de encapsulamento. No caso de sub-rotinas – estruturas que agrupam linhas de código para resolução de problemas menores de um todo – tem-se encapsulamento de nível 1. A orientação a objetos que concebe a estrutura de classes reflete um encapsulamento de nível 2. Os níveis de encapsulamento são definidos e utilizados por Page-Jones [PAGE-JONES 2001]. Outros níveis superiores de encapsulamento poderiam ser citados, onde se encontram as estruturas de pacotes e componentes, mas para um início de estudo de congeneridade a proposta se limita ao nível 2. O termo congeneridade não se origina na Ciência da Computação. Em sua concepção, a expressão significa “terem nascido juntos”. Dois elementos são congêneres (do mesmo gênero) quando a existência de um influencia na existência do outro. Em qualquer fase de desenvolvimento de um software, elementos congêneres são gerados por alguma necessidade comum. 1.1. Melhoria no processo de desenvolvimento de software Existe a carência de mecanismos para avaliação da congeneridade tanto explícita como implícita. A congeneridade explícita, apesar de facilmente percebida através de editores de programas ou ferramentas de buscas de texto, é trabalhosa e a criação de um recurso que auxilie este processo de avaliação de forma rápida seria de grande validade. A percepção da congeneridade implícita não é tão trivial, principalmente em se tratando de sistemas que já não podem mais ser considerados pequenos e de manutenção simples. Esta avaliação requer atenção minuciosa apoiada por uma documentação rica do sistema em avaliação. Neste caso uma ferramenta de apoio teria um valor maior ainda. Em ambientes em que sistemas detêm grande responsabilidade pelo funcionamento de sua estrutura, seja pela importância das informações contidas, seja pela sua complexidade, a manutenção pode tornar-se um procedimento extremamente caro. Algumas das variáveis deste custo são o acoplamento e a congeneridade excessivos entre os objetos. Um mecanismo de apoio à avaliação destas características pode ser útil para facilitar e minimizar os custos de manutenção. 1.2 A propriedade da congeneridade Em desenvolvimento de software a congeneridade pode ser notada no seguinte exemplo de código: int valor; // linha de código A valor := 100; // linha de código B Caso a variável “valor” tivesse seu tipo alterado para char, a atribuição do valor à variável que ocorre na linha B não poderia ocorrer. Tem-se neste caso uma congeneridade de tipo. Se a variável “valor” tivesse seu nome alterado para “valorInicial” obrigatoriamente a linha B também teria de ser alterada. Trata-se de uma congeneridade de nome. Ambos os casos apresentam uma congeneridade explícita facilmente detectável em um editor de programas. Mais adiante, neste texto, onde será detalhada a congeneridade de posição, a ocorrência da congeneridade implícita será comentada. Este tipo de congeneridade não é de tão fácil percepção como a explícita. Existem alguns pontos sobre congeneridade que devem ser salientados [PAGE- JONES 2001]: • Dois elementos de software não precisam se comunicar para serem congêneres. • Algumas formas de congeneridade são direcionais. Se um elemento X refere-se diretamente ao elemento Y, o elemento X é unidirecionalmente congênere, pois existe o sentido de X para Y. No caso de elementos que tem direcionamento recíproco tem-se congeneridade bidirecional. • Algumas formas de congeneridade não são direcionais. Caso X e Y se utilizem de um mesmo algoritmo mas não houver referência entre eles existe a congeneridade porém, sem nenhum direcionamento. Este artigo desconsidera a congeneridade existente nos aspectos dinâmicos de software. O descrito até então aborda a congeneridade estática. Abaixo serão descritos outros casos deste tipo, bem como, detalhadas com mais clareza, as congeneridades de nome e de tipo/classe [PAGE-JONES 2001]: • Congeneridade de nome: indica que dois elementos, podem ser eles classes, atributos, operações, tipos, etc, estão nomeados da mesma forma. Isto pode ocorrer em uma hierarquia de classes onde uma determinada propriedade da classe filha possui o mesmo nome da classe mãe. Uma mudança neste elemento implica na análise de sua relação. • Congeneridade de tipo ou classe: esta congeneridade ocorre quando um elemento é definido como “um tipo de” e uma possível atribuição de conteúdo a este elemento deve ser compatível com o tipo declarado. • Congeneridade de convenção: refere-se a valores pré-concebidos que um atributo pode conter. O software que acessa este atributo terá comportamentos diferentes conforme o valor encontrado. Como o nome diz, existe a convenção de valores pré- definidos que serão utilizados pelo software. Esta convenção pode ser de conhecimento mundial como medidas de distância (metros, milhas, etc) ou de conhecimento específico como a regra de negócio de uma empresa, de uma pesquisa, etc. • Congeneridade de algoritmo: é similar a congeneridade de convenção e trata da utilização comum de determinados componentes em vários pontos de um software. Um determinado trecho de código que deveria estar encapsulado em uma rotina por meio de um procedimento em código estruturado ou uma operação de uma classe, mas que, por algum motivo encontra-se espalhado em vários pontos de um sistema, apresenta congeneridade de algoritmopelo fato de uma possível manutenção ser obrigada a ser replicada em todas as ocorrências do código. Este tipo de congeneridade é, ou ao menos tende ser, pouco incidente em desenhos orientados a objeto. Sua maior incidência ocorre em códigos procedurais. • Congeneridade de posição: refere-se à seqüência de execução de linhas de código. Elas devem estar posicionadas na correta distribuição léxica do código. A congeneridade de posição pode ser seqüencial (ordem das linhas de código) ou adjacente (proximidade das linhas de código). Ela também pode ser notada na seqüência de parâmetros de um determinado método. A chamada deste método deve enviar os devidos valores aos parâmetros na correta posição. A congeneridade não se refere apenas à igualdade ou semelhança entre elementos. Há casos em que a diferença é fundamental e a isto se dá o nome de contrageneridade. Na contrageneridade confere-se que um método ou atributo, por exemplo, não pode ter seu nome trocado para um que já exista. Tem-se, neste caso, um exemplo clássico de possível erro em um sistema e a total necessidade de que um elemento nada tenha a ver com o outro. Especialmente na contrageneridade o encapsulamento é fundamental. Isto pode ser facilmente visualizado em um software com milhares de linhas de código. A simples criação de uma variável pode oferecer sérios riscos em sistemas fracamente encapsulados. Outro problema pode ser a dificuldade de entendimento da posição de determinadas linhas de código. Neste caso tem-se congeneridade de posição. Uma inversão de duas linhas ou a inserção de uma terceira também pode gerar problemas de funcionamento do software. O parágrafo anterior apresenta dois exemplos que podem ocorrer em um sistema que não se encontra fragmentado em unidades encapsuladas. Isto implica uma congeneridade descontrolada (principalmente referindo-se a contrageneridade) e a confusão do que é de fato uma congeneridade e o que é apenas uma similaridade acidental. Uma similaridade acidental é encontrada em um nome de uma variável comum a duas classes completamente distintas e separadas. Não há nenhum tipo de congeneridade neste caso. Qualquer uma das variáveis comuns à estas classes poderiam ter seu nome ou tipo trocado sem qualquer relação com a outra. A congeneridade é, também, uma razão do funcionamento da orientação a objetos. A orientação a objeto reduz e, em alguns casos, elimina a congeneridade desenfreada que ocorre em sistemas modulares convencionais que apresentem somente nível 1 de encapsulamento. Este problema solucionado pela orientação a objetos pode ser notado na seguinte situação: supõe-se que um determinado sistema (desenhado no nível 1 de encapsulamento) precise de uma manutenção em um determinado procedimento. Sabe- se que este procedimento é chamado em diversos pontos do sistema e que a manutenção neste procedimento acarreta mudanças em todos os pontos de chamada. Trata-se de uma congeneridade de algoritmo. O encapsulamento de nível 1 não encaminha aos locais que existem estes pontos muito menos os numera. Caso o sistema não apresente uma documentação atualizada e confiável a manutenção pode se tornar relativamente cara. Um sistema orientado a objeto com um encapsulamento de nível 2, apresenta apenas um local onde o procedimento descrito acima pode ser encontrado. O problema se encontrará encapsulado em uma fronteira e a manutenção é infinitamente mais fácil, principalmente com o apoio de um mecanismo que auxilie nesta identificação. De acordo com Page-Jones [PAGE-JONES 2001], a congeneridade apresenta três diretrizes para a melhoria no processo de manutenção de software. São elas: a minimização da congeneridade total, a minimização da congeneridade existente entre fronteiras de encapsulamento e a maximização da congeneridade dentro das fronteiras de encapsulamento. Quanto mais implícita é a congeneridade, mais tempo se consome e maior é o custo para ele ser detectada, caso ela não esteja bem documentada. Isto implica em grandes avaliações em documentação de classes, em textos ou outra forma de documento que pode consumir muito tempo e será difícil de ser encontrada. 1.3. A manutenção de sistemas no que se refere à congeneridade As diretrizes abaixo, propostas por Page-Jones [PAGE-JONES 2001] se aplicam a qualquer paradigma de construção de software de nível 2, 3 ou maior: • Minimizar a congeneridade total – isso inclui, é certo, a contrageneridade – ao fragmentar o sistema em elementos encapsulados. • Minimizar qualquer congeneridade remanescente que cruze as fronteiras de encapsulamento. • Maximizar a congeneridade dentro das fronteiras de encapsulamento. Estas diretrizes induzem ao princípio do desenho de software que dizia que era necessário agrupar coisas semelhantes e separar coisas diferentes. Porém, estas coisas semelhantes não eram bem claras ou eram subjetivas a cada desenhista ou desenvolvedor. Na verdade coisas semelhantes são elementos de software com congeneridade mútua [PAGE-JONES 2001]. A figura abaixo exibe classes com congeneridade entre elas. As setas mais espessas indicam a violação de um dos princípios da orientação a objetos onde a estrutura interna de uma classe é acessada diretamente pela outra classe. As “coisas semelhantes” foram colocadas em estruturas de software diferentes. operação classe atributo privado Figura 1. Incidência de congeneridade violando encapsulamento 2. Proposição do mecanismo de identificação da congeneridade A congeneridade tem abrangência e incidência em todo o ciclo de vida do software. Considerando que haja coerência entre as fases, casos de usos devem ser reflexo do que foi requisitado para um software, modelos de classes modelam o negócio deste software, a implementação deve ser fiel reflexo deste modelo de classes, um plano de teste deve certificar a validade e correção do que foi implementado. Nota-se, neste breve exemplo, a relação direta entre as fases de desenvolvimento. Há, então, congeneridade entre elas, ou melhor, entre os artefatos criados nestas fases. Este artigo foca a identificação da congeneridade em modelos de classes. Neles são encontrados elementos explicitamente visíveis, outros, nem tanto. Será apresentada uma proposta de solução no problema típico incidente na herança de classes. 2.1. Congeneridade de polimorfismo A figura abaixo apresenta a incidência de congeneridade de polimorfismo: Figura 2. Incidência de congeneridade de polimorfismo É possível notar que as classes “class3” e “class4” são extensões da classe “class1” e a “class5” é extensão de “class3”. Porém, “class5” implementa o método “op3class5” que por sua vez, não é definido nas suas respectivas superclasses. Seguindo os conceitos de herança, não há qualquer problema nisto não fosse o fato de uma possível chamada em um trecho de código invocar o método definido exclusivamente em “class5” utilizando o conceito de ligação tardia (a definição do método que será invocado ocorre em tempo de execução). Como “class5” é derivada de uma hierarquia de classes e seu método exclusivo não é definido, nem de forma abstrata, em suas superclasses, qualquer chamada de um objeto derivado de “class1” apresentará problemas. Tem-se, desta forma, congeneridade de polimorfismo. Esta situação aponta um possível erro de modelagem devido à particularidade criada pela operação existente exclusivamente em “class5”. Isto se deve ao fato de que esta classe pode não estar se adequando ao contexto de hierarquia a que está inserida, ou seja, “class5” pode não ser um sub-tipo de “class1” [COOK 1990]. Em termos práticos é o mesmo que dizer que “class1” define um comportamento de veículos, “class2” defineum comportamento de “carro” e “class3” define o comportamento de um barco onde a operação “op3class5”, por sua vez, desta classe, implementa um método “ancorar”. Não coerência entre esta hierarquia já que barco não é um tipo de carro apesar de ser um tipo de veículo. A figura 3 propõe uma maneira de identificação desta situação e sua descrição está descrita abaixo: • Verifica-se a incidência de hierarquia de classes (herança); • Verificam-se as assinaturas das operações na árvore da hierarquia; • Havendo incidência de sobrescrita, sobrecarga de métodos ou definição de operação apenas na(s) classe(s) filha(s), é apresenta a congeneridade de polimorfismo. Figura 3. Proposta para identificação da congeneridade de polimorfismo 2.2. Congeneridade entre outros artefatos Nesta seção serão exemplificados outros artefatos de desenvolvimento de software imaginados pelos autores deste trabalho. São itens de propostas de estudo, supostamente viáveis, que foram surgindo ao longo do tempo da pesquisa. • Congeneridade entre requisitos e casos de uso: Conforme Booch, um requisito é uma característica de projeto, uma propriedade ou um comportamento do sistema [BOOCH 2000]. Há um relacionamento direto entre requisitos de software e casos de uso. Não há cardinalidade padrão para tal mapeamento. Um requisito pode gerar n casos de uso e o contrário também é verdadeiro. Desconsiderando os processos de engenharia reversa, casos de uso são criados de forma a atender os requisitos do software. Estes artefatos são interdependentes, ou seja, possuem congeneridade. A abstração é de alto nível, porém, a avaliação desta congeneridade parece ser possível. • Congeneridade entre diagramas de seqüência de diagramas de classes: Diagramas de seqüência dão ênfase à ordenação temporal das mensagens trocadas entre os objetos [BOOCH 2000]. Para haver esta troca de mensagens entre os objetos, supondo-se haver ambos os diagramas – seqüência e classes, as mensagens e seus respectivos objetos devem estar definidas nestes diagramas. Consequentemente, a avaliação também é possível e bem semelhante ao proposto neste estudo. • Congeneridade entre processos de teste e requisitos: Considerando o processo normal e recomendado pelas melhores práticas de mercado utilizadas atualmente, os testes de software habilitam e certificam de que o software, entre outras coisas, atende os requisitos previstos. Nota-se, com isto, que não só os casos de uso estão relacionados com os requisitos, mas, também, processos de teste relacionam-se da mesma forma. • Redundância de banco de dados: No tocante ao aspecto de hardware a redundância de bancos de dados, normalmente implementada através de estruturas de espelhamento, apresentam congeneridade devido a este “espelho” não tolerar qualquer tipo de distorção de informações. 3. Conclusão Na obra de Page-Jones, fonte principal deste estudo, os tipos de congeneridade propostos são pontuais e instigantes. São propostos exemplos clássicos e problemas típicos de desenvolvimento de software. E a mensagem deixada, de forma subliminar, é de que novos tipos podem ser propostos e apresentados e de que a congeneridade é extremamente ampla. Na pesquisa realizada até a conclusão deste material não foi encontrado qualquer tipo de trabalho, pesquisa ou software que aprofundasse um estudo específico deste assunto. Pesquisas que focassem as conseqüências da congeneridade aplicada à software ou como as linguagens atuais solucionam problemas referentes a ela não foram abordadas, logo, são sugestões de outros estudos. De certa forma, este artigo é resultado da instigação do autor e tem a ambição de ser instigador de novas pesquisas. A proposta original de Page-Jones é pontual com relação aos elementos congêneres e seus tipos. Esta pesquisa também foi pontual avaliando modelos de classes. Este diagrama se enquadra nas estruturas estáticas da UML. Conseqüentemente, apenas as congeneridades estáticas foram mapeadas. Com isto, trabalhos futuros podem estender estudos com relação à indicação da congeneridade dinâmica detectada nos modelos dinâmicos e outros artefatos descritos na seção 2.2. Este artigo apresenta um raciocínio inicial da propriedade da congeneridade aplicada a software. Espera-se algo construtivo em termos científicos e alavancador de novas propostas de melhoria de desenvolvimento de software. 4. Referências Booch, G, Rumbaugh, J. and Jacobson, I. (2000) “UML guia do usuário”. Rio de Janeiro. Cook, W. R and Hill, W. L. (1990). “Inheritance is not subtyping”. ACM. Page-Jones, M. (2001). “Fundamentos do desenho orientado a objeto com UML”. São Paulo. ______. (1992). “Comparing techniques by means of encapsulation and connascence”. Communications of the ACM, v.35, n.9, p.147-151, September. Pfleeger, S. (2004). “Engenharia de Software: teoria e prática”. São Paulo.
Compartilhar