Enviei uma inscrição que escrevi para alguns outros arquitetos para revisão de código. Um deles quase imediatamente me escreveu de volta e disse: "Não use" estático ". Você não pode escrever testes automatizados com classes e métodos estáticos." Estático "deve ser evitado."
Eu verifiquei e totalmente 1/4 das minhas aulas estão marcadas como "estáticas". Uso estático quando não vou criar uma instância de uma classe porque a classe é uma única classe global usada em todo o código.
Ele passou a mencionar algo que envolvia zombaria, técnicas IOC / DI que não podem ser usadas com código estático. Ele diz que é lamentável quando as bibliotecas de terceiros são estáticas devido à sua falta de testabilidade.
Esse outro arquiteto está correto?
update: aqui está um exemplo:
APIManager - essa classe mantém dicionários de APIs de terceiros que estou chamando junto com o próximo tempo permitido. Ele impõe limites de uso da API que muitos terceiros têm em seus termos de serviço. Eu o uso em qualquer lugar em que estou chamando um serviço de terceiros, chamando Thread.Sleep (APIManager.GetWait ("ProviderXYZ")); antes de fazer a ligação. Tudo aqui é seguro para threads e funciona muito bem com o TPL em C #.
fonte
static
está bem;static
campos precisam ser tratados com muito cuidadoRespostas:
Depende se as classes estáticas mantêm o estado ou não. Pessoalmente, não tenho nenhum problema com funções sem estado lançadas juntas em uma classe estática.
fonte
Ele é muito geral sobre isso. Ele está correto, dificulta o teste. No entanto,
static
classes e métodos têm seu lugar e isso realmente depende do contexto. Sem exemplos de código, você não pode realmente dizer.Esse pode ser um cheiro severo ao código. Para que você está usando as aulas? Para armazenar dados? Para acessar um banco de dados? Então ele está correto. Nesse caso, você deve examinar a injeção de dependência, pois essa classe estática é efetivamente um singleton implícito.
Se você os estiver usando para métodos de extensão ou auxiliares que não alteram o estado e apenas operam com os parâmetros que você fornece, geralmente eles estão bem.
fonte
A melhor coisa a fazer é tentar testar seu código de unidade. Tente projetar testes que sejam repetíveis, independentes, simples e testem apenas um método por vez. Tente executar seus testes em ordem aleatória diferente. Você pode obter uma compilação "verde" estável?
Se sim, esse é um ponto válido para defender seu código. Se, no entanto, você tiver dificuldades, talvez deva usar métodos baseados em instância.
fonte
As respostas já publicadas abrangem muitos pontos realmente bons, mas há um que parece estar faltando:
Os campos estáticos nunca são coletados como lixo.
Isso é realmente importante se você tiver um aplicativo com muitas restrições de memória e esse padrão pode ser muito comum quando as pessoas tentam implementar um cache.
As funções estáticas não são tão ruins, mas todo mundo já cobriu isso com detalhes suficientes.
fonte
Uma das vantagens que você obtém do IoC / DI é que a maioria das interações entre classes é negociada entre interfaces. Isso facilita o teste de unidade, porque as interfaces podem ser simuladas automaticamente ou semi-automaticamente e, portanto, cada uma das partes pode ser testada quanto a entradas e saídas. Além disso, além da testabilidade, a colocação de interfaces entre tudo permite que você tenha o código mais modular possível - você pode substituir facilmente uma implementação sem muita preocupação, pois está estragando as dependências.
Como o C # não possui metaclasses, uma classe não pode implementar uma interface usando recursos estáticos; portanto, os recursos estáticos das classes acabam estragando qualquer esforço para implementar um modelo de objeto IoC / DI puro. Ou seja, você não pode criar uma simulação para testá-los e precisa criar dependências reais.
Se a sua empresa / projeto é fortemente investida na IoC, é claro que isso é uma preocupação razoável, e a dor que você está enfrentando é para o ganho de todos. Do ponto de vista arquitetônico, no entanto, eu pessoalmente não acho que qualquer modelo deva ser seguido até o túmulo. Há algumas coisas que fazem sentido implementar usando métodos estáticos - a estratégia de design singleton, por exemplo. Sou menos propenso a classes estáticas, porque acho que elas tendem a perder as vantagens do OO, mas há momentos em que uma classe de biblioteca é provavelmente uma expressão mais natural de algo do que um mecanismo.
O comentarista me lembra os métodos de extensão, que obviamente precisam estar em classes estáticas em C #. Isso é legítimo e é um exemplo de como a IoC pura não funciona muito bem em C #, pelo menos se você estiver tentando tirar proveito da amplitude do idioma.
fonte
Às vezes, as classes estáticas são mal utilizadas e devem ser:
Também pode ser uma função chamada 'utilitário' e parte de uma classe de utilitário. As classes de utilitário são classes que contêm apenas métodos estáticos e servem como funções auxiliares sem qualquer contexto.
fonte
Os métodos estáticos são bons de usar e têm um lugar de direito na programação. Parece que seu arquiteto possui uma estrutura de teste que não suporta totalmente métodos estáticos. Se o seu código faz parte de um projeto maior, é importante atender às diretrizes dos arquitetos. No entanto, não permita que este projeto o impeça de usar métodos estáticos quando for apropriado.
fonte
Eu tenho usado propriedades estáticas para coisas que são comuns a todas as instâncias de uma classe. E tenho usado métodos estáticos para obter grupos de objetos de classe. Eu não sou um especialista, mas isso tem funcionado para mim até agora.
Exemplo de PHP:
fonte
Eu direi que os princípios que eles adotam estão bem, mas a afirmação (não use estática) pode estar errada. Qual é a cobertura do seu código? se o número for alto e você se sentir confortável com o teste de unidade do seu aplicativo, estará bem. Caso contrário, sugiro revisar o código. Você pode achar que as classes estáticas são a razão ou não, isso dependerá de muitas coisas.
fonte
Classes com métodos estáticos abusam dos princípios da OOP. Já não é um POO, é uma programação orientada a classe COP.
Eles raramente têm uma "personalidade" clara (eu uso minha metáfora humana favorita aqui) ou identidade. Então eles não sabem quem são. Esse ponto, por si só, é suficiente para se livrar desse conceito no POO, mas há mais deles.
O próximo é uma consequência do primeiro ponto. Como essas classes não sabem quem são, tendem a ser de grandes a grandes.
Terceiro, seu código é absolutamente insustentável. O uso de métodos estáticos introduz dependências ocultas . Eles aparecem por todo o lugar, e você nunca sabe o que está acontecendo em sua classe. Você não pode ter certeza disso apenas olhando para a assinatura do construtor.
Lenta, mas inevitavelmente, seu código está ficando cada vez menos coeso, pois as dependências ocultas são mal controladas. Eles parecem invisíveis. E é tão fácil adicionar outro! Você não precisa modificar a assinatura de nenhum método. Tudo que você precisa fazer é chamar um método estático. E que código feio se segue ...
Ok, você provavelmente já adivinhou. O acoplamento apertado é um atendente frequente de baixa coesão. Se houver muitos clientes usando alguma classe, o acoplamento está ficando mais apertado. E há uma grande sedução no uso de uma classe ou método já escrito que requer apenas pequenas correções. Apenas um método flag-parameter.
O que usar em vez de métodos estáticos? Bem, minha sugestão é OOP. Por que não tentar?
fonte