É comum usar classes parciais para obter 'modularidade'?


24

Recentemente, encontrei uma situação em nossa base de código em que uma equipe diferente criou uma 'classe divina' contendo cerca de 800 métodos, divididos em 135 arquivos como uma classe parcial.

Eu perguntei à outra equipe sobre isso. Embora minha reação instintiva tenha sido retirá-lo da órbita, eles insistem que é um bom design, uma prática comum e que promove 'modularidade' e 'facilidade de implementação', porque os novos desenvolvedores podem usar a funcionalidade quase sem conhecer o resto. do sistema.

Isso é realmente uma prática comum ou de alguma forma uma boa idéia? Estou inclinado a tomar medidas imediatas para derrubar esta fera (ou pelo menos impedir que ela cresça ainda mais), mas estou disposto a acreditar que estou errado.


6
matá-lo com fogo! Mas, falando sério, a outra equipe pode fornecer citações para essa suposta prática comum?
214128 MattDavey

11
Nenhum. Tenho certeza que eles estão soprando fumaça, mas estou tentando fazer a minha diligência antes de largar o martelo.
19372 Joshua Smith

Qual é o raciocínio deles para não fazer isso o tempo todo?
19412 JeffO

3
Peça que descrevam, em uma frase, o que os 800 métodos em 135 arquivos têm em comum. Deveria ser possível responder isso para qualquer classe sensata e razoável.
Carson63000

3
@ Carson63000 "Ele executa todas as funções necessárias do projeto." há sua única frase.
Ryathal

Respostas:


39

Isso não é de forma alguma uma boa idéia.

Existem classes parciais para ajudar o designer de formulários. Usá-los por qualquer outro motivo (e sem dúvida para o objetivo pretendido, mas isso é um assunto diferente) é uma má ideia, porque leva a classes inchadas que são difíceis de ler e entender.

Veja da seguinte maneira: se uma classe de deus com 800 métodos em um arquivo, onde você sabe onde está tudo, é uma coisa ruim - e eu acho que todos concordariam que é - então como uma classe de deus com 800 métodos espalhados por 135 arquivos, onde você não sabe onde tudo pode ser uma coisa boa?


11
Eu concordo principalmente, mas acho que pode haver alguns casos raros em que partialpodem ser úteis, mesmo sem o código gerado. Talvez quando você tem algo como uma classe aninhada?
svick

11
@svick: Classes parciais são interessantes, mas geralmente não são necessárias. Não sei por que dividir uma classe em arquivos separados seria útil quando há classes aninhadas. A menos que você queira a classe aninhada em seu próprio arquivo físico. Nesse caso ... talvez esteja tudo bem. ;)
FrustratedWithFormsDesigner

5
Às vezes, uso classes parciais para implementações explícitas de interface - especialmente algo como System.IConvertible. De alguma forma, parece mais limpo do que colocar uma # região maciça na minha classe.
18893 MattDavey

11
O comentário da classe aninhada é realmente uma boa ideia, eu nunca pensei nisso. Embora ... que tem mais a ver com a organização, que 'modularidade'
Sheldon Warkentin

11
"Existem classes parciais para ajudar o criador de formulários." Correto em geral, mas eu adicionaria "... e outros geradores de código". Concordo com o resto da sua resposta;)
Silas

14

Então a pergunta era:

Isso é realmente uma prática comum ou de alguma forma uma boa idéia?

Entre as respostas atualmente disponíveis, há um retumbante não . Portanto, existem poucas outras coisas em que eu poderia falar disso; até mesmo o código processual pode ser modificado e incluir tudo, menos a pia da cozinha . O que uma classe gigante dividida em parciais faz, tudo se transforma em uma grande bagunça.

No entanto, essa pergunta é um arenque vermelho para a parte crítica real do que foi esquecido; como o OP também tem o seguinte a dizer sobre a situação:

(...) Enquanto minha reação intestinal foi tirá-lo da órbita, eles insistem ...

(...) Estou inclinado a tomar medidas imediatas para derrubar esta fera (ou pelo menos impedir que ela cresça ainda mais), mas estou disposto a acreditar que estou errado.

SEGURE SEUS CAVALOS!

Isso aqui é algo que faria meu monóculo figurativamente falando cair em minha xícara figurativa de chá.

Já estive em situações semelhantes e deixe-me dizer: não caia no desejo de fazê-lo. Claro, você pode soltar o Nuke Hammer of Justice na equipe, mas antes de fazê-lo, tenha humor com o seguinte trecho de enigma:

O que acontecerá se você disser à equipe que o código deles é péssimo e não funciona ?

(... ou algo parecido, mas menos ofensivo, isso realmente não importa, porque eles ficarão ofendidos, independentemente do que você faça, se decidir aplicar força total neles)

Qual é a situação atual com a base de código? Está funcionando? Então você terá grandes problemas para explicar aos clientes que o código deles é péssimo . Quaisquer que sejam os motivos, desde que funcionem, a maioria dos clientes não se preocupa com a organização do código.

Também se coloque no lugar deles, o que eles fariam? Deixe-me diverti-lo com o seguinte resultado muito possível:

