É um cheiro de código se um método privado chama um público?


25

É um cheiro de código chamar método público em método privado da mesma instância de objeto?


AAMOI você tem um exemplo específico?
ocodo 12/01

Não, atualmente não. Acabei de me lembrar de um caso que discuti com meus colegas. Queria obter algumas opiniões aqui também.
Eimantas

5
Normalmente, consigo descobrir um acrônimo pelo contexto, mas AAMOI definitivamente precisava procurar
Carson Myers

@Carson - você encontrou alguma coisa?
Eimantas

4
Como uma questão de interesse
Carson Myers

Respostas:


32

Não, não cheiro ruim. Isso pode ser necessário, por que você suspeita que esteja errado? Um método no nível atômico é uma entidade independente que executa uma tarefa. Desde que execute uma tarefa, qualquer pessoa que tenha acesso a ela poderá chamá-la para concluir a tarefa.


Concordo. Alguns métodos fornecem funcionalidades úteis tanto para internos quanto para chamadores externos. Uma bandeira vermelha pode ser se o método público for muito específico para a implementação interna, mas, mesmo assim, nem toda classe pretende ocultar seus elementos internos. Geralmente, tenho uma camada de "ferramenta" da estrutura de dados abaixo de uma camada de tipo abstrato de contêiner, por exemplo - dessa forma, posso reutilizar parte do código da estrutura de dados para outras estruturas de dados subjacentes a outros contêineres.
Steve314 12/01

19

Código cheiro? Sim, não é realmente ruim, mas é um bom indicador de que a classe pode ter muitas responsabilidades.

Tome isso como um sinal de que a classe pode precisar ser dividida em diferentes objetos; os métodos privados não precisam realmente chamar métodos públicos do mesmo objeto, certamente em um design limpo de OO.

Obviamente, depois de inspecionar a classe e os motivos da chamada do método ficarem claros, pode ser um uso perfeitamente razoável; em geral, você espera que os métodos utilitários da classe sejam privados, mas se um for útil o suficiente para ser público e utilizado por outros métodos, eu geralmente esperaria que esses métodos também fossem públicos.

Como em todos os odores de código, isso é uma motivação para uma inspeção mais aprofundada, racionalizar e talvez refatorar, mas não é motivo de alarme.


5
+1 para 'não causa motivo de alarme'. Muitas vezes vemos um 'cheiro' e entram instantaneamente no modo refatorar sem pensar.
Michael K

+1 para SRP. Acabei de encontrar um caso em que um decorador não estava funcionando porque a classe decorada chamava sua própria função pública, ignorando o decorador. A solução: divida a classe em duas e injete a dependência decorada.
9138 Jon Hulka

18

Pode levar a surpresas desagradáveis ​​se alguém que não leu o código fonte dessa classe tentar subclassificá-lo e substituir o método público. Se essa é uma preocupação real, obviamente depende da sua situação. Talvez você deva considerar tornar o método público ou até a aula final.


Por quê? Se um método público sobrescrito leva a surpresas desagradáveis, realmente importa quem chamou o método?
precisa saber é o seguinte

4
Sim. Se substituir um método público quebra outro método público, também posso substituir esse outro método. Se ele quebra um método privado, eu posso ....?
Kim

5
Uma surpresa desagradável resultante da substituição de um método público é um cheiro de código em si. Um fedor de código, na verdade.
Larry Coleman

Kim: se o método for público, você deve assumir que outras classes chamam esse método da mesma forma ...
#

@ Larry: Exatamente! Um método privado (que geralmente contém suposições específicas da implementação) chamando um público torna mais provável que a substituição do método público possa quebrar as coisas.
Kim

5

Não acho que possamos genaralizar.

Tudo depende muito do contexto.

Eu poderia ter, digamos, um método de utilidade pública em uma classe que é usada por outras classes, e também algum método privado na mesma classe.


5

Não. O que mais deve ser feito nesse caso? Tornar público o método privado ou privado? Copiar e colar o código do método público para o privado?


Ou peça ao método público que delegue para um (novo) método privado que é invocado pelo outro método privado. Mas, por que se preocupar?
Lawrence Dol

4

NÃO , não tem cheiro ruim aqui.

se implementarmos a interface de uma fila com a List, é um mau cheiro chamar apenas as funções de List apropriadas para conseguir a implementação da fila facilmente?

