Estou vendo muitas classes instanciadas no mundo C ++ e Java que não têm nenhum estado.
Realmente não consigo descobrir por que as pessoas fazem isso, elas podem usar apenas um espaço para nome com funções livres em C ++, ou uma classe com um construtor privado e apenas métodos estáticos em Java.
O único benefício em que consigo pensar é que você não precisa alterar a maior parte do seu código se depois decidir que deseja uma implementação diferente em determinadas situações. Mas isso não é um caso de design prematuro? Pode ser transformado em uma classe mais tarde, quando / se for apropriado.
Estou entendendo errado? Não é POO se eu não colocar tudo em objetos (ou seja, classes instanciadas)? Então, por que existem tantos namespaces e classes de utilitários nas bibliotecas padrão de C ++ e Java?
Atualização: Eu certamente já vi muitos exemplos disso em meus trabalhos anteriores, mas estou lutando para encontrar exemplos de código aberto, então talvez não seja tão comum assim. Ainda assim, estou me perguntando por que as pessoas fazem isso e como é comum.
Respostas:
Algumas razões possíveis para criar classes sem seus próprios ivars:
O estado é ou pode estar contido em uma superclasse.
Classe implementa alguma interface e precisa ser instanciada para que as instâncias possam ser passadas para outros objetos.
A classe deve ser subclassificada.
Maneira prática de agrupar funções relacionadas. (Sim, pode haver maneiras melhores ou diferentes de fazer o mesmo.)
OOP é um paradigma, não uma lei da natureza. Existem alguns idiomas em que tudo é um objeto, então você realmente não tem escolha. Outros idiomas (por exemplo, C) não oferecem nenhum suporte para OOP, mas você ainda pode programar em um estilo orientado a objetos. Eu diria que você pode ter OOP se não fizer tudo nas aulas ... você pode dizer que apenas tem menos OOP nesse caso.
fonte
Caleb e Robert Harvey já apontaram o que são classes de utilidade e algumas razões legítimas para ter classes "sem dados". Essas descrições são claras, mas tratam dos aspectos positivos.
Gostaria apenas de mencionar que o abuso de classes de utilidade pode definitivamente ser um anti-padrão OO (consulte a descrição do c2wiki ). Esta citação resume bem:
Se você está afirmando estar praticando design orientado a objetos, mas sua base de código consiste quase inteiramente em classes de utilidade, eu diria que você definitivamente está fazendo algo errado. Dito isto, uma abordagem funcional tem tantos méritos e também pode ser excelente para se trabalhar. Apenas não afirme estar seguindo um, enquanto implementa o outro sem entusiasmo.
fonte
As classes de utilitário em Java e C ++ são usadas para manter uma biblioteca de métodos que usam um ou mais parâmetros de entrada e retornam um resultado. Eles não precisam manter o estado, se simplesmente retornarem um valor. A esse respeito, esses métodos podem ser considerados como uma forma bruta de programação funcional, com todas as vantagens (sem problemas de concorrência, por um lado).
De qualquer forma, essas classes servem apenas para agrupar métodos relacionados em um único contêiner, métodos que não requerem instanciação de um objeto para funcionar corretamente. Um exemplo dessa classe é uma classe Math que contém as funções SINE e COSINE (e outras matemáticas).
fonte
Muitas dessas classes interagem com dados, mesmo que não os contenham explicitamente, e precisam fazê-lo de maneiras que exijam que várias instâncias simultâneas estejam ativas. Por exemplo, um bean de sessão sem estado que interage com um procedimento armazenado no banco de dados, transmitindo dados recebidos para algum pacote PL / SQL e transmitindo os resultados de volta ao aplicativo de chamada. Essa coisa precisa existir em várias instâncias, mas ela mesma não contém nenhum campo de dados.
fonte
Em linguagens orientadas a objetos onde classes não são objetos, você pode fazer muito mais com um objeto do que com uma classe.
Você pode passar um objeto como parâmetro, você pode substituir um objeto compatível com o tipo, você pode implementar uma interface (imagino que existem linguagens nas quais as classes são objetos, mas você pode fazer algumas dessas coisas, mas em qualquer caso ...) . Todas essas coisas são muito importantes; portanto, a decisão padrão é geralmente tornar uma classe instanciada.
Para algumas classes, os recursos concedidos pela instanciação parecem improváveis. Você provavelmente não precisará trocar uma implementação do Cosine por outra, por exemplo. Acontece que são principalmente funções utilitárias que não precisam desses recursos; portanto, são principalmente funções utilitárias que possuem classes que não são instanciadas.
fonte