Olá sejam bem-vindos ao canal engenharia de software com ênfase uml Eu sou professor Denis Gets e eu já atuo na área de modelagem de software há vários anos eu tenho quatro livros publicados sobre o assunto e eu já ministrei diversas palestras cursos técnicos so modelagem de software utilizando a linguagem uml na aula de hoje eu vou dar continuidade ao tema sobre ma cheiros de código dessa vez abordando os ma cheiros do tipo abusadores da orientação objetos Então vamos iniciar nossa aula Então esta é a segunda aula sobre ma cheiros de código e como eu falei
eu vou tratar sobre abusadores da orientação objetos que é uma das grandes classificações dos mau cheiros de código na aula anterior nós falamos sobre blotters ou arenques defumados ou inchados hoje nós vamos falar sobre abusadores da orientação objetos Então vamos iniciar bom eh Então esse tipo de mau cheiro eles representam situações em que os princípios da programação orientado a objetos Eles foram mal aplicados Ou foram distorcidos eles foram utilizados de maneira eh errada e podem por esse motivo apresentar diversos eh problemas como problemas de manutenção ou mesmo gerar eh erros de utilização do software bom
o objetivo da programação orientada a objetos é é organizar o código de maneira a refletir o mundo real o objetivo Entre outros motivos para facilitar a reusabilidade a modularidade e a manutenção porém algumas práticas podem acabar abusando dessa filosofia isso leva a problemas no projeto de software pode dificultar Como já falei a manutenção A reusabilidade do código e mesmo fazer com que erros surjam ã quando o software for ser utilizado Ah então alguns marcheiros desse tipo são os mais conhecidos são declarações Suit ou complexidade condicional Campos temporários legado recusado e classes alternativas com interfaces diferentes
vamos falar um pouquinho sobre cada um deles então vamos falar sobre declarações Suit ou complexidade condicional Ah então esse tipo de ma cheiro ele ocorre quando se utiliza declarações sutch com código razoavelmente complexo ou muitas sequências de ifs com código relativamente complexo ah na verdade uma das marcas da orientação objetos é o uso bastante raro do Switch o Switch até pode ser utilizado ã para escolher entre eh alternativas simples mas no momento que existe um certo grau de complexidade o uso de switch ou uso de vários zfs h não é recomendado Então quais são as
razões para esse problema razões Para que ocorra esse mau cheiro eh então ah o problema Um dos problemas é que o código para um sutch ele pode estar espalhado em vários lugares no código então se Uma Nova Condição for adicionada é necessário então encontrar todas as ocorrências do Suits E modificá-los então Como regra básica quando existem Suits deve-se pensar se não vale a pena substituí-los por alternativas como polimorfismo bom eh vou falar um pouquinho sobre as violações e problemas que podem ser causados por esse mau cheiro Bom primeiramente eh esse mau cheiro ele viola o
princípio da responsabilidade única o srp ou single responsibility principal que basicamente declara que deve haver somente uma responsabilidade para um método ou um trecho de código para uma classe ou um trecho de código ã então um operador Switch ou uma sequência de ifs que trabalhem com múltiplas condições eles podem violar Esse princípio eles podem eh aglomerar podem englobar ã várias funções várias funcionalidades um outro problema é que há uma dificuldade em com relação à extensibilidade e modificabilidade do código então um Switch ou um conjunto de if complexos TNA o código difícil de manter de alterar
então no momento que for necessário adicionar um novo Case um novo if ou alterar a lógica dentro de um cas de um if é muito Provável que seja necessário mexer em blocos de código que já apresentam complexidade Ah E que provavelmente se tornarão mais complexos ainda isso pode levar a erros um outro problema é polimorfismo não utilizado ah normalmente se recomenda que em vez de se usar um sutch um conjunto de ifs para representar o comportamento de várias classes ou vários objetos então Eh deve-se utilizar polimorfismo se sugere que se utilize polimorfismo Aqui nós temos
o exemplo pode-se definir uma interface ou uma classe abstrata com um método que cada classe concreta implemente de maneira diferente isso eliminaria a necessidade de verificar tipos ou estados isso seria delegado para essas classes Ahã um outro problema é a dificuldade em criar testes unitários então estruturas de controle com complexas estruturas de controle de fluxo complexas elas não são muito simples de criar testes unitários eficazes porque o código ele se torna menos modular e mais difícil de isolar ã bom e quais são os tratamentos para esse tipo de ma cheiro então eh para isolar o
switch e colocá-lo na classe correta pode-se por exemplo mover o código para um novo método separado e substituir o código antigo por uma chamada a esse método uma outra alternativa criar subclasses enfocando os Ramos condicionais então criar o método compartilhado e mover o código do ramo correspondente para esse método e então substituir o condicional pela chamada do método em questão Ah uma outra alternativa se não há muitas condições e todas elas chamam o mesmo método com parâmetros diferentes então o o polimorfismo não será adequado nessa situação então uma alternativa seria dividir o método em múltiplos
métodos menores e mudar o Suit de acordo com esses métodos ainda pode pensar em aplicar padrões de projeto como state o strategy ou comand que eles têm a vantagem de melhorar a legibilidade e facilitam a manutenção do código além de permitir que novos comportamentos sejam adicionados sem eh ser preciso modificar estruturas existentes Qual é a recompensa para esse tipo de refatoração há uma melhor organização do código e por cons a sua complexidade diminui Vamos falar agora sobre um outro ma cheiro de código que é os campos temporários então isso ocorre quando existem Campos que só
são utilizados em certas circunstâncias ou seja ele só recebem valor eh em determinados situações na maioria das outras eles são deixados vazios Ah então quando ocorre uma situação em que uma classe ela possui Campos que só são utilizados sobre determinadas condições ou por determinados métodos mas que esses campos são ignorados em todas as outras situações isso pode indicar um projeto pobre ou um projeto inadequado ah Quais são as razões para esse mau cheiro Ah isso pode ocorrer eh quando são criados vários Campos temporários para uso em um determinado algoritmo que pode requerir uma grande quantidade
de entradas então ao invés de criar um grande número de parâmetros No método o que por si só já caracteriza um outro macheiro de código então se decide criar Campos para esses dados na classe ã e esses campos eles são utilizados somente naquele algoritmo e ficam sem uso em qualquer outra situação Ah esse tipo de código ele costuma ser difícil de entender porque muitas vezes se esperam ver dados nos campos de objeto mas muitas vezes eles vão estar vazios Qual é o tratamento para esse mal cheio de código bom pode-se então Eh mover os campos
temporários e o código associado a eles para uma classe separada então Eh se esses campos eles forem ser utilizado somente em determinadas condições então eles podem ser extraídas extraídos por uma classe específica que vai encapsular a lógica ah desses Campos juntamente com o comportamento a ele associado então isso irá reduzir o acoplamento e melhorar a coesão dentro da classe original Ah uma outra alternativa seria utilizar subclasses para encapsular o comportamento condicional Então se o comportamento que utiliza Campos temporários for específico a uma condição ah a criação de subclasses pode permitir que vários comportamentos sejam representados
de forma Clara e isso elimina a necessidade de Campos temporários ainda pode-se pensar em utilizar padrões de projeto para que seja encapsulado o comportamento condicional então Eh os padrões de projeto eles podem ser por exemplo strategy ou state que eles podem ser utilizados para essa função Ah vamos falar agora sobre um outro ã mau cheiro de código que é o legado recusado ou refuse the bequest Ah esse mau cheiro costuma ocorrer quando uma classe ela erda propriedades de Out de uma de uma superclasse propriedades como atributos ou métodos mas que H na verdade ela não
utiliza tudo que foi dado utiliza apenas uma parte Ah então isso pode eh denotar que há um problema na hierarquia de classes e sugere que a herança ela está sendo usada de maneira inadequada ou que as classes foram mal projetadas Quais são as razões para esse problema então Eh como já foi falado costuma ocorrer quando uma hierarquia de classe uma herança ela é utilizada de maneira inadequada obviamente com objetivo de utilizar o código da superclasse mas ainda assim de forma de forma errada ah a superclasse e as suas subclasses elas são muito diferentes entre si
eh elas não compartilham exatamente o o mesmo propósito e os mesmos comportamentos Então essas classes elas ficam em desacordo [Música] ã com relação ao que a superclasse ela oferece e o que a subclasse realmente precisa Ah então o resultado São um conjunto de métodos ou propriedades que foram herdados mas que não fazem sentido ou simplesmente são desnecessários n nas subclasses Qual é o tratamento para esse malche de código então qu herança não faz sentido se as subclasses elas compartilham pouco em comum com a superclasse então a herança Possivelmente ela não é adequada então ela deve
ser removida e se substituída por exemplo por uma associação de composição outra situação ã ah eliás continuando essa solução ah depois disso se cria um campo na subclasse que conté um objeto superclasse e deve se delegar a chamadas de método apropriados para ele mantendo o comportamento necessário dessa forma se elimina a dependência de herança inadequada e se cria uma relação mais flexível entre as classes ah numa outra situação a herança é apropriada mas existem vários elementos desnecessários Então deve se extrair os elementos relevantes para a subclasse e colocados em uma nova superclasse que seja mais
especializada e que seja realmente adequada às necessidades da subclasse ã então a herança inadequada vai ser substituída pela atual E assim a a subclasse ou subclasses irão herdar a propriedades e métodos que elas realmente precisam Então aquela herança inadequada aquela herança errada vai ser substituído Qual é a recompensa para esse refaturamento há uma melhora na clareza e na organização do código H uma maior facilidade de manter o código evoluir o código a complexidade reduzida é mais fácil produzir testes e o código pode ser reutilizado com mais facilidade Vamos falar agora sobre classes alternativas com interfac
diferentes então este mau cheiro ele se caracteriza por existência de duas ou mais classes que fornecem comportamentos semelhantes mas que utilizam métodos diferentes e ou apis ou interfaces incompatíveis api significa application program interface ou interface de programa de aplicação bom então esse macheiro ele resulta em um código inconsistente e difícil de utilizar compreender e alterar razões para problema pode acontecer de os programadores irem criando novas classes eh e sem saber que já existiam classes com funcionalidades equivalentes isso ocorre principalmente devido à falta de documentação adequada no projeto ou no código e também com rela a
falta de comunicação entre a equipe de desenvolvimento um princípio dos métodos ágeis não está sendo eh obedecido adequadamente que é a constante comunicação entre equipe Ah qual é o tratamento para esse mau cheiro então deves tentar unificar a interface das classes eh em termos de um denominador comum deve se aplicar uma das possíveis abordagens uma delas eh renomear os métodos para tornar todos idênticos em todas as classes alternativas dessa forma fazendo uma maior consistência na interface uma outra alternativa mover os métodos ou adicionar parâmetros de tal forma que os métodos possam ser parametrizados Isso vai
tornar a assinatura ou seja o conjunto de parâmetros e a implementação dos métodos mais coerente e compatível entre as classes eh outra forma se somente uma parte da funcionalidade está duplicada Então deve se mover o que é comum para uma superclasse e especializar a as classes a partir da dessa subclasse dessa superclasse então transformar as classes problemáticas em subclasses então elas vão informar vão herdar o que é comum e não vão ter métodos repetidos Ah também pode tentar aplicar padrões de projeto Como por exemplo o adapter ou facet então o adapter que significa adaptador o
nome já diz ele utiliza um adaptador quando as classes tem interfaces que são incompatíveis mas que oferecem funcionalidades ou funções semelhantes então o adaptador ele vai converter uma Interface para uma forma que possa ser entendida por outra por outra eh sem modificar o código original e o facit ele eh deve ser utilizado quando se deseja simplificar e unificar o acesso a várias classes com interfaces diferentes Então se cria uma interface mais amigável e Coesa Qual é a recompensa para essa refatoração bom o código desnecessário ele vai ser eliminado código duplicado Aliás o código duplicado desnecessário
será eliminado código duplicado é um problema grave em programação e o código ele se torna menor mais fácil de ler mais fácil de entender e nós concluímos mais essa aula eu espero que vocês tenham considerado esta aula adequada espero que vocês tenham gostado desse vídeo se vocês gostaram desse vídeo eu peço que vocês curtam esse vídeo compartilhem esse conteúdo com quem possa interessar e se ainda não estão inscritos eu peço que se inscrevam obrigado pela atenção nós nos vemos na próxima aula