Manter minhas classes e métodos o mais pequeno possível?

20

Alguns dias atrás, eu estava conversando com uma candidata a PhD em Engenharia de Software e em algum momento ela me disse:

Mantenha suas classes e métodos o mais pequeno possível

E me pergunto se essa é sempre uma boa prática.

Quero dizer, por exemplo, vale a pena ter uma aula com apenas dois atributos? Por exemplo, em alguns métodos, preciso de pares de números inteiros para trabalhar. Devo escrever uma classe "PairOfIntgers"?

Essa maneira de pensar poderia "quebrar" o código em muitos pedaços?

Florents Tselai
fonte
10
Isso deveria ser"As small as possible, but no smaller."
StuperUser
"Quero dizer, por exemplo, vale a pena ter uma aula com apenas dois atributos?" - Pode ser, procure por "Obsessão primitiva" (por exemplo, jamesshore.com/Blog/PrimitiveObsession.html )
Torsten
Eu acho que a fonte da confusão é a palavra "possível". O princípio se torna ridículo se "possível" estiver se referindo apenas ao código, porque a menor classe possível que faz alguma coisa útil tem apenas um método (e, em alguns casos, zero). O candidato provavelmente pretendia levar em consideração a coesão e o acoplamento.
Kelvin

Respostas:

23

Há um certo grau de verdade nesse conselho, mas IMHO não é muito bem expresso, portanto é fácil entender mal e / ou levar a um extremo estúpido. De qualquer forma, isso deve ser uma regra de ouro, e não uma lei rígida. E você sempre deve implicar em tais regras a cláusula "dentro de limites razoáveis" ou "mas não se esqueça de usar seu bom senso" :-)

O princípio da verdade é que, na prática, classes e métodos sempre tendem a crescer por natureza, não a encolher . Uma correção de bug aqui, uma pequena extensão de recurso lá, lidando com um caso especial por lá ... e pronto, sua classe uma vez limpa e pequena começa a inchar. Com o tempo, seu código quase inevitavelmente tende a se tornar uma bagunça monstruosa de espaguete - a menos que você lute ativamente contra essa tendência via refatoração . A refatoração quase sempre produz muitas classes / métodos menores, de algumas grandes. Mas é claro que há um limite sensato para miniaturizar. O objetivo da refatoração não é ter classes e métodos menores em si, mas tornar seu código mais limpo, mais fácil de entender e manter. Em um certo ponto, tornar seus métodos / classes menores começa a diminuir a legibilidade, em vez de aumentá-la. Apontar para esse ótimo. É uma área-alvo embaçada e em movimento, para que você não precise acertá-la no local. Apenas melhore um pouco o código sempre que notar algum problema .

Péter Török
fonte
1
definitivamente uma regra para não seguir cegamente, muitas turmas minúsculas é muito pior do que algumas turmas maiores na maioria das vezes.
Ryathal
4
Minha regra pessoal é: se você não conseguir ver toda a implementação do método na tela de uma só vez, refatorar.
Dan Ray
6
@ DanRay, sim, eu costumava ter a mesma regra, até ler Código Limpo . Foi um choque, mas gradualmente fez com que o meu melhor diminuísse para cerca de 10 linhas.
Péter Török
2
O Código Limpo da OMI é horrível em sua extremidade em relação a métodos pequenos. O problema é que, quando os métodos são reduzidos, haverá mais deles. É claro que métodos muito longos são muito longos, mas Bob Martin parece preferir 10 métodos de 1 linha ao invés de 1 de 10 linhas (portanto, o mesmo código efetivamente ocupa cerca de 5x o espaço da tela). Talvez seja para ser algum tipo de truque educacional, não acredito que alguém realmente ache o código desse livro bom.
Joonas Pulakka
5
@JoonasPulakka - Digamos que nunca li um método e pensei: "Gostaria que esse método fizesse mais". Ao encurtar os métodos, você pode escrever nomes de métodos muito descritivos que frequentemente eliminam a necessidade de ler o corpo do método completamente. Eu achei o conselho no código limpo muito sensato. Nós apenas temos que concordar em discordar. :)
David Harkness
9

A questão mais importante a ser enfatizada aqui é criar boas abstrações . Classes pequenas que são pouco acopladas e têm alta coesão são o produto de boas abstrações .

Às vezes, faz todo sentido encapsular dois números inteiros em uma classe. Especialmente se você quiser ter métodos 'anexados' a essa classe para também encapsular como se pode manipular esses atributos e garantir que você os proteja de outras partes do programa, alterando-os.

Outro ponto positivo para criar uma classe nesse caso é que a classe pode evoluir muito melhor / melhor do que digamos uma estrutura de dados de nível mais baixo, como um mapa ou uma lista.

Terceiro, uma boa abstração pode melhorar bastante a legibilidade. As classes que aderem ao SRP geralmente são muito mais fáceis de entender por um ser humano do que as classes que não o fazem.