Membro da equipe nº 1: "Então esse cara está nos dizendo que estamos fazendo errado nos últimos anos."

Membro da equipe nº 2 e nº 3: "Que idiota."

Membro influente da equipe nº 4: "Não se preocupe, vou apenas para a gerência e relatar isso como um assédio".

Veja o que o membro da equipe influente nº 4 fez lá? Ele foi para a gerência e reduziu seu carma na empresa. Ele pode ser americano-italiano, dizendo a todos para não se preocuparem com isso, mas então eu seria racista sobre isso.

Pintar a equipe infratora em um canto e deixá-los admitir que fizeram errado por tanto tempo também é uma má idéia e leva à mesma coisa. Você perderá o respeito e algum carma político do escritório.

Mesmo que você tenha conseguido que várias pessoas concordassem com isso, a fim de "ensinar uma lição à equipe", lembre-se de que você está fazendo isso com pessoas razoavelmente inteligentes que aparentemente fazem algumas coisas. Uma vez que o código seja reescrito / refatorado / tratado / seja o que for e surgirem problemas, você será responsabilizado como se fosse o bombeiro-bombeiro .

Ser adversário em situações como essa é principalmente um jogo de perder / perder , pois corre o risco de se tornar um círculo vicioso de jogos de culpa. Este é um resultado subótimo para esta situação. Mesmo se você vencer, de repente você é entregue a bagunça que outra pessoa fez.

Existem outras maneiras (muito maduras)

Eu estava em uma situação semelhante uma vez, mas depois peguei uma flecha no joelho. Então, depois de um tempo com aquela repentina carreira na minha mente, consegui um livro Driving Technical Change de Terrence Ryan . Ele lista vários padrões de céticos, o tipo de pessoa que não age com base em boas idéias. É provável que todos sejam aplicáveis ​​no caso do OP:

  • Os desinformados - Eles realmente não sabiam que existem outras maneiras ou simplesmente não entendiam. Os desenvolvedores juniores geralmente se enquadram nessa categoria, mas não necessariamente. (Para ser sincero: conheci desenvolvedores juniores que seriam mais brilhantes que isso.)
  • The Herd - Eles conheciam técnicas melhores do que usar classes parciais, mas não sabiam que eram permitidos.
  • The Cynic - Eles apenas gostam de argumentar que ter aulas parciais é melhor do que a sua ideia apenas por uma questão de argumentar. É fácil fazer isso na multidão, em vez de ficar na frente da multidão.
  • The Burned - Por alguma estranha razão, eles não gostam de criar novas classes, provavelmente percebem isso muito difícil.
  • The Time Crunched - Eles estão tão ocupados que não conseguem se preocupar em corrigir seu código.
  • O Chefe - Eles pensam: "Bem, funciona; então, por que se preocupar?"
  • The Irrational - Ok, eles são completamente loucos.

O livro continua com uma lista de estratégias e assim por diante, mas no caso do OP é uma questão de persuasão. Ir de cabeça erguida com fatos sobre o antipadrão não é suficiente.

Se for do seu interesse aumentar a qualidade do código, pelo menos ofereça à equipe infratora chances de reiterar e corrigir sua própria bagunça . Pessoalmente, eu tentava influenciá-los ouvindo e fazendo perguntas importantes, deixando-os contar sua história:

  • O que exatamente a classe de Deus está fazendo?
  • Eles tiveram algum problema? Eles têm algum erro? Sugira correções sãs sem pedir que elas o façam.
  • Se você é um usuário dessa classe god como uma API: existem maneiras mais simples de usar o código do que usar a coisa toda? Sugira exemplos mais simples, veja como eles reagem.
  • Você pode trocar alguma funcionalidade por outra, sem precisar escrever a função?
  • Eles precisam de algum treinamento? Você pode convencer a gerência a fazê-lo ou almoçar sobre padrões e práticas?

... e assim por diante. Dê-lhes pequenas sugestões para que possam avançar. Leva tempo e vai precisar de alguma graxa de cotovelo no nível político do escritório, mas paciência e trabalho duro são uma virtude, certo?


Esta é uma resposta muito perspicaz. Se você é um novo desenvolvedor, precisa entender isso. A maioria dos desenvolvedores experientes percebe isso depois de vários anos, alguns nunca o fazem.
FishySwede

6

A página Classes e métodos parciais do MSDN sugere duas situações para o uso de classes parciais:
1. Para dividir uma classe gigante em vários arquivos separados.
2. Ter um local para colocar o código fonte gerado automaticamente.

2 é muito usado pelo Visual studio (por exemplo, para arquivos aspx e winforms). Este é um uso razoável de classes parciais.

1 é o que sua equipe está fazendo. Eu diria que o uso de classes parciais é uma maneira perfeitamente razoável de obter modularidade quando você tem classes gigantes, mas ter classes gigantes não é razoável. Em outras palavras, ter uma classe gigante é uma má idéia, mas se você tiver uma classe gigante, classes parciais são uma boa ideia.

Embora se você puder dividir inteligentemente uma classe em arquivos separados para diferentes usuários, você não pode simplesmente dividi-la em classes separadas?


