Ocasionalmente, temos que escrever métodos que recebem muitos argumentos, por exemplo:
public void doSomething(Object objA , Object objectB ,Date date1 ,Date date2 ,String str1 ,String str2 )
{
}
Quando encontro esse tipo de problema, geralmente encapsulo os argumentos em um mapa.
Map<Object,Object> params = new HashMap<Object,Object>();
params.put("objA",ObjA) ;
......
public void doSomething(Map<Object,Object> params)
{
// extracting params
Object objA = (Object)params.get("objA");
......
}
Esta não é uma boa prática, encapsular parâmetros em um mapa é totalmente um desperdício de eficiência. O bom é que a assinatura limpa é fácil de adicionar outros parâmetros com o mínimo de modificação. qual é a melhor prática para esse tipo de problema?
java
performance
parameters
parameter-passing
Serrador
fonte
fonte
Usar um mapa com chaves de corda mágicas é uma má ideia. Você perde qualquer verificação de tempo de compilação e realmente não está claro quais são os parâmetros necessários. Você precisaria escrever uma documentação muito completa para compensar isso. Você vai se lembrar em algumas semanas o que são essas Strings sem olhar para o código? E se você cometeu um erro de digitação? Use o tipo errado? Você não descobrirá até que execute o código.
Em vez disso, use um modelo. Faça uma classe que será um recipiente para todos esses parâmetros. Dessa forma, você mantém a segurança de tipo do Java. Você também pode passar esse objeto para outros métodos, colocá-lo em coleções, etc.
Obviamente, se o conjunto de parâmetros não for usado em outro lugar ou transmitido, um modelo dedicado pode ser um exagero. Há um equilíbrio a ser alcançado, então use o bom senso.
fonte
Se você tiver muitos parâmetros opcionais, pode criar uma API fluente: substitua o método único pela cadeia de métodos
Usando a importação estática, você pode criar APIs fluentes internas:
fonte
É chamado de "Introduzir objeto de parâmetro". Se você passar a mesma lista de parâmetros em vários lugares, basta criar uma classe que contenha todos eles.
Mesmo que você não passe a mesma lista de parâmetros com tanta frequência, essa fácil refatoração ainda melhorará a legibilidade do código, o que é sempre bom. Se você olhar seu código 3 meses depois, será mais fácil de compreender quando precisar corrigir um bug ou adicionar um recurso.
É uma filosofia geral, é claro, e como você não forneceu detalhes, também não posso dar conselhos mais detalhados. :-)
fonte
XXXParameter param = new XXXParameter();
disponível e, em seguida, usarXXXParameter.setObjA(objA)
; etc ...Primeiro, tentaria refatorar o método. Se estiver usando tantos parâmetros, pode ser muito longo. Dividi-lo melhoraria o código e reduziria potencialmente o número de parâmetros para cada método. Você também pode refatorar toda a operação em sua própria classe. Em segundo lugar, procuraria outras instâncias em que estou usando o mesmo (ou superconjunto) da mesma lista de parâmetros. Se você tiver várias instâncias, isso provavelmente indicará que essas propriedades pertencem umas às outras. Nesse caso, crie uma classe para conter os parâmetros e usá-la. Por último, eu avaliaria se o número de parâmetros vale a pena criar um objeto de mapa para melhorar a legibilidade do código. Eu acho que esta é uma chamada pessoal - há dor em cada sentido com esta solução e onde o ponto de troca pode ser diferente. Por seis parâmetros, provavelmente não o faria. Por 10, provavelmente o faria (se nenhum dos outros métodos funcionasse primeiro).
fonte
Isso costuma ser um problema ao construir objetos.
Nesse caso, use o padrão de objeto do construtor , ele funciona bem se você tiver uma grande lista de parâmetros e nem sempre precisar de todos eles.
Você também pode adaptá-lo à chamada de método.
Também aumenta muito a legibilidade.
Você também pode colocar lógica de verificação nos métodos Builder set .. () e build ().
fonte
final
? Essa é a principal coisa que me impede de escrever funções auxiliares. Suponho que posso tornar os campos privados e ter certeza de não modificá-los incorretamente no código dessa classe, mas espero algo mais elegante.Existe um padrão chamado de objeto Parameter .
A ideia é usar um objeto no lugar de todos os parâmetros. Agora, mesmo que você precise adicionar parâmetros posteriormente, você só precisa adicioná-los ao objeto. A interface do método permanece a mesma.
fonte
Você pode criar uma classe para armazenar esses dados. Precisa ser significativo o suficiente, mas muito melhor do que usar um mapa (OMG).
fonte
O Código Completo * sugere algumas coisas:
* Primeira edição, sei que devo atualizar. Além disso, é provável que alguns desses conselhos tenham mudado desde que a segunda edição foi escrita, quando OOP estava começando a se tornar mais popular.
fonte
A boa prática seria refatorar. O que significa que esses objetos devem ser passados para este método? Eles devem ser encapsulados em um único objeto?
fonte
Usar um mapa é uma maneira simples de limpar a assinatura da chamada, mas então você tem outro problema. Você precisa olhar dentro do corpo do método para ver o que o método espera naquele mapa, quais são os nomes das chaves ou quais tipos os valores têm.
Uma maneira mais limpa seria agrupar todos os parâmetros em um bean de objeto, mas isso ainda não corrige o problema inteiramente.
O que você tem aqui é um problema de design. Com mais de 7 parâmetros para um método você começará a ter problemas para lembrar o que eles representam e a ordem que eles têm. A partir daqui, você obterá muitos bugs apenas chamando o método na ordem de parâmetro errada.
Você precisa de um design melhor do aplicativo, não uma prática recomendada para enviar muitos parâmetros.
fonte
Crie uma classe de bean e defina todos os parâmetros (método setter) e passe este objeto de bean para o método.
fonte
Observe seu código e veja por que todos esses parâmetros são passados. Às vezes, é possível refatorar o próprio método.
Usar um mapa deixa seu método vulnerável. E se alguém usando seu método escrever incorretamente um nome de parâmetro ou postar uma string onde seu método espera um UDT?
Defina um objeto de transferência . Ele fornecerá, no mínimo, verificação de tipo; pode até ser possível executar alguma validação no ponto de uso, em vez de dentro do seu método.
fonte
Isso geralmente é uma indicação de que sua classe tem mais de uma responsabilidade (ou seja, sua classe tem DEMAIS).
Veja o princípio de responsabilidade única
para mais detalhes.
fonte
Se você estiver passando muitos parâmetros, tente refatorar o método. Talvez esteja fazendo muitas coisas que não deveria fazer. Se esse não for o caso, tente substituir os parâmetros por uma única classe. Desta forma, você pode encapsular tudo em uma única instância de classe e passar a instância e não os parâmetros.
fonte
Eu diria que continue do jeito que você fez antes. O número de parâmetros em seu exemplo não é muito, mas as alternativas são muito mais horríveis.
Mapa - Existe a questão da eficiência que você mencionou, mas o maior problema aqui são:
outra coisa ... Você tem javadocs que afirmam exatamente quais chaves e
valores são usados? Se você fizer isso (o que é ótimo), ter muitos parâmetros também não será um problema.
Objetos de invólucro - isso apenas move o problema, visto que você precisa preencher o objeto de invólucro em primeiro lugar - em vez de diretamente para o seu método, será para o construtor do objeto de parâmetro. Para determinar se mover o problema é apropriado ou não depende da reutilização do referido objeto. Por exemplo:
Não usaria: Seria usado apenas uma vez na primeira chamada, então muito código adicional para lidar com 1 linha ...?
Pode usar: aqui, pode fazer um pouco mais. Primeiro, ele pode fatorar os parâmetros para 3 chamadas de método. ele também pode executar 2 outras linhas em si mesmo ... então se torna uma variável de estado em certo sentido ...
Outra coisa que as pessoas esquecem de considerar é o papel do IDE em tudo isso. Quando os métodos têm parâmetros, os IDEs geram a maior parte do código para você e você tem as linhas vermelhas lembrando o que você precisa fornecer / definir. Ao usar a opção 3 ... você perde isso completamente. Agora cabe ao programador acertar, e não há pistas durante a codificação e o tempo de compilação ... o programador deve testá-lo para descobrir.
Além disso, as opções 2 e 3, se adotadas de forma ampla desnecessariamente, têm implicações negativas de longo prazo em termos de manutenção devido à grande quantidade de código duplicado que gera. Quanto mais código houver, mais há para manter, mais tempo e dinheiro é gasto para mantê-lo.
fonte