se você tem alguma coisa e deseja convertê-la em outra coisa (como wrapper), então não é um mau cheiro, seu código pode ser reutilizado com padrão de design atuado no nível da função (a função é um objeto?)


2

Sei que este é um post antigo, mas é algo que venho debatendo no trabalho. Considero isso um cheiro de código e não consigo entender por que você gostaria de fazer isso. Se um método privado precisar chamar um método público, o conteúdo do método público deverá ser utilizado e colocado em um método privado, que os dois métodos poderão chamar. Por quê?

  1. O método público pode conter testes que não são necessários após a execução interna do código. Ele pode receber um UserObj e deseja testar permissões de usuário, por exemplo.

  2. Após uma chamada pública, você pode ter um requisito para bloquear o objeto, se estiver usando a segmentação, então internamente, você não gostaria de chamar de volta para um método público.

  3. É mais provável que eu introduza erros circulares, loops infinitos e exceções de mem na minha opinião.

  4. Simples e simples, design ruim e "preguiçoso". Métodos públicos fornecem acesso ao mundo exterior. Não há razão para voltar para fora quando você já está dentro.


1
E se o método público existente for chamado por muitas outras classes? Torná-lo privado vai quebrar isso. Lembre-se de que métodos públicos são chamados por outras classes por outros motivos, não apenas nesta classe. meio por que existem métodos públicos.
Michael Durrant

Afirmei que 'o conteúdo do método público deve ser tomado e colocado em um método privado ...' O método público permanecerá, mas faça uma chamada para o novo método privado. Como qualquer outro método particular que precise reutilizar a mesma funcionalidade.
Mark Graham

Então você está adicionando outro método por nenhuma outra razão senão - bem, porque você declarou que este é um "cheiro de código". Métodos inúteis é um cheiro de código pior.
gnasher729

Desculpe, mas eu não apenas listei vários motivos acima. Muito do código que escrevo é para sistemas comerciais, muitas classes são restritas a usuários com base na função. Muitos métodos públicos testam permissões e parâmetros de usuário. Por que diabos eu gostaria de retornar ao mesmo método público para reutilizar sua funcionalidade e testar novamente as permissões do usuário?
Mark Graham

Nunca na minha vida precisei chamar um método público de um método privado. Parece e me parece muito errado. Estou realmente surpreso que a maioria das pessoas acha que está tudo bem.
Armadilha

2

Imagine o contrário. Você está em um método privado e precisa da funcionalidade em um método público. E se você não pudesse chamar esse método público pelo privado. O que você faria?

  • Criar um método privado duplicado? Não
  • Criar um método público especial para a ocasião? Não
  • Chamar um método privado especial que possa chamar métodos públicos? Não
  • Algum tipo de super que pode fazer isso? Não

A resposta é clara: quando você quiser a funcionalidade em um método público, poderá chamá-lo a partir de métodos dessa classe ou de outras classes.


1

No meu código, geralmente crio getters de carregamento lento, ou seja, o objeto é inicializado na primeira vez em que é solicitado e depois reutiliza o mesmo objeto instanciado. No entanto, um objeto instanciado usando uma carga lenta implica que ele não pode necessariamente ser instanciado em um determinado momento. Em vez de entender a sequência de chamadas de modo que eu saiba que esse objeto já está instanciado ou repita o mesmo código de uma carga lenta dentro de outro método, eu simplesmente chamo o carregador lento sempre que preciso desse objeto.

Assim como você pode usar métodos públicos de maneira inteligente, também pode usá-los incorretamente. Um exemplo disso pode ser um método público que processa seus parâmetros antes de chamar outro método privado. Seria um erro chamar esse método público casualmente simplesmente porque você tem os mesmos parâmetros. O erro é sutil, mas é um erro de design mais do que qualquer outra coisa e requer que você aprenda a gerenciar com os parâmetros do método interno e não com os parâmetros do método público.

Portanto, para responder sua pergunta, certamente não é um código ruim se você o usar corretamente.


1

A pergunta que você precisa fazer é: por que sua turma tem a mesma necessidade dos clientes da sua turma? Normalmente, uma classe tem necessidades muito diferentes de seus clientes. Então, sim, isso é uma indicação de que você tem

(a) expôs algo publicamente que deveria ser privado; ou

(b) o comportamento da classe não é restrito o suficiente (pense no princípio da responsabilidade única).

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.