+1 em "você não pode simplesmente dividi-lo em classes separadas?". É exatamente isso que estamos sugerindo. Parece senso comum que deveria ter sido feito dessa maneira originalmente.
19372 Joshua Smith

4

Então, no final, eles estão desenvolvendo o processo normalmente, sem nenhuma parte do POO. Eles têm um espaço para nome global com todos os métodos, variáveis ​​e outros enfeites.

Ou convencê-los de que estão fazendo errado ou dar o fora dali.


1

Uma classe de utilitário contém métodos que não podem ser sensivelmente combinados com outros métodos para criar uma classe. Se você tiver mais de 800 métodos, divididos em 135 arquivos, é provável que alguém tenha encontrado alguns métodos comuns ...

Só porque você tem uma classe de utilitário, não significa que você não pode ter outra classe de utilitário.

Mesmo se você tiver 800 métodos não relacionados, a solução não é uma classe grande e muitos arquivos. A solução é um espaço para nome, alguns sub-espaços para nome e muitas pequenas classes. Isso é um pouco mais trabalhoso (você precisa criar um nome para a classe e também para o método). Mas facilitará sua vida quando chegar a hora de limpar essa bagunça e, enquanto isso, facilitará o uso do intellisense (isto é, será mais fácil descobrir onde um método deve ser usado).

E não, isso não é comum (mais o número de arquivos do que o número de funções gratuitas).


0

Eu não gosto disso. No entanto, talvez as classes parciais fizessem sentido para os desenvolvedores durante o desenvolvimento, pois permitiam o desenvolvimento simultâneo desse grande número de métodos, especialmente se não houver muita dependência entre eles.

Outra possibilidade é que essas classes parciais tenham sido construídas para alterar uma classe principal gerada automaticamente. Se for esse o caso, não se deve tocá-los; caso contrário, o código personalizado será acionado ao gerar novamente.

Não tenho certeza de que alguém possa manter isso com facilidade sem algum estudo. Agora, se você o matar, o número de métodos não diminuirá. O número de métodos e complexidade, para mim, é o verdadeiro problema. Se os métodos realmente pertencerem à classe, ter um arquivo grande não facilitará sua vida, especialmente na manutenção. Na verdade, pode ser mais propenso a erros expor todo esse código a erros tolos, como a busca por caracteres curinga e substitua.

Portanto, tenha cuidado e justifique a decisão de matar. Além disso, considere que teste será necessário.


0

É perfeitamente bem do ponto de vista prático do projeto, assumindo que os 135 arquivos realmente agrupam métodos semelhantes ao que as classes tradicionais fariam. É apenas uma média de 6 métodos por arquivo. Definitivamente, não é a maneira mais popular ou tradicional de criar um projeto. Tentar mudar isso apenas criará um monte de problemas e má vontade sem nenhum benefício real. A conformidade do projeto com os padrões OO criará tantos problemas quanto ele resolver. É uma questão completamente diferente se os vários arquivos não fornecerem realmente separações significativas.


3
A refatoração de código de procedimento no OO geralmente tem esse problema - acho que corrigir isso será uma tarefa enorme e ensinar a equipe a codificar adequadamente, mesmo assim, Josué será responsabilizado por tudo o que acontecer ao longo do próximo ano (e além ) se ele os convencer a refatorar. É por isso que ninguém se esforça demais para fazer refatores como esse (pelo menos não depois de ver os resultados). Além disso, se você acha que é um bom design - bem - revisite essa resposta em 5 anos e deixe-nos saber o que pensa (parece que eu aprendo tudo o que sei sobre design a cada 5 anos).
Bill K

@ BillK, se você esperar dez anos, provavelmente saberá a atual filosofia de design "in".
Ryathal

Os 135 arquivos geralmente agrupam métodos relacionados, mas isso (para mim) ainda não faz disso uma boa ideia. Quero colocar esse sistema em teste, mas raspar / zombar da hidra do método 800 será uma coisa horrível.
21412 Joshua Smith

@Ryathal não é o que está "dentro", é o que você acha que é um bom design (por boas razões); depois, à medida que você pratica e aprimora, percebe que não é uma idéia tão boa quanto você pensava. Parece que isso acontece a cada 5 anos, mais ou menos, e uma vez que reconheci que tempera minha resposta aos comentários de algumas pessoas, porque percebo que eles são realmente excelentes designers que estão (como todos nós) no processo de melhorar nossas práticas para sempre. O único programador com o qual me preocupo é aquele que não achou que poderia melhorar o código que havia escrito há 5 anos.
Bill K

0

Além das respostas já apontadas, as classes parciais podem ser úteis em um design em camadas, no qual você deseja organizar a funcionalidade que corta sua hierarquia de classes em arquivos separados por camada. Isso permite que você use o Solution Explorer para navegar pela funcionalidade por camada (por organização de arquivos) e a visualização da classe para navegar pela funcionalidade por classe. Eu preferiria usar uma linguagem que suporte mixins e / ou características, mas classes parciais são uma alternativa razoável se usadas com moderação e não devem substituir o bom design da hierarquia de classes.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.