E apenas como uma nota final ... não importa quão bom aluno você seja ... para entender OOP e boas abstrações e quando usá-las, você precisa de experiência. Você precisa escrever um código incorreto e passar por dificuldades para mantê-lo. Você precisa ver outras pessoas escreverem um bom código para aumentar o seu conhecimento sobre o que é 'bom' e o que será um problema no futuro ... Portanto, não se espante se você não entender imediatamente.

c_maker
fonte
2

O antipadrão de Objeto de Deus é o que ela provavelmente estava se referindo. Costumo pensar que, se eu tiver um "e" na descrição da minha classe, eu deveria ter duas classes. Se eu tiver mais de dez linhas de código em um método / função, devo dividi-lo. Como o código pirata, essas são mais diretrizes do que regras.

Sardathrion - Restabelecer Monica
fonte
2

Na programação orientada a objetos, o princípio da responsabilidade única declara que todo objeto deve ter uma única responsabilidade e que a responsabilidade deve ser totalmente encapsulada pela classe. Normalmente você está fazendo mais de uma coisa se a sua turma ficar muito grande. No seu caso, a classe é apenas uma classe de dados que contém dados totalmente ok. Você não deve nomear a classe PairOfInteger. O que os números inteiros descrevem? Dependendo do seu cenário, uma Tupla (como em C #) também pode ser suficiente. E você pode querer pensar em um suporte em vez de uma aula.

Tente dar aulas pequenas. E métodos ainda menores. Talvez 10 linhas?!? Atualmente, estou tentando usar o design de fluxo e componentes baseados em eventos, o que parece ajudar a manter as classes pequenas. Primeiro eu estava preocupado em frequentar muitas aulas, mas realmente funciona !!! http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/flow-design-cheat-sheet-ndash-part-i-notation.aspx http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03 /20/flow-design-cheat-sheet-ndash-part-ii-translation.aspx

KCT
fonte
2

Torne as coisas o mais simples possível, mas não mais simples. Essa é a regra pela qual tento seguir. Às vezes, faz sentido que uma classe faça o que, estritamente falando, equivale a mais de uma coisa, se essas coisas estiverem relacionadas a algum tema comum . Veja o .NET; existem inúmeras classes que implementam um grande número de interfaces, cada uma com sua própria lista de membros necessários. Um método pode acabar precisando se tornar um pouco longo se fizer algo complexo com várias etapas intermediárias, todas interconectadas e, portanto, não se prestam muito bem a refatoração adicional. (A refatoração para manter os métodos curtos deve, em última análise, ter a legibilidade e a capacidade de manutenção; se o método longo for mais legível e / ou sustentável do que o curto, todo o resto será igual, aceitarei o longo a qualquer dia.)

Apenas "tornar as classes e métodos o menor possível" é, na minha opinião, equivocado. O verdadeiro desafio é, como aponta o @c_maker, fornecer boas abstrações. Seu exemplo de agrupamento de dois números é excelente, por exemplo, se você estiver trabalhando em uma implementação aritmética de números complexos, ou se em um sistema Unix, precisará se referir a um contexto de usuário / grupo. Faz muito pouco sentido se os números representam, por exemplo, um ID da fatura e um ID do produto a serem adicionados a essa fatura.

um CVn
fonte
0

Esse é um conselho aceitável, mas precisa ser implementado de maneira inteligente. Definitivamente não o siga cegamente.

Quando olho para o meu código, sei se um método é muito grande. Se está fazendo muito e seria muito difícil de ler, é hora de refatorar.

Aqui está um bom exemplo: você tem um loop e talvez tenha 60 linhas de código nesse método. Nesse caso, provavelmente é hora de refatorar, porque você provavelmente está fazendo muito nesse método.

Mas, não é uma regra difícil e rápida. É apenas algo que você aprende fazendo. Além disso, outros desenvolvedores com os quais você está trabalhando nem sempre concordam e podem chamá-lo em uma revisão de código ou qualquer outra coisa.

Alan Delimon
fonte
Nunca diminua os métodos, siga o SRP e ele fará o trabalho automaticamente.
Vinay Prajapati
0

O tio Bob diz que você deve refatorar / dividir / extrair seus métodos até que seja impossível diminuí-los . Isso geralmente termina em ter vários métodos com 3 ou 4 linhas cada. Quando você obtém muitos métodos, precisa criar mais classes.

Se você tentar seguir o SRP e um nível de abstração por método, essas regras o servirão bem. Pelo menos eles me servem bem. Apontar para "o menor possível" me fornece métodos pequenos e razoáveis, pois geralmente não consigo atingir esse objetivo.

E é sempre mais fácil entender classes menores. Vá em frente, leia "Código Limpo"

Peter Kofler
fonte