Eu tive um pequeno debate com um colega de trabalho. Simplificando, existe um bom motivo para ocultar / encapsular funções que são puras?
Por "puro", quero dizer a definição da Wikipedia :
- Sempre retorna os mesmos resultados da mesma entrada. (Para fins desta discussão,
Foo Create(){ return new Foo(); }
é considerado impuro seFoo
não tiver semântica de valor.) - Não usa estado mutável (exceto variáveis locais) ou E / S.
- Não produz efeitos colaterais.
design
pure-function
Telastyn
fonte
fonte
Respostas:
Uma função pura ainda pode ser um detalhe de implementação. Embora a função possa não causar danos (do ponto de vista de não quebrar invariantes / contratos importantes), expondo-a tanto o autor quanto os usuários dessa classe / módulo / pacote perdem. O autor perde porque agora ele não pode removê-lo, mesmo que a implementação mude e a função não seja mais útil para ele. Os usuários perdem porque precisam peneirar e ignorar funções extras que não são relevantes para o uso da API para entendê-la.
fonte
A questão está ao contrário.
Você não procura um motivo para tornar uma função não pública. É uma mentalidade incorreta para começar (na minha opinião). O raciocínio deve seguir o contrário.
Em outras palavras - não pergunte "por que eu o tornaria privado?". Pergunte: "por que eu a tornaria pública?"
Em caso de dúvida, não exponha. É como a navalha de Ockham - não multiplique entidades além da necessidade.
EDIT: Abordando contra-argumentos apresentados por @Telastyn nos comentários (para evitar discussões prolongadas):
Sim, às vezes é difícil se uma classe é aberta para herança, mas você não pode substituir alguns métodos privados (cujo comportamento você gostaria de alterar).
Mas
protected
seria suficiente - e ainda não é público.Se isso se tornar problemático, simplesmente torne-o público! Existe a necessidade de que eu estava falando :)
Meu argumento é que você não deve fazê-lo por precaução (YAGNI e tudo).
Observe que é sempre mais fácil tornar pública uma função privada do que recolocá-la na privacidade. O último provavelmente quebra o código existente.
fonte
Não acho que a decisão de ocultar / encapsular uma função dependa de sua pureza. Só porque uma função é pura, não significa que os externos precisam saber sobre ela. É interessante notar que, se a função é pura e pretende ser pública, talvez nem precise ser um membro da instância da interface; talvez seja mais adequada como estática. Mas, novamente, tudo isso depende da intenção do contrato e, nesse caso, do agrupamento lógico da funcionalidade, não da pureza da função.
fonte
As aulas devem seguir o Princípio da Responsabilidade Única . Embora uma classe precise recorrer a outras funcionalidades para atingir seus objetivos, ela só deve expor funções que fazem parte de sua única responsabilidade.
Aqui está apenas um exemplo de caso em que a visibilidade pode causar um problema.
Considere uma classe que frobica os widgets. Talvez como parte de seu código de frobificação, ele precise de alguma função utilitária que analise uma string: talvez precise transformar o nome do widget de uma maneira que as funções de string padrão não suportem.
Como essa é uma função pura (a string entra, a transforma de alguma forma, retorna uma nova string), ela pode ser pública ou privada sem conseqüências. Ou poderia?
Se você o tornar público, agora a sua classe tem duas responsabilidades: fazer widgets em alta velocidade e transformar strings. Isso viola o SRP e pode causar problemas se outras classes dependerem da função. Como isso é algo que você acha que é usado apenas internamente na classe, talvez você altere sua interface ou visibilidade. Agora as aulas em outras partes do sistema estão interrompidas.
Mantendo a função privada, ninguém nunca tem a oportunidade de confiar em códigos que não fazem parte da responsabilidade única da classe.
fonte
StringTransformer
classe separada para encapsular duas ou três linhas de código que são usadas apenas em um só lugar? Concordo que, uma vez que o código é usado em vários locais, é melhor separá-lo em uma nova classe com uma responsabilidade, mas há uma troca.