Sou um aluno que ingressou recentemente em uma empresa de desenvolvimento de software como estagiário. De volta à universidade, um de meus professores costumava dizer que devemos nos esforçar para alcançar “baixo acoplamento e alta coesão”.

Eu entendo o significado de baixo acoplamento. Significa manter o código de componentes separados separadamente, de modo que uma mudança em um lugar não quebre o código em outro.

Mas o que se entende por alta coesão? Se isso significa integrar bem as várias peças do mesmo componente umas com as outras, não entendo como isso se torna vantajoso.

O que significa alta coesão? Um exemplo pode ser explicado para entender seus benefícios?

Comentários

  • possível duplicata de Existem Métricas para coesão e acoplamento?
  • O artigo da wikipedia não responde sua pergunta suficientemente? en.wikipedia.org/wiki/Cohesion_(computer_science)
  • Há um bom artigo sobre isso em: msdn.microsoft.com/en-us/magazine/cc947917.aspx
  • @EoinCarroll: Infelizmente, o artigo da wikipedia no momento atual não traz nenhum valor exemplos concretos com os quais novos programadores podem trabalhar. A teoria é boa e tudo, mas não ' realmente dura até que você ' tenha cometido os erros que cercam a baixa coesão. Alta coesão é um daqueles tópicos que levei vários anos de programação para entender completamente por que ela é importante e como alcançá-la.
  • Eu nunca realmente entendi Coesão até ler Código limpo. Você também deveria.

Resposta

Uma maneira de olhar para a coesão em termos de OO é se os métodos em a classe está usando qualquer um dos atributos privados. Usando métricas como LCOM4 (falta de métodos coesivos), conforme apontado por gnat nesta resposta aqui , você pode identificar classes que podem ser refatoradas. O motivo pelo qual você deseja refatorar métodos ou classes para serem mais coesos é que isso torna o design do código mais simples para que outros o usem . Confie em mim; a maioria dos líderes de tecnologia e programadores de manutenção vão adorar quando você corrigir esses problemas.

Você pode usar ferramentas em seu processo de compilação, como Sonar para identificar baixa coesão na base de código. Existem alguns casos muito comuns nos quais posso pensar em que os métodos têm baixa “coesão” :

Caso 1: o método não está relacionado à classe de forma alguma

Considere o seguinte exemplo:

 public class Food { private int _foodValue = 10; public void Eat() { _foodValue -= 1; } public void Replenish() { _foodValue += 1; } public void Discharge() { Console.WriteLine("Nnngghhh!"); } }  

Um dos métodos , Discharge(), carece de coesão porque não atinge nenhum dos membros privados da classe. Neste caso, há apenas um membro privado: _foodValue. Se ele não faz nada com as partes internas da classe, ele realmente pertence a ela? O método poderia ser movido para outra classe que poderia ser chamada, por exemplo, FoodDischarger.

 // Non-cohesive function extracted to another class, which can // be potentially reused in other contexts public FoodDischarger { public void Discharge() { Console.WriteLine("Nnngghhh!"); } }  

Você está fazendo isso em Javascript, uma vez que as funções são objetos de primeira classe, o pode ser uma função gratuita:

 function Food() { this._foodValue = 10; } Food.prototype.eat = function() { this._foodValue -= 1; }; Food.prototype.replenish = function() { this._foodValue += 1; }; // This Food.prototype.discharge = function() { console.log("Nnngghhh!"); }; // can easily be refactored to: var discharge = function() { console.log("Nnngghhh!"); }; // making it easily reusable without creating a class  

Caso 2: Classe de utilitário

Este é realmente um caso comum que quebra a coesão. Todo mundo adora classes de utilitário, mas elas geralmente indicam falhas de design e na maioria das vezes tornam a base de código mais complicada de manter (por causa da alta dependência associada às classes de utilitário). Considere as seguintes classes:

 public class Food { public int FoodValue { get; set; } } public static class FoodHelper { public static void EatFood(Food food) { food.FoodValue -= 1; } public static void ReplenishFood(Food food) { food.FoodValue += 1; } }  

Aqui podemos ver que a classe de utilitário precisa para acessar uma propriedade na classe Food. Os métodos na classe de utilitário não têm coesão nenhuma neste caso porque precisa de recursos externos para fazer seu trabalho. Neste caso, não seria melhor ter os métodos na classe com os quais eles estão trabalhando ( bem como no primeiro caso)?

Caso 2b: Objetos ocultos em classes de utilidades

Há outro caso de classes de utilidades onde há objetos de domínio não realizados. A primeira reação automática um programador tem quando a manipulação de string de programação é escrever uma classe de utilitário para ela.Como este aqui, que valida algumas representações de string comuns:

 public static class StringUtils { public static bool ValidateZipCode(string zipcode) { // validation logic } public static bool ValidatePhoneNumber(string phoneNumber) { // validation logic } }  

O que a maioria não percebe aqui é que um código postal, um número de telefone ou qualquer outra representação de string pode ser um objeto em si:

 public class ZipCode { private string _zipCode; public bool Validates() { // validation logic for _zipCode } } public class PhoneNumber { private string _phoneNumber; public bool Validates() { // validation logic for _phoneNumber } }  

A noção de que você não deve” “manusear strings” diretamente é detalhada nesta postagem do blog por @codemonkeyism , mas está intimamente relacionado à coesão porque a maneira como os programadores usam strings ao colocar a lógica em classes de utilitários.

Comentários

Resposta

Alta coesão significa manter coisas semelhantes e relacionadas juntas, para acoplar ou fundir partes que compartilham conteúdo, funcionalidade, razão ou objetivo . Em outras palavras, baixa coesão pode, por exemplo, significar uma função / classe / entidade de código que serve a vários propósitos ao invés de ser “ direto ao ponto “. Uma das melhores ideias é fazer uma coisa e fazê-la bem . Outros podem incluir o fato óbvio de que você não replica funcionalidade semelhante em muitos lugares. Isso também melhora a localidade da base de código, certos tipos de coisas são encontrados em um determinado lugar (arquivo, classe, conjunto de funções, …) em vez de estarem espalhadas.

Como exemplo, considere uma classe que serve a dois ou três propósitos: Carrega / armazena recursos (por exemplo, um arquivo) e, em seguida, analisa e exibe o conteúdo. Tal classe tem coesão baixa porque gerencia pelo menos duas tarefas separadas que não estão relacionadas de forma alguma (E / S de arquivo, análise e exibição). Um design de alta coesão pode usar classes distintas para carregar e armazenar o recurso, analisá-lo e, em seguida, exibi-lo.

Por outro lado, o baixo acoplamento visa manter coisas distintas separadas – de modo que elas interajam umas com as outras. o mínimo possível, o que reduz a complexidade e simplifica o design.

Resposta

Significa que as partes de um objeto estão intimamente relacionadas à função do objeto. Isso significa que há muito pouco ou nenhum desperdício dentro do objeto em termos de função ou responsabilidade. Isso, por sua vez, pode melhorar a compreensão de para que o objeto em questão deve ser usado.

Comentários

  • não ' Isso também se aplica a um nível mais alto do que apenas objetos? por exemplo, agrupar objetos / funções relacionados a uma tarefa em namespaces?